#include <algorithm> 
#include <cstdio> 
#include <cstring>
#include <iostream>
#include <vector>

#define debug(...) fprintf(stderr, __VA_ARGS__)

using namespace std;

inline char nc()
{
	return getchar();
	static char buf[100000],*l=buf,*r=buf;
	return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
}
template<class T> void read(T &x)
{
	x=0; int f=1,ch=nc();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
	while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=nc();}
	x*=f;
}

const int maxn = 50 + 5;
int T;
int N;
struct node
{
	int u, v;
	node(int u=0,int v=0)
	{
		if(u > v) swap(u, v);
		this->u = u;
		this->v = v; 
	}
	bool operator < (const node &other) const
	{
		if(u != other.u) return u < other.u;
		return v < other.v;
	}
};
node a[maxn], b[maxn];

int deg[maxn];
int head[maxn];
struct edge
{
	int to, nex;
	edge(int to=0,int nex=0):to(to),nex(nex){}
};
vector<edge> G;
inline void addedge(int u, int v)
{
	G.push_back(edge(v, head[u])), head[u] = G.size() - 1;
	++deg[v];
}
bool topsort()
{
	static int q[maxn]; int hd = 0, tl = 0;
	for(int i = 1; i <= N; ++i)
	{
		if(deg[i] == 0) q[tl++] = i;
	}
	while(hd < tl)
	{
		int u = q[hd++];
		for(int i = head[u]; ~i; i = G[i].nex)
		{
			int v = G[i].to;
			if(--deg[v] == 0) q[tl++] = v;
		}
	}
	return tl == N;
}

int adj[maxn][maxn];
bool vis[maxn];
vector<int> V;
vector<int> A[maxn];
vector<int> B[maxn];
void travel(int u)
{
	if(vis[u]) return;
	vis[u] = 1;
	V.push_back(u);
	for(unsigned int i = 0; i < A[u].size(); ++i)
	{
		int v = A[u][i]; if(adj[u][v] < 2) continue;
		travel(v);
	}
}
void dfsA(int u, int fa)
{
	for(unsigned int i = 0; i < A[u].size(); ++i)
	{
		int v = A[u][i]; if(v == fa) continue;
		dfsA(v, u);
		addedge(v, u);
	}
}
void dfsB(int u, int fa)
{
	for(unsigned int i = 0; i < B[u].size(); ++i)
	{
		int v = B[u][i]; if(v == fa) continue;
		dfsB(v, u);
		addedge(u, v); 
	}
}
int sol(int r)
{
	memset(adj, 0, sizeof(adj));
	for(int i = 1; i <= N; ++i)
	{
		A[i].clear();
		B[i].clear();
	}
	for(int i = 1; i < N; ++i)
	{
		int u = a[i].u, v = a[i].v;
		A[u].push_back(v);
		A[v].push_back(u);
		++adj[u][v], ++adj[v][u];
	}
	for(int i = 1; i < N; ++i)
	{
		int u = b[i].u, v = b[i].v;
		B[u].push_back(v);
		B[v].push_back(u);
		++adj[u][v], ++adj[v][u];
	}
	V.clear();
	memset(vis, 0, sizeof(vis));
	travel(r); 
	memset(deg, 0, sizeof(deg));
	memset(head, -1, sizeof(head));
	G.clear();
	for(unsigned int i = 0; i < V.size(); ++i)
	{
		int u = V[i];
		for(unsigned int i = 0; i < A[u].size(); ++i)
		{
			int v = A[u][i]; if(vis[v]) continue;
			dfsA(v, u);
		}
		for(unsigned int i = 0; i < B[u].size(); ++i)
		{
			int v = B[u][i]; if(vis[v]) continue;
			dfsB(v, u);
		}
	}
	return topsort() ? N - V.size() : -1;
}

int da[maxn];
int main()
{
	read(T);
	while(T--)
	{
		read(N);
		memset(da, 0, sizeof(da));
		for(int i = 1; i < N; ++i)
		{
			int u, v; read(u), read(v);
			a[i] = node(u, v);
			++da[u], ++da[v];
		}
		for(int i = 1; i < N; ++i)
		{
			int u, v; read(u), read(v);
			b[i] = node(u, v); 
		}
		sort(a + 1, a + N);
		sort(b + 1, b + N);
		bool flag = true;
		for(int i = 1; i < N; ++i)
		{
			if(a[i].u != b[i].u || a[i].v != b[i].v)
			{
				flag = false;
				break;
			}
		}
		if(flag) 
		{
			puts("0");
			continue;
		}
		int an = -1;
		for(int i = 1; i <= N; ++i) if(da[i] == 1)
		{
			int k = -1, v = -1;
			for(int j = 1; j < N; ++j)
			{
				if(a[j].u == i || a[j].v == i) 
				{
					k = j, v = a[j].u + a[j].v - i; 
					break;
				}
			}
			for(int j = 1; j <= N; ++j) if(j != i && j != v)
			{
				a[0] = node(i, j);
				swap(a[0], a[k]);
				int d = sol(i);
				if(d != -1)
				{
//					debug("-- %d\n", i);
//					for(int i = 1; i < N; ++i)
//					{
//						debug("%d %d\n", a[i].u, a[i].v);
//					}
//					debug("\n");
//					for(int i = 1; i < N; ++i)
//					{
//						debug("%d %d\n", b[i].u, b[i].v);
//					}
					++d;
					if(an == -1 || an > d) an = d;
				}
				swap(a[0], a[k]);
			}
		}
		printf("%d\n", an);
	}
	return 0;
}

Measured memory_bytes: 256