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++ (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int T;
int n;
struct data{
    int to,nxt;
};
struct Graph{
    int ma[55][55];
    int d[55];
    int ed[55][2];
    int oe[55];
    data mp[110];
    int head[55],cnt;
    void clear()
    {
        memset(ma,0,sizeof(ma));
        memset(d,0,sizeof(d));
        memset(ed,0,sizeof(ed));
        memset(oe,0,sizeof(oe));
        memset(head,0,sizeof(head));cnt=0;
    }
    void ins()
    {
        int xx,yy;
        for(int i=1;i<n;++i)
        {
            scanf("%d%d",&xx,&yy);
            ed[i][0]=xx;ed[i][1]=yy;
            d[xx]++;d[yy]++;
            oe[xx]=oe[yy]=i;
            ma[xx][yy]=ma[yy][xx]=1;
        }
    }
    void link(int x,int y)
    {
        mp[++cnt].to=y;
        mp[cnt].nxt=head[x];
        head[x]=cnt;
    }
    int fa[55];
    void dfs(int x,int f)
    {
        fa[x]=f;
        for(int i=head[x];i;i=mp[i].nxt)
            if(mp[i].to!=f)
                dfs(mp[i].to,x);
    }
}A,B;
void build_B()
{
    for(int i=1;i<n;++i)
    {
        B.link(B.ed[i][0],B.ed[i][1]);
        B.link(B.ed[i][1],B.ed[i][0]);
    }
}
int ch[55];
data mp[110];
int head[55],cnt;
int d[55];
bool in[55];
void link(int x,int y)
{
    mp[++cnt].to=y;
    mp[cnt].nxt=head[x];
    head[x]=cnt;
    in[x]=in[y]=1;
}
bool ot[55];
bool Topsort()
{
    queue<int>q;
    memset(ot,0,sizeof(ot));
    for(int i=1;i<=n;++i)
        if(in[i]&&!d[i])
            ot[i]=1,q.push(i);
    int u,v;
    while(!q.empty())
    {
        u=q.front();q.pop();
        for(int i=head[u];i;i=mp[i].nxt)
        {
            v=mp[i].to;
            d[v]--;
            if(!d[v])ot[v]=1,q.push(v);
        }
    }
    for(int i=1;i<=n;++i)
        if(in[i]&&!ot[i])return 0;
    return 1;
}
int solve(int rt,int ano,int id)
{
    memset(A.head,0,sizeof(A.head));
    A.cnt=0;
    for(int i=1;i<n;++i)
    {
        if(i==id)continue;
        A.link(A.ed[i][0],A.ed[i][1]);
        A.link(A.ed[i][1],A.ed[i][0]);
    }
    A.link(rt,ano);A.link(ano,rt);
    A.dfs(rt,0);B.dfs(rt,0);
    int res=0;
    for(int i=1;i<=n;++i) ch[i]=(A.fa[i]!=B.fa[i]),res+=ch[i];
    memset(head,0,sizeof(head));cnt=0;
    memset(d,0,sizeof(d));
    memset(in,0,sizeof(in));
    for(int i=1;i<=n;++i)
    {
        if(i==rt)continue;
        if(!ch[i]&&ch[A.fa[i]])return inf;
        if(ch[i]&&ch[A.fa[i]]) link(i,A.fa[i]),d[A.fa[i]]++;
        if(ch[i]&&ch[B.fa[i]]) link(B.fa[i],i),d[i]++;
    }
    if(Topsort())return res;
    else return inf;
}
int main()
{
    scanf("%d",&T);
while(T--)
{
    scanf("%d",&n);
    A.clear();B.clear();
    A.ins();  B.ins();
    build_B();
    int ans=inf;
    for(int rt=1;rt<=n;++rt)
    {
        if(A.d[rt]!=1)continue;
        for(int f=1;f<=n;++f)
        {
            if(f==rt)continue;
            ans=min(ans,(A.ma[rt][f]^1)+solve(rt,f,A.oe[rt]));
        }
    }
    if(ans>n)puts("-1");
    else printf("%d\n",ans);
}
    return 0;
}