Problem:
Score : 1900 points

Problem Statement

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.

Sample Input 1

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

Sample Output 1

1
-1

The graph in each case is shown below.

In case 1, A can be made to coincide with B by choosing Vertex 1, removing the edge connecting 1 and 2, and adding an edge connecting 1 and 3. Note that Vertex 2 is not a leaf vertex and thus cannot be chosen.

Sample Input 2

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

Sample Output 2

6
0
7

A may coincide with B from the beginning.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;

const int N = 100; 
const int INF = 1<<30; 

inline int read() {
	char c = getchar(); int f = 1, x = 0;
	while( c < '0' || c>'9' ) { if(c == '-') f = -1;  c = getchar(); }
	while( c >= '0'&&c<='9' ) { x = x * 10 + c - '0'; c = getchar(); }
	return f * x;
}

struct edge {
	int v, next; 
} ;

struct graph {
	
	int front[N], tot, fa[N], checked[N], degree[N]; edge e[N*N]; 
	
	inline void clear() {
		memset( checked, 0, sizeof( checked ) ); 
		memset( degree, 0, sizeof( degree ) ); 
		memset( front, 0, sizeof( front ) ); tot = 0; 	
	}
	
	inline void add_edge( int u, int v ) {
		e[++tot] = { v, front[u] }; front[u] = tot; degree[v] ++;  
	} 
	
	inline void add_edge2( int u, int v ) {
		add_edge( u, v ); add_edge( v, u ); 
	}
	
	inline void calc_fa( int u, int anc )
	{
//		printf( "%d %d\n", u, fa[u] ); 
		for( int i = front[u]; i; i = e[i].next ) 
			if( e[i].v != fa[u] && e[i].v != anc ) fa[e[i].v] = u, calc_fa( e[i].v, anc ); 
	}
	
	inline bool check( int u, int anc ) 
	{
		if( checked[u] && checked[u] != anc )  
			return true; 
		if( checked[u] == anc ) return false;  
		
		checked[u] = anc; 
		
		for( int i = front[u]; i; i = e[i].next )
			if( !check( e[i].v, anc ) ) return false; 
		return true; 
	}
	
} A, B, G;

int n; bool visited[N];  

void find( int u, int fa )
{
	if( visited[u] ) return; 
	visited[u] = true; 
	
	priority_queue <int> q; 
	
	for( int i = A.front[u]; i; i = A.e[i].next ) 
		if( A.e[i].v != fa ) q.push( A.e[i].v ); 
	
	for( int i = B.front[u]; i; i = B.e[i].next )
		if( B.e[i].v != fa ) q.push( B.e[i].v );   

	int last = 0; 
	while( !q.empty() )
	{
		if( q.top() == last ) 	
			find( q.top(), u ); 
			
		last = q.top(); q.pop(); 
	}
}

inline int calc_ans( int k )
{
	int ans = n; 
	
	memset( visited, false, sizeof( visited ) ); 
	
	find( k, 0 );
	 
	for( int i = 1; i <= n; i ++ )
		if( visited[i] ) ans --; 
	
	memset( A.fa, 0, sizeof( A.fa ) ); A.calc_fa( k, k ); 
	memset( B.fa, 0, sizeof( B.fa ) ); B.calc_fa( k, k ); 

	G.clear(); 

	for( int i = 1; i <= n; i ++ )
	{
		if( !visited[i] && !visited[ A.fa[i] ] )
			G.add_edge( i, A.fa[i] ); 
		if( !visited[i] && !visited[ B.fa[i] ] )
			G.add_edge( B.fa[i], i ); 
	}
	
	for( int i = 1; i <= n; i ++ )
		if( !G.check( i, i ) ) return INF; 

	return ans; 
}

inline void solve()
{
	n = read(); int ans = INF;  
	
	A.clear(); B.clear(); 
	
	for( int i = 1; i < n; i ++ )
		A.add_edge2( read(), read() ); 
	
	for( int i = 1; i < n; i ++ )
		B.add_edge2( read(), read() ); 	
	
	for( int i = 1; i <= n; i ++ )
		ans = min( ans, calc_ans( i ) ); 
		
	for( int i = 1; i <= n; i ++ )
	{
		if( A.degree[i] != 1 ) continue;
		int old = A.e[ A.front[i] ].v; 
		 
		for( int j = 1; j <= n; j ++ )
		{
			if( j == i || j == old )
				continue; 
			
			A.e[ A.front[i] ].v = j; 
			calc_ans( i ); 
		}
		
		A.e[ A.front[i] ].v = old; 
	}
	
	if( ans == INF ) ans = -1; 
	printf( "%d\n", ans ); 
}

int main()
{
	int ttt = read(); 
	
	while( ttt -- ) 
		solve(); 
	
	return 0; 
}