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 <algorithm>
// #include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#include <bitset>
using namespace std;
typedef long long LL;
typedef double db;
const int oo=2139063143;
const int N=1010000;
const int P=1000000007;
const db eps=1e-7;
#define pritnf printf
//char buf[1<<22],*p1=buf,*p2=buf,obuf[1<<22],*O=obuf;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
template <typename T>
inline void sc (T &x)
{
    x=0; static int p; p=1; static char c; c=getchar();
    while (!isdigit(c)) { if (c=='-') p=-1; c=getchar(); }
    while ( isdigit(c)) { x=(x<<1)+(x<<3)+(c-48); c=getchar(); }
    x*=p;
}
template <typename T>
inline void print (T x)
{
    if (x< 0) putchar('-'),x=-x;
    if (x>=10) print(x/10);
    putchar(x%10+'0');
}
template <typename T>
inline void pr (T x) { print(x),putchar('\n'); }
template <typename T1,typename T2>
void chkmax (T1 &A,T2 B) { A=A>=B?A:B; }
template <typename T1,typename T2>
void chkmin (T1 &A,T2 B) { A=A<=B?A:B; }
int n;
#define pb push_back
struct TREE
{
    int x[N],y[N],deg[N];
    void get () { for (int i=1; i< n; i++) sc(x[i]),sc(y[i]),++deg[x[i]],++deg[y[i]]; }
    vector <int> G[N];
    void clear () { for (int u=1; u<=n; u++) G[u].clear (); }
    void add (int x,int y) { G[x].pb (y),G[y].pb (x); }
    void link (int g)
    {
        for (int i=1; i< n; i++) if (x[i]!=g&&y[i]!=g)
            add (x[i],y[i]);
    }
    int fa[N];
    void dfs (int u,int f)
    {
        fa[u]=f;
        for (int v:G[u]) if (v!=f)
            dfs (v,u);
    }
    int find (int rt)
    {
        for (int i=1; i< n; i++)
            if (x[i]==rt) return y[i];
            else if (y[i]==rt) return x[i];
        return 0;
    }
}A,B;
vector <int> G[N]; int deg[N];
void clear () { for (int u=1; u<=n; u++) G[u].clear (),deg[u]=0; }
void add (int x,int y) { G[y].pb (x),++deg[x]; }//printf ("     %d %d\n",x,y); }
bool check ()
{
    queue <int> q;
    for (int u=1; u<=n; u++)
        if (!deg[u]) q.push (u);
    int num=0;
    while (q.size ())
    {
        int u=q.front (); q.pop (); ++num;
        for (int v:G[u])
            if (!--deg[v]) q.push (v);
    }
    return num==n;
}
bool vis[N];
int main ()
{
    // freopen ("rd.in","r",stdin);
    // freopen ("my.out","w",stdout);
    int T; sc(T);
    while (T--)
    {
        sc(n);
        for (int i=1; i<=n; i++)
            A.deg[i]=0;
        A.clear (),B.clear ();
        A.get (),B.get ();
        B.link (0);
        int ans=oo;
        for (int rt=1; rt<=n; rt++) if (A.deg[rt]==1)
        {
            B.dfs (rt,0);
            for (int x=1; x<=n; x++) if (x!=rt)
            {
                A.clear ();
                A.link (rt);
                A.add (rt,x);
                A.dfs (rt,0);
                memset (vis,0,sizeof (bool)*(n+1));
                int sum=0;
                for (int u=1; u<=n; u++)
                    vis[u]=A.fa[u]!=B.fa[u],sum+=vis[u];
                bool fg=1;
                for (int u=1; u<=n; u++)
                    if (vis[A.fa[u]]&&!vis[u]) { fg=0; break; }
                if (!fg) continue;
                clear ();
                for (int u=1; u<=n; u++)
                {
                    if (vis[A.fa[u]]) add (u,A.fa[u]);
                    if (vis[B.fa[u]]) add (B.fa[u],u);
                }
                if (!check ()) continue;
                // printf ("     %d %d %d\n",rt,x,sum+(A.find (rt)!=x));
                chkmin (ans,sum+(A.find (rt)!=x));
            }
            // A.dfs (rt,0),B.dfs (rt,0);
            // memset (vis,0,sizeof (bool)*(n+1));
            // int sum=0;
            // for (int u=1; u<=n; u++)
            //  if (A.fa[u]!=B.fa[u]) vis[u]=1,++sum;
            // bool fg=1;
            // for (int u=1; u<=n; u++)
            //  if (vis[A.fa[u]]&&!vis[u]) { fg=0; break; }
            // if (!fg) continue;
            // clear ();
            // for (int u=1; u<=n; u++) if (vis[A.fa[u]])
            // {
            //  add (u,A.fa[u]);
            //  if (vis[B.fa[u]]) add (B.fa[u],u);
            // }
            // if (!check ()) continue;
            // chkmin (ans,sum);
        }
        pr(ans==oo?-1:ans);
    }

    return 0;
}