#include<bits/stdc++.h>
using namespace std;
const int M=2000005;
#define fi first 
#define se second 
int n,m,k;
int a[M];
stack<int>st[305];

pair<int,int> q[305][1005];
int head[305],tail[305];

int num[305],cnt;
queue<int>ID[605];
int Find[605],isfind[305][605],isback[605],isfront[605];

int op,Say[10005][4];

queue<int>newnode;
bool isdelete[100005];

void init(){
	op=0;
	for(int i=1;i<=n;i++){
		while(!st[i].empty()) st[i].pop();
		num[i]=0;
		head[i]=1,tail[i]=0;
	} 
	for(int i=1;i<=k;i++){
		while(!ID[i].empty()) ID[i].pop();
		isback[i]=isfront[i]=0;
	}
	memset(isfind,0,sizeof(isfind));
	memset(isdelete,0,sizeof(isdelete));
	while(!newnode.empty()) newnode.pop();
}

int _new(){
	if(!newnode.empty()){
		int x=newnode.front();
		newnode.pop();
		return x;
	}
	++cnt;
	return cnt;
}

void clearnum(int x){
	while(isback[x]>=2){
		int id1=0,id2=0;
		for(int j=1;j<=cnt;j++){
			if(q[j][head[j]].fi==x){
				if(id1==0) id1=j;
				else{
					id2=j;
					break;
				}
			}
		}
		
//		printf("2 %d %d\n",id1,id2);
		Say[++op][0]=2;
		Say[op][1]=id1,Say[op][2]=id2;
		
		isback[x]-=2;
//		if(isback[x]<0) puts("444");
		
		++head[id1];
		if(head[id1]>tail[id1]){
			head[id1]=1,tail[id1]=0;
			newnode.push(id1);
		}
		else{
			++isback[q[id1][head[id1]].fi];
			if(q[id1][head[id1]].fi>=2) clearnum(q[id1][head[id1]].fi);
		}
		
		++head[id2];
		if(head[id2]>tail[id2]){
			head[id2]=1,tail[id2]=0;
			newnode.push(id2);
		}
		else{
			++isback[q[id2][head[id2]].fi];
			if(q[id2][head[id1]].fi>=2) clearnum(q[id2][head[id2]].fi);
		}
	}
}

void putans(){
	printf("%d\n",op);
	for(int i=1;i<=op;i++){
		printf("%d ",Say[i][0]);
		if(Say[i][0]==1) printf("%d\n",Say[i][1]);
		else printf("%d %d\n",Say[i][1],Say[i][2]);
	}
}

void solve(){
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=m;i++){
		scanf("%d",&a[i]);
	}
	cnt=0;
	int cntid=0;
	init();
	
	for(int i=1;i<=m;i++){
		for(int j=1;j<=k;j++)
			while(!ID[i].empty()&&isdelete[ID[i].front()]) ID[i].pop();
		if(ID[a[i]].empty()) ID[a[i]].push(++cntid);
		
//		printf(">>>%d:%d [isfront:%d] [isback:%d]\n",i,a[i],isfront[a[i]],isback[a[i]]);
//		if(isback[a[i]]<0) while(1);
		
		if(isfront[a[i]]){
			int id=0;
			for(int j=1;j<=cnt;j++){
				if(head[j]<=tail[j]&&q[j][tail[j]].fi==a[i]){
					id=j;
					isdelete[q[j][tail[j]].se]=1;
					isdelete[ID[a[i]].front()]=1;
					
					--isfront[a[i]];
					--tail[j];
					
					if(head[j]<=tail[j]) ++isfront[q[j][tail[j]].fi];
					else newnode.push(j),--isback[a[i]];
					
//					if(isback[a[i]]<0) puts("111");
					
					break;
				}
			}
			
			Say[++op][0]=1;
			Say[op][1]=id;
//			printf("1 %d\n",id);
			
			continue;
		}
		if(isback[a[i]]){
			
			int id=0;
			for(int j=1;j<=cnt;j++)
				if(head[j]<=tail[j]&&q[j][head[j]].fi==a[i]){
					id=j;
					break;
				}
			int x=_new();
			
			Say[++op][0]=1;
			Say[op][1]=x;
//			printf("1 %d\n",x);
			
			Say[++op][0]=2;
			Say[op][1]=id,Say[op][2]=x;
//			printf("2 %d %d\n",id,x);
			newnode.push(x);
			
			isdelete[q[id][head[id]].se]=1;
			isdelete[ID[a[i]].front()]=1;
			
			--isback[a[i]];
//			if(isback[a[i]]<0) puts("222"),exit(0);
			++head[id];
			if(head[id]>tail[id]){

				--isfront[q[id][tail[id]].fi];
//				if(isfront[q[id][tail[id]].fi]<0) puts("222"),exit(0);
				head[id]=1,tail[id]=0;
				newnode.push(id);
			}
			else{
				++isback[q[id][head[id]].fi];
				clearnum(q[id][head[id]].fi);
			}
			continue;
		}
		int id=0;
		for(int j=1;j<=cnt;j++){
//			printf("%d:%d  [%d] [%d]\n",i,j,q[j][tail[j]].se,ID[a[i]].front());
			if(head[j]<=tail[j]&&q[j][tail[j]].se<ID[a[i]].front()){
//				if(j==3) printf(">[%d %d](%d)%d:%d  [%d] [%d]\n",head[j],tail[j],q[j][tail[j]].fi,i,j,q[j][tail[j]].se,ID[a[i]].front());
//				if(a[i]==15) printf("%d\n",q[3][tail[3]].fi);
				id=j;
				--isfront[q[j][tail[j]].fi];
				++isfront[a[i]];
				
//				if(isfront[q[j][tail[j]].fi]<0) puts("333");
//				printf(">>%d %d\n",q[j][tail[j]].fi,a[i]);
				
				num[j]=ID[a[i]].front();
				
				q[j][++tail[j]].fi=a[i];
				q[j][tail[j]].se=ID[a[i]].front();
				
				break;
			}
		}
		if(id!=0){
			Say[++op][0]=1;
			Say[op][1]=id;
//			printf("1 %d\n",id);
		}
		else{
//			printf("NEW nowcnt:%d\n",cnt);
			
			id=_new();
//			printf("ID:%d CNT:%d\n",id,cnt);
			
//			if(id==3) printf(">%d<\n",i);
			
			num[id]=ID[a[i]].front();
			
			q[id][++tail[id]].fi=a[i];
			q[id][tail[id]].se=ID[a[i]].front();
			
			++isfront[a[i]];
			++isback[a[i]];
			
			Say[++op][0]=1;
			Say[op][1]=id;
			
//			printf("1 %d\n",id);
		}
		continue;
	}
	
//	for(int i=1;i<=k;i++) printf("(%d %d)\n",i,isback[i]);
	
	while(1){
		bool f=1;
		for(int i=1;i<=k;i++){
			if(isback[i]){
				f=0;
				clearnum(i);
			}
		}
		if(f) break;
//		printf("%d\n",114514);
	}
	
	
	putans();
/*
1
2 4 2
1 2 1 2
*/

}

int main(){
	freopen("meow.in","r",stdin);
	freopen("meow.out","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)
		solve();

	return 0;
}
/*
1
3 10 5
1 2 3 4 5 2 3 4 5 1

15
1 1
1 1
1 1
1 1
1 1
1 2
1 2
1 2
1 2
1 3
2 1 3
2 1 2
2 1 2
2 1 2
2 1 2
*/
