#include using namespace std; const int VALMAX = numeric_limits ::max(); const int TMAX = 20; const int NMAX = 50000; const int SUMNMAX = 200000; #ifdef LOCAL vector v; #endif int ask(int a, int b, int c) { cout << "1 " << a + 1 << ' ' << b + 1 << ' ' << c + 1 << endl; int ans; #ifdef LOCAL ans = v[a] ^ v[b] ^ v[c]; #else assert(cin >> ans); #endif assert(0 <= ans && ans <= VALMAX); return ans; } void solve(const vector &v, vector &ans) { const int N = v.size(); assert(N <= 7); vector res(N); for (int i = 0; i < N; ++i) res[i] = ask(v[i], v[(i + 1) % N], v[(i + 2) % N]); vector > known(N, vector (N, -1)); for (int i = 0; i < N; ++i) { known[i][(i + 3) % N] = res[i] ^ res[(i + 1) % N]; known[(i + 3) % N][i] = res[i] ^ res[(i + 1) % N]; } for (int i = 0; i < N; ++i) known[i][i] = 0; for (int k = 0; k < N; ++k) for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) if (known[i][k] != -1 && known[k][j] != -1) known[i][j] = known[i][k] ^ known[k][j]; for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) assert(known[i][j] != -1); for (int i = 0; i < N; ++i) ans[v[i]] = res[i] ^ known[(i + 1) % N][(i + 2) % N]; } bool test() { static int sum_N = 0; int N; assert(cin >> N); assert(8 <= N && N <= NMAX); sum_N += N; assert(sum_N <= SUMNMAX); vector ans(N); #ifdef LOCAL for (int i = 0; i < N; ++i) { v.push_back(i); } #endif int cnt[8] = {0}; // N = 8, 9, 10, 11 if (N % 4 == 0) { cnt[4] = 2; N -= 8; } else if (N % 4 == 1) { cnt[4] = 1; cnt[5] = 1; N -= 9; } else if (N % 4 == 2) { cnt[5] = 2; N -= 10; } else { cnt[4] = 1; cnt[7] = 1; N -= 11; } cnt[4] += N / 4; int where = 0; for (int i = 0; i < 8; ++i) { while (cnt[i]--) { vector pos; for (int j = 0; j < i; ++j) { pos.push_back(where + j); } solve(pos, ans); where += i; } } cout << '2' << endl; for (int i = 0; i < ans.size(); ++i) { cout << ans[i] << " \n"[i + 1 == ans.size()]; } cout.flush(); int ok_input; cin >> ok_input; assert(ok_input == 1); } int main() { int T = 0; assert(cin >> T); assert(1 <= T && T <= TMAX); while (T--) { test(); } return 0; }