#include <bits/stdc++.h>

std::vector<int>G[105];
int n,c[105],tl,x[105],c1,c2;

int q1(int x,int y) {
	c1 ++;
	assert(c1 <= 9 * n);
	x --; y --;
	printf("1 %d %d\n",x,y);
	fflush(stdout);
	int res = 0;
	scanf("%d",&res);
	assert(res != -1);
	return res;
}

int q2(int x,std::vector<int>v) {
	c2 ++;
	assert(c2 <= 2 * n);
	printf("2 %d %d ",x - 1,v.size());
	for (int y:v) printf("%d ",y - 1);
	puts("");
	fflush(stdout);
	int res;
	scanf("%d",&res);
	assert(res != -1);
	return res;
}

std::vector<int> find_path(int n) {
	std::vector<int>v;
	if (n == 1) { v = {1}; return v; }
	v = find_path(n - 1);
	if (q1(v.back(),n)) { v.push_back(n); }
	else if (q1(n,v[0])) { v.insert(v.begin(),n); }
	else {
		int l = 0, r = n - 2;
		while (l < r - 1) {
			int mid = (l + r) >> 1;
			if (q1(v[mid],n)) l = mid;
			else r = mid;
		} v.insert(std::find(v.begin(),v.end(),v[r]),n);
	} return v;
}

void merge(int x,int y) {
	for (int u:G[y]) G[x].push_back(u);
	G[y].clear();
}

int query(int x,int y) {
	std::vector<int>v;
	for (int i = 1; i <= x; ++ i) {
		for (int j:G[i]) v.push_back(j);
	} return q2(y,v);
}


void solve() {
	tl = 0;
	c1 = c2 = 0;
	scanf("%d",&n);
	for (int i = 1; i <= n; ++ i) {
		G[i].clear();
		c[i] = 0;
	}
	std::vector<int>v = find_path(n);
//	for (int x:v) printf("%d ",x); puts("");
	for (int i = 1; i <= n; ++ i) {
		int u = v[i - 1];
	//	printf("<%d>\n",u);
		G[++tl].push_back(u);
		for (int j = tl - 1; j >= 1; j --) {
			if (G[j].empty()) continue;
			if (!query(j,u)) break;
			else for (int k = j; k < tl; ++ k) merge(tl,k);
		}
	}
	for (int i = 1; i <= n; ++ i) 
		for (int x:G[i]) c[x] = i;
//	for (int i = 1; i <= n; ++ i)
	//	printf("%d ",c[i]);
	//	puts("");
	puts("3");
	for (int i = 1; i <= n; ++ i) {
		for (int j = 1; j <= n; ++ j) {					
			printf("%d",(c[i] <= c[j]));
		} puts("");
	}
	fflush(stdout);
	int res = 0;
	scanf("%d",&res);
	return ;
}

int main() {
	int t;scanf("%d",&t);while(t--)solve();
	return 0;
}