#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
inline int read()
{
	int f = 1, x = 0;
	char ch;

	do{
		ch = getchar();
		if (ch == '-')
			f = -1;
	}while(ch < '0' || ch > '9');
	do{
		x = x * 10 + ch - '0';
		ch = getchar();
	}while(ch >= '0' && ch <= '9');
	return f * x;
}
const int N = 16;

int tt;
int n;
struct Edge {
	int to, next;
} edge[N * (1 << N) + 1];
int start[1 << N], tot;
int p[1 << N], vis[1 << N], inq[1 << N];
queue<int> q;
int ans[1 << N];
int color[1 << N];

inline void addedge(int u, int v)
{
	edge[++tot] = { v, start[u] };
	start[u] = tot;
	edge[++tot] = { u, start[v] };
	start[v] = tot;
	return;
}
inline void bfs()
{
	while (!q.empty()) {
		int u = q.front();
		vis[u] = 1;
		q.pop();
		for (int i = start[u]; i; i = edge[i].next) {
			int v = edge[i].to;
			if (!vis[v]) {
				p[v] |= p[u];
				if (!inq[v]) {
					q.push(v);
					inq[v] = 1;
				}
			}
		}
	}
	return;
}
int main()
{
	tt = read();

	while (tt--) {
		memset(start, 0, sizeof(int) * (1 << N));
		memset(p, 0, sizeof(int) * (1 << N));
		memset(vis, 0, sizeof(int) * (1 << N));
		memset(inq, 0, sizeof(int) * (1 << N));
		memset(color, 0, sizeof(int) * (1 << N));
		tot = 0;
		n = read();
		for (int i = 1; i <= n * (1 << (n - 1)); i++)
			addedge(read(), read());
		p[0] = 0;
		vis[0] = 1;
		for (int i = start[0], j = 1; i; i = edge[i].next, j <<= 1) {
			int v = edge[i].to;
			p[v] = j;
			q.push(v);
			vis[v] = 1;
		}
		bfs();
		for (int i = 0; i < 1 << n; i++)
			ans[p[i]] = i;
		for (int i = 0; i < 1 << n; i++)
			printf("%d ", ans[i]);
		printf("\n");
		if (n == 1 || n == 2 || n == 4 || n == 8 || n == 16) {
			for (int i = 0; i < 1 << n; i++) {
				for (int j = 0; j < n; j++)
					if (p[i] & (1 << j))
						color[i] ^= j;
				printf("%d ", color[i]);
			}
			printf("\n");
		} else {
			printf("-1\n");
		}
	}

	return 0;
}
