#include <bits/stdc++.h>
struct edge {
  int to;
  edge* next;
};
struct Tree {
  int n, ch[1001][1001], ccnt[1001], cset[1001];
  edge E[2000], *ne, *first[1001];
  void link(int u, int v) {
    *ne = (edge){v, first[u]};
    first[u] = ne++;
  }
  void read() {
    scanf("%d", &n);
    ne = E;
    for (int i = 1, u, v; i < n; i++)
      scanf("%d%d", &u, &v), link(u, v), link(v, u);
  }
  void dfs(int i, int f) {
    int c = cset[i] = 0;
    for (edge* e = first[i]; e; e = e->next)
      if (e->to != f) dfs(ch[i][c++] = e->to, i), cset[i] |= 1 << e->to - 1;
    ccnt[i] = c;
  }
} S, T;
int f[1001][1 << 12];
int dfs(int i, int j, int V) {
  if (!j) return !V;
  int& s = f[S.ch[i][j - 1]][V];
  if (s) return s - 1;
  s = dfs(i, j - 1, V);
  for (int c = S.ch[i][j - 1], k = 0; k < T.n; k++)
    if (V >> k & 1)
      s = (s + 1ll * dfs(i, j - 1, V - (1 << k)) *
                   dfs(c, S.ccnt[c], T.cset[k + 1])) %
          1000000007;
  return s++;
}
long long inv(int a, int p) {
  return a == 1 ? 1 : (1 + p * (a - inv(p % a, a))) / a % p;
}
int main() {
  S.read();
  T.read();
  S.dfs(1, 0);
  int ans = 0;
  for (int r = 1; r <= T.n; r++) {
    T.dfs(r, 0);
    for (int i = 1; i <= S.n; i++)
      ans = (ans + dfs(i, S.ccnt[i], T.cset[r])) % 1000000007;
    memset(f, 0, sizeof(f));
  }
  S = T;
  S.dfs(1, 0);
  int ans2 = 0;
  for (int r = 1; r <= T.n; r++) {
    T.dfs(r, 0);
    ans2 = (ans2 + dfs(1, S.ccnt[1], T.cset[r])) % 1000000007;
    memset(f, 0, sizeof(f[0]) * 13);
  }
  ans = ans * inv(ans2, 1000000007) % 1000000007;
  printf("%d\n", ans);
}

### Prompt

Generate a cpp solution to the following problem:

You are given two trees (connected undirected acyclic graphs) S and T.

Count the number of subtrees (connected subgraphs) of S that are isomorphic to tree T. Since this number can get quite large, output it modulo 109 + 7.

Two subtrees of tree S are considered different, if there exists a vertex in S that belongs to exactly one of them.

Tree G is called isomorphic to tree H if there exists a bijection f from the set of vertices of G to the set of vertices of H that has the following property: if there is an edge between vertices A and B in tree G, then there must be an edge between vertices f(A) and f(B) in tree H. And vice versa — if there is an edge between vertices A and B in tree H, there must be an edge between f - 1(A) and f - 1(B) in tree G.

Input

The first line contains a single integer |S| (1 ≤ |S| ≤ 1000) — the number of vertices of tree S.

Next |S| - 1 lines contain two integers ui and vi (1 ≤ ui, vi ≤ |S|) and describe edges of tree S.

The next line contains a single integer |T| (1 ≤ |T| ≤ 12) — the number of vertices of tree T.

Next |T| - 1 lines contain two integers xi and yi (1 ≤ xi, yi ≤ |T|) and describe edges of tree T.

Output

On the first line output a single integer — the answer to the given task modulo 109 + 7.

Examples

Input

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


Output

3


Input

3
2 3
3 1
3
1 2
1 3


Output

1


Input

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


Output

20


Input

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


Output

0

### Response

```cpp
#include <bits/stdc++.h>
struct edge {
  int to;
  edge* next;
};
struct Tree {
  int n, ch[1001][1001], ccnt[1001], cset[1001];
  edge E[2000], *ne, *first[1001];
  void link(int u, int v) {
    *ne = (edge){v, first[u]};
    first[u] = ne++;
  }
  void read() {
    scanf("%d", &n);
    ne = E;
    for (int i = 1, u, v; i < n; i++)
      scanf("%d%d", &u, &v), link(u, v), link(v, u);
  }
  void dfs(int i, int f) {
    int c = cset[i] = 0;
    for (edge* e = first[i]; e; e = e->next)
      if (e->to != f) dfs(ch[i][c++] = e->to, i), cset[i] |= 1 << e->to - 1;
    ccnt[i] = c;
  }
} S, T;
int f[1001][1 << 12];
int dfs(int i, int j, int V) {
  if (!j) return !V;
  int& s = f[S.ch[i][j - 1]][V];
  if (s) return s - 1;
  s = dfs(i, j - 1, V);
  for (int c = S.ch[i][j - 1], k = 0; k < T.n; k++)
    if (V >> k & 1)
      s = (s + 1ll * dfs(i, j - 1, V - (1 << k)) *
                   dfs(c, S.ccnt[c], T.cset[k + 1])) %
          1000000007;
  return s++;
}
long long inv(int a, int p) {
  return a == 1 ? 1 : (1 + p * (a - inv(p % a, a))) / a % p;
}
int main() {
  S.read();
  T.read();
  S.dfs(1, 0);
  int ans = 0;
  for (int r = 1; r <= T.n; r++) {
    T.dfs(r, 0);
    for (int i = 1; i <= S.n; i++)
      ans = (ans + dfs(i, S.ccnt[i], T.cset[r])) % 1000000007;
    memset(f, 0, sizeof(f));
  }
  S = T;
  S.dfs(1, 0);
  int ans2 = 0;
  for (int r = 1; r <= T.n; r++) {
    T.dfs(r, 0);
    ans2 = (ans2 + dfs(1, S.ccnt[1], T.cset[r])) % 1000000007;
    memset(f, 0, sizeof(f[0]) * 13);
  }
  ans = ans * inv(ans2, 1000000007) % 1000000007;
  printf("%d\n", ans);
}

```