#include <bits/stdc++.h>
using namespace std;

bool query1(int a, int b){
	cout << "1 " << a << " " << b << endl;
	int x; cin >> x; assert(x != -1); return x;
}

bool query2(int a, vector<int> v){
	if(v.empty()) return 0;
	cout << "2 " << a << " " << v.size();
	for(int& num : v) cout << " " << num;
	cout << endl; int x; cin >> x; assert(x != -1); return x;
}

vector<int> merge(const vector<int>& lhs, const vector<int>& rhs){
	int l = 0, r = 0, _l = lhs.size(), _r = rhs.size();

	vector<int> curr;

	while(l < _l && r < _r){
		if(query1(lhs[l], rhs[r])){
			curr.push_back(lhs[l]); l++;
		}else{
			curr.push_back(rhs[r]); r++;
		}
	}	

	while(l < _l){
		curr.push_back(lhs[l]); l++;
	}

	while(r < _r){
		curr.push_back(rhs[r]); r++;
	}

	return curr;
}

vector<int> mergesort(int l, int r){
	if(l == r) return {l};
	int mid = l + r >> 1;
	vector<int> lhs = mergesort(l, mid), rhs = mergesort(mid + 1, r);
	return merge(lhs, rhs);
}

vector<int> toposort;

vector<int> all(int idx){ // [0, idx]
	vector<int> curr;
	for(int i = 0; i <= idx; i++) curr.push_back(toposort[i]);
	return curr;
}

int T, N;

int main(){

	cin >> T;

	while(T--){

		cin >> N; 

		toposort.clear();
		toposort = mergesort(0, N - 1);

		stack<int> st; st.push(0);

		for(int i = 1; i < N; i++){
			while(!st.empty() && query2(toposort[i], all(st.top()))) st.pop();
			st.push(i);
		}

		vector<vector<int>> scc;

		while(!st.empty()){
			int curr = st.top(); st.pop(); 
			int prev = st.empty() ? -1 : st.top();

			scc.push_back({});

			for(int i = prev + 1; i <= curr; i++) scc.back().push_back(toposort[i]);
		}

		vector<vector<bool>> sol(N, vector<bool>(N, 0));

		vector<int> previous = {};

		for(int i = 0; i < scc.size(); i++){
			for(int& num : scc[i]) previous.push_back(num);
			for(int j = 0; j < scc[i].size(); j++)
				for(int& num : previous) sol[scc[i][j]][num] = 1;
		}

		cout << 3 << '\n';

		for(int i = 0; i < N; i++){
			for(int j = 0; j < N; j++) cout << sol[i][j];
			cout << '\n';
		}

		cout.flush();

		int x; cin >> x;
	}
}