Problem: Snuke has found two trees A and B, each with N vertices numbered 1 to N. The i-th edge of A connects Vertex a_i and b_i, and the j-th edge of B connects Vertex c_j and d_j. Also, all vertices of A are initially painted white.

Snuke would like to perform the following operation on A zero or more times so that A coincides with B:

* Choose a leaf vertex that is painted white. (Let this vertex be v.)
* Remove the edge incident to v, and add a new edge that connects v to another vertex.
* Paint v black.



Determine if A can be made to coincide with B, ignoring color. If the answer is yes, find the minimum number of operations required.

You are given T cases of this kind. Find the answer for each of them.

Constraints

* 1 \leq T \leq 20
* 3 \leq N \leq 50
* 1 \leq a_i,b_i,c_i,d_i \leq N
* All given graphs are trees.

Input

Input is given from Standard Input in the following format:


T
case_1
:
case_{T}


Each case is given in the following format:


N
a_1 b_1
:
a_{N-1} b_{N-1}
c_1 d_1
:
c_{N-1} d_{N-1}


Output

For each case, if A can be made to coincide with B ignoring color, print the minimum number of operations required, and print `-1` if it cannot.

Examples

Input

2
3
1 2
2 3
1 3
3 2
6
1 2
2 3
3 4
4 5
5 6
1 2
2 4
4 3
3 5
5 6


Output

1
-1


Input

3
8
2 7
4 8
8 6
7 1
7 3
5 7
7 8
4 2
5 2
1 2
8 1
3 2
2 6
2 7
4
1 2
2 3
3 4
3 4
2 1
3 2
9
5 3
4 3
9 3
6 8
2 3
1 3
3 8
1 7
4 1
2 8
9 6
3 6
3 5
1 8
9 7
1 6


Output

6
0
7

Solution (in CPP):

Solution:
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define L(i,u) for(int i=head[u];i;i=nxt[i])
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef pair<int,int> Pii;
typedef vector<int> Vi;
const int N = 123,inf=0x3f3f3f3f;
int n,deg[N];Pii T1[N],T2[N];
inline void read(Pii &c){int x,y;scanf("%d%d",&x,&y);if(x>y)swap(x,y);c=Pii(x,y);}
Vi e2[N],e1[N],e[N];int fa[N],ok[N],q[N],f,r;
void dfs(int u, int Fa){
	fa[u]=Fa;per(i,(int)e1[u].size()-1,0)if(e1[u][i]!=Fa)dfs(e1[u][i],u);
}
inline void upd(int u){
	per(i,(int)e[u].size()-1,0)if(deg[e[u][i]]==1&&!ok[e[u][i]]&&ok[fa[e[u][i]]])q[r++]=e[u][i];
}
inline void find(int u){
	ok[u]=1;
	per(i,(int)e2[u].size()-1,0)if(!ok[e2[u][i]]&&fa[e2[u][i]]==u)find(e2[u][i]);
	upd(u);
}
inline int solve(int rt){
//	rep(i,1,n-1)printf("%d %d %d %d\n",T1[i].fi,T1[i].se,T2[i].fi,T2[i].se);puts("");
	memset(ok,0,sizeof(ok));rep(i,1,n)e1[i].clear();
	rep(i,1,n-1)e1[T2[i].fi].pb(T2[i].se),e1[T2[i].se].pb(T2[i].fi);
	dfs(rt,0);memset(deg,0,sizeof(deg));rep(i,1,n-1)deg[T1[i].fi]++,deg[T1[i].se]++;
	rep(i,1,n)e[i].clear();rep(i,1,n)e[fa[i]].pb(i);
	rep(i,1,n)e2[i].clear();rep(i,1,n-1)e2[T1[i].fi].pb(T1[i].se),e2[T1[i].se].pb(T1[i].fi);
	int res=0;f=1;r=1;find(rt);while(f!=r){
		int u=q[f++];if(ok[u])continue;
		ok[u]=2;int v=0;per(i,(int)e2[u].size()-1,0)if(ok[e2[u][i]]!=2)v=e2[u][i];
		deg[v]--;if(deg[v]==1&&ok[fa[v]]&&!ok[v])q[r++]=v;upd(u);res++;
	}
	rep(i,1,n)if(!ok[i])return inf;return res;
}
int main(){//freopen("1.in","r",stdin);
	int T;scanf("%d",&T);
	while(T--){
		scanf("%d",&n);rep(i,1,n-1)read(T1[i]);rep(i,1,n-1)read(T2[i]);
		sort(T1+1,T1+n);sort(T2+1,T2+n);bool same=1;
		rep(i,1,n-1)same&=(T1[i]==T2[i]);
		if(same)puts("0");
		else{
			static int d[N];int res=inf;memset(d,0,sizeof(d));
			rep(i,1,n-1)d[T1[i].fi]++,d[T1[i].se]++;
			rep(rt,1,n)if(d[rt]==1)rep(i,1,n)if(i!=rt){
				int rec=0;rep(j,1,n-1)if(T1[j].fi==rt||T1[j].se==rt){
					if(T1[j].fi==rt)rec=T1[j].se,T1[j].se=i;else rec=T1[j].fi,T1[j].fi=i;
				}
				res=min(res,solve(rt)+1);
				rep(j,1,n-1)if(T1[j].fi==rt||T1[j].se==rt){
					if(T1[j].fi==rt)T1[j].se=rec;else T1[j].fi=rec;
				}
			}
			printf("%d\n",res<inf?res:-1);
		}
	}
	return 0;
}