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 Java7 (OpenJDK 1.7.0) (judge verdict: Accepted)

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskF solver = new TaskF();
        int testCount = Integer.parseInt(in.next());
        for (int i = 1; i <= testCount; i++)
            solver.solve(i, in, out);
        out.close();
    }

    static class TaskF {
        static final int INF = (int) 1e9;
        boolean[] matched;
        int[] queue;
        int[] degSrc;
        boolean[] readyDst;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            boolean[][] gSrc = new boolean[n][n];
            boolean[][] gDst = new boolean[n][n];
            int[] degSrc = new int[n];
            for (int i = 0; i < n - 1; ++i) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                ++degSrc[a];
                ++degSrc[b];
                gSrc[a][b] = gSrc[b][a] = true;
            }
            for (int i = 0; i < n - 1; ++i) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                gDst[a][b] = gDst[b][a] = true;
            }
            boolean allSame = true;
            for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (gSrc[i][j] != gDst[i][j]) allSame = false;
            if (allSame) {
                out.println(0);
                return;
            }
            int res = INF;
            matched = new boolean[n];
            queue = new int[n];
            this.degSrc = new int[n];
            readyDst = new boolean[n];
            for (int first = 0; first < n; ++first)
                if (degSrc[first] == 1) {
                    int firstOldTo = 0;
                    while (!gSrc[first][firstOldTo]) ++firstOldTo;
                    for (int firstTo = 0; firstTo < n; ++firstTo) {
                        if (first != firstTo && !gSrc[first][firstTo]) {
                            gSrc[first][firstOldTo] = false;
                            gSrc[firstOldTo][first] = false;
                            gSrc[first][firstTo] = true;
                            gSrc[firstTo][first] = true;
                            res = Math.min(res, 1 + solveWithFixed(first, n, gSrc, gDst));
                            gSrc[first][firstTo] = false;
                            gSrc[firstTo][first] = false;
                            gSrc[first][firstOldTo] = true;
                            gSrc[firstOldTo][first] = true;
                        }
                    }
                }
            if (res >= INF) out.println(-1);
            else out.println(res);
        }

        private int solveWithFixed(int fixed, int n, boolean[][] gSrc, boolean[][] gDst) {
            Arrays.fill(matched, false);
            matched[fixed] = true;
            int qt = 0;
            int qh = 1;
            queue[0] = fixed;
            while (qt < qh) {
                int cur = queue[qt++];
                for (int i = 0; i < n; ++i)
                    if (!matched[i] && gSrc[cur][i] && gDst[cur][i]) {
                        matched[i] = true;
                        queue[qh++] = i;
                    }
            }
            int ret = 0;
            for (boolean x : matched) if (!x) ++ret;
            Arrays.fill(degSrc, 0);
            Arrays.fill(readyDst, false);
            for (int i = 0; i < n; ++i)
                if (!matched[i])
                    for (int j = 0; j < n; ++j) if (gSrc[i][j]) ++degSrc[i];
            for (int i = 0; i < n; ++i)
                if (matched[i])
                    for (int j = 0; j < n; ++j) if (!matched[j] && gDst[i][j]) readyDst[j] = true;
            qt = 0;
            qh = 0;
            for (int i = 0; i < n; ++i)
                if (!matched[i] && degSrc[i] == 1 && readyDst[i]) {
                    queue[qh++] = i;
                }
            while (qt < qh) {
                int cur = queue[qt++];
                matched[cur] = true;
                for (int i = 0; i < n; ++i)
                    if (gSrc[cur][i] && !matched[i]) {
                        --degSrc[i];
                        if (degSrc[i] == 1 && readyDst[i]) {
                            queue[qh++] = i;
                        }
                    }
                for (int i = 0; i < n; ++i)
                    if (gDst[cur][i] && !matched[i] && !readyDst[i]) {
                        readyDst[i] = true;
                        if (degSrc[i] == 1) {
                            queue[qh++] = i;
                        }
                    }
            }
            if (ret == qh)
                return ret;
            else
                return INF;
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}