#include <bits/stdc++.h>
using namespace std;
long double PI = acos(-1);
long double DEL = 1e-10;
int M =  1e9 + 7;
const int N = 3e5 + 10;

#define ftt cin>>tc;for(int cas=1;cas<=tc;++cas)
#define all(a) a.begin(),a.end()
#define vpii vector<pair<int,int>>
#define vvi vector<vector<int>>
#define pii pair<int,int>
#define vi vector<int>
#define sq(a) ((a)*(a))
#define double long double
#define dbg cout<<"\nhi\n";
#define int long long
#define nl cout<<endl
#define sp <<" "<<
#define S second
#define F first

template<class T> using minpq = priority_queue<T,vector<T>,greater<T>>;
struct DSU
{
    vi par,size;
    DSU (int n)
    {
        par.resize(n+1);
        size.resize(n+1);
        for(int i=0;i<=n;i++)
        {
            par[i] = i;
            size[i] = 1;
        }
    }
    
    int find(int x)
    {
        return par[x] = (x == par[x]? par[x]:find(par[x]));
        
    }
    
    void join(int x,int y)
    {
        int parx = find(x),pary = find(y);
        if(parx == pary)
        {
            return;
        }
        if(size[parx] > size[pary])
        {
            size[parx] += size[pary];
            par[pary] = parx;
        }
        else
        {
            size[pary] += size[parx];
            par[parx] = pary;
        }
    }
};
int fpow(int x, int n)
{
    int res = 1;
    x %= M;
    while(n)
    {
        if(n&1)res = res * x % M;
        x = x * x % M;
        n>>=1;
    }
    return res;
}
int gcd(int a,int b)
{
    if(b == 0)return a;
    return gcd(b,a % b);
}
int lcm(int a,int b)
{
    return a*(b/gcd(a,b));
}
int popcount(int x)
{
    return bitset<65>(x).count();
}
void create_fac(int n)
{
    vector<int> fac(N),inv(N);
    fac[0] = inv[0] = 1;
    for(int i=1;i<=n;i++)
    {
        fac[i] = fac[i-1]*i % M;
        inv[i] = fpow(fac[i],M-2);
    }
}
int ncr(int n,int r)
{
    vector<int> fac(N),inv(N);
    return fac[n] * (inv[r] * inv[n-r] % M) % M;
    return fac[n] * (fpow(fac[r],M-2) * fpow(fac[n-r],M-2) % M ) % M;
}
void sieve (int n)      // linear sieve
{
    vector <int> primes;
    bool iscomp[N];
    for (int i = 2; i <= n; ++i)
    {
        if (!iscomp[i]) primes.push_back(i);
        for (int j = 0; j < primes.size() && i * primes[j] <= n; ++j)
        {
            iscomp[i * primes[j]] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

//**************************************** CHECK CONSTRAINTS ***************************************
int cnt, sum, mid, mx, mn, ans[N], a[N], b[N];
int n, m, d, i, j, k, l, p[N], q, r, t, w, x, y, z, tc;
string s;

bool ch(int a,int b){
    cout<<1 sp a sp b;nl;
    int ans;
    cin>>ans;
    if(ans == -1)exit(0);
    return ans == 1;
}

void build(int l,int r){
    if(l == r){
        return;
    }
    int mid = (l+r)/2;
    build(l,mid);
    build(mid+1,r);
    
    int i = l;
    int j = mid + 1;
    
    vi v;
    while(i <= mid and j <= r){
        if(ch(a[i],a[j])){
            v.push_back(a[i]);
            i++;
        }
        else{
            v.push_back(a[j]);
            j++;
        }
    }
    while(i <= mid){
        v.push_back(a[i]);
        i++;
    }
    while(j <= r){
        v.push_back(a[j]);
        j++;
    }
    
    int k = l;
    for(auto j:v){
        a[k] = j;
        k++;
    }
    
}

bool query(int i,int l){
    cout<<2 sp i sp l + 1;
    for(int j = 0;j <= l;j++){
        cout<<" "<<a[j];
    }
    nl;
    int ans;
    cin>>ans;
    if(ans == -1)exit(0);

    return ans;
}


int32_t main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//    #ifndef ONLINE_JUDGE
//    freopen("/Users/jenish/XCode/CP/input.txt","r",stdin);
//    #endif
    
    ftt{
        cin>>n;
        
        for(int i = 0;i < n; i++){
            a[i] = i;
        }
        
        //a[1]...a[n] represents hamiltonian path
        //build(0,n - 1);
        stable_sort(a,a+n,ch);
        
        //for(int i = 1;i<=n;i++)cout<<a[i]<<" ";nl;
        p[n] = n;
        cnt = 0;
        vvi ans(n,vi(n,1));

        for(int i = n - 1;i >= 0;--i){
            p[i] = min(i - 1,p[i+1] - 1);
            
            while(p[i] >= 0 and query(a[i],p[i])){
                p[i]--;
            }
            
            p[i]++;
            
            for(int j = p[i];j < i;j++){
                p[j] = p[i];
            }
            
            if(p[i] == i)
                for(int j = p[i];j<n;j++){
                    for(int k = 0;k < p[i];k++){
                        ans[a[j]][a[k]] = 0;
                    }
                }
        }
        
        cout<<3;nl;
        for(int i = 0;i < n;++i){
            for(int j = 0;j < n;++j){
                cout<<ans[i][j];
            }
            nl;
        }
        cin>>x;
        if(x == -1){
            return 0;
        }
    }
    
}
