#include <iostream>
#include <queue>
#include <list>
using std::queue;
using std::list;
//using namespace std;

inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch == ' ' || ch == '\n' || ch == '\t') ch = getchar();
	while (true) {
		if (ch >= '0' && ch <= '9') x = 10 * x + ch - '0';
		else if (ch == '-') f *= -1;
		else break;
		ch = getchar();
	}
	return x * f;
}

void write(int x) {
	if (x < 0) {
		putchar('-');
		x *= -1;
	}
	if (x < 10) {
		putchar('0' + x);
		return;
	}
	write(x / 10);
	putchar('0' + x % 10);
}

// test group, stack count, card count, card type count
int T, n, m, k;
int a[2000006];
int aed;
list<int> stks[305];// begin() is bottom, --end() is top
int tcnt[615];
int tedStkId[615];
int out[10000][3];
int outEd = 0;// doesnt include ed

inline void writes(int a, int b) {
	out[outEd][0] = a;
	out[outEd++][1] = b + 1;
}
inline void writes(int a, int b, int c) {
	out[outEd][0] = a;
	out[outEd][1] = b + 1;
	out[outEd++][2] = c + 1;
}
inline void erase() {
	outEd--;
}

void print() {
//	puts("====\n");
	write(outEd), putchar('\n');
	for (int i = 0; i < outEd; i++) {
		write(out[i][0]), putchar(' ');
		write(out[i][1]);
		if (~out[i][0] & 1) {
			putchar(' ');
			write(out[i][2]);
		}
		putchar('\n');
	}
}
bool dfs() {
	if (aed == m) {
		int resetOp1[20][3], resetOp1Len = 0;
		// do op2 first
		while (true) {
			int maxCnt = 0, maxNum;
			int chose;
			for (int i = 1; i <= k; i++) tcnt[i] = 0;
			for (int i = 0; i < n; i++) {
				if (stks[i].empty()) continue;
				if (++tcnt[*stks[i].begin()] > maxCnt) {
					maxCnt = tcnt[*stks[i].begin()];
					chose = tedStkId[*stks[i].begin()];
					maxNum = *stks[i].begin();
				}
				tedStkId[*stks[i].begin()] = i;
			}
			if (maxCnt >= 2) {
				int s1 = chose, s2 = tedStkId[maxNum];
				writes(2, s1, s2);
				stks[s1].erase(stks[s1].begin(), ++stks[s1].begin());
				stks[s2].erase(stks[s2].begin(), ++stks[s2].begin());
				resetOp1[resetOp1Len][0] = s1;
				resetOp1[resetOp1Len][1] = s2;
				resetOp1[resetOp1Len++][2] = maxNum;
			} else break;
		}
		// end
		bool flg = true;
		for (int i = 0; i < n; i++) {
			if (!stks[i].empty()) {
				flg = false;
				break;
			}
		}
//		print();
		if (flg) return 1;
		for (int i = resetOp1Len - 1; ~i; i--) {
			stks[resetOp1[i][0]].insert(stks[resetOp1[i][0]].begin(), resetOp1[i][2]);
			stks[resetOp1[i][1]].insert(stks[resetOp1[i][1]].begin(), resetOp1[i][2]);
		}
		outEd -= resetOp1Len;
		return 0;
	}
	// do op 1
	int card = a[aed++];
//	printf("%d ", aed);
//	for (int i = 0; i < n; i++) {
//		writes(1, i);
//		if (!stks[i].empty() && *(--stks[i].end()) == card) {
//			stks[i].erase(--stks[i].end(), stks[i].end());
//			if (dfs()) return 1;
//			stks[i].push_back(card);
//		} else {
//			stks[i].push_back(card);
//			if (dfs()) return 1;
//			stks[i].erase(--stks[i].end(), stks[i].end());
//		}
//		erase();
//	}
	bool hasSameCard = 0, sameCardId;
	for (int i = 0; i < n; i++) {
		if (!stks[i].empty() && *(--stks[i].end()) == card) {
			hasSameCard = 1, sameCardId = i;
		}
	}
	if (hasSameCard) {
		writes(1, sameCardId);
		stks[sameCardId].erase(--stks[sameCardId].end(), stks[sameCardId].end());
		if (dfs()) return 1;
		stks[sameCardId].push_back(card);
		erase();
	} else {
		for (int i = 0; i < n; i++) {
			writes(1, i);
			if (!stks[i].empty() && *(--stks[i].end()) == card) {
				stks[i].erase(--stks[i].end(), stks[i].end());
				if (dfs()) return 1;
				stks[i].push_back(card);
			} else {
				stks[i].push_back(card);
				if (dfs()) return 1;
				stks[i].erase(--stks[i].end(), stks[i].end());
			}
			erase();
		}
	}
	aed--;
	return 0;
}

void process() {
	n = read(), m = read(), k = read();
	for (register int i = 0; i < m; i++) a[i] = read();
	aed = 0;
	outEd = 0;
	dfs();
	print();
}

int main() {
	freopen("meow.in", "r", stdin);
	freopen("meow.out", "w", stdout);
	T = read();
	for (int i = 0; i < T; i++) process();
	return 0;
}