#include <iostream>
#include <vector>
#include <cassert>
#include <set>
#include <map>
#include <algorithm>
using namespace std;

template<class T> ostream& operator<<(ostream& out, const vector<T> &V) {
  out << "[ "; for (unsigned i=0; i<V.size(); i++) out << V[i] << ", "; out << "]"; return out;
}
#define DEBUG(x) cout << #x << ": " << (x) << endl;
typedef pair<int,int> PII;

void doit(const vector<int> &path, int N) {
  vector<int> H;
  
  H.push_back(0); 
  H.push_back(N/2); 
  int flip = 0;
  
  for (unsigned i=1; i<path.size(); i++) {
    if (path[i] < path[i-1]) flip = !flip;
    H.push_back( path[i] + (flip?N/2:0) );
    H.push_back( path[i] + (flip?0:N/2) );
  }

  for (unsigned i=0; i<path.size(); i++) cout << H[2*i+1] << " " << H[(2*i+2)%N] << " "; cout << endl;
  for (unsigned i=1; i<path.size(); i++) swap( H[2*i], H[2*i+1] );
  for (unsigned i=0; i<path.size(); i++) cout << H[2*i+1] << " " << H[(2*i+2)%N] << " "; cout << endl;
}


int main() {
  int N, T;
  cin >> T;

  while (T--) {
  
    cin >> N;
    N *= 2;

    assert(N%4==2 || N==4 || N==8 || N==12);

    if (N==4) { cout << "0 1 2 3" << endl << "0 3 2 1" << endl << endl; continue; }

    if (N==8 || N==12) {
      // hard-wire the correct solution here :)
      cout << "???" << endl << endl;
      continue;
    }

    // decompose K_{N/2} into hamiltonian cycles
    vector< vector<int> > paths;

    vector<int> initial;
    for (int i=0; i<(N/2)-1; i++) {
      if (i%2==0) {
        initial.push_back( i/2 );
      } else {
        initial.push_back( N/2-2-(i/2) );
      }
    }
    initial.push_back( N/2 - 1);
    paths.push_back( initial );

    for (int i=1; i<(N/4); i++) {
      vector<int> next;
      next = initial;
      for (int j=0; j<(N/2)-1; j++) { next[j] += i; next[j] %= (N/2)-1; }
      paths.push_back( next );
    }
    // DEBUG(paths);

    // check correctness of the decomposition
    int edges = (N/2) * (N/2 - 1) / 2;
    map<PII,int> hrany;
    for (unsigned i=0; i<paths.size(); i++) 
      for (unsigned j=0; j<paths[i].size(); j++) {
        int x = paths[i][j];
        int y = paths[i][(j+1) % paths[i].size()];
        if (x>y) swap(x,y);
        assert(x!=y);
        assert(!hrany[ PII(x,y) ]);
        hrany[ PII(x,y) ] = 1;
        edges--;
      }
    assert(edges == 0);

    // output the main matching
    // for (int i=0; i<N/2; i++) cout << i << " " << (i+N/2) << " "; cout << endl;

    for (unsigned i=0; i<paths.size(); i++) {
      while (paths[i][0]) rotate( paths[i].begin(), paths[i].begin()+1, paths[i].end() );
      doit( paths[i], N );
      reverse( paths[i].begin()+1, paths[i].end() );
      doit( paths[i], N );
    }
    cout << endl;
    
  }
}
