#include <bits/stdc++.h>
using namespace std;
inline int read() {
  register int x = 0, f = 1;
  register char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = 0;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + (ch ^ '0');
    ch = getchar();
  }
  return f ? x : -x;
}
const int N = 1e3 + 10, M = 15, mod = 1e9 + 7;
int n, m, num1, num2, head1[N], head2[M], ans;
map<int, vector<int> > _list;
map<int, int> f[N];
struct edge {
  int to, next;
} e1[N << 1], e2[M << 1];
inline void add1(int u, int v) {
  e1[++num1] = (edge){v, head1[u]}, head1[u] = num1;
}
inline void add2(int u, int v) {
  e2[++num2] = (edge){v, head2[u]}, head2[u] = num2;
}
inline void pls(int &x, int y) { x = x + y >= mod ? x + y - mod : x + y; }
inline int length(int x) { return 32 - __builtin_clz(x); }
inline void combine(int &x, int y) { x = x << length(y) | y; }
inline int Cal(int u, int pa) {
  int s = 1;
  vector<int> nw;
  for (int i = head2[u]; i; i = e2[i].next) {
    if (e2[i].to == pa) continue;
    nw.push_back((Cal(e2[i].to, u)));
  }
  sort(nw.begin(), nw.end());
  for (int i = (0), ed = (nw.size() - 1); i <= ed; ++i) combine(s, nw[i]);
  s <<= 1;
  if (!_list.count(s)) _list[s] = nw;
  return s;
}
inline void Dfs(int u, int pa) {
  static int g[2][1 << M];
  vector<int> son;
  for (int i = head1[u]; i; i = e1[i].next) {
    if (e1[i].to == pa) continue;
    son.push_back((e1[i].to));
    Dfs(e1[i].to, u);
  }
  for (map<int, vector<int> >::iterator it = _list.begin(); it != _list.end();
       ++it) {
    vector<int> nw = (*it).second;
    int s = (*it).first, siz = nw.size(), all = (1 << siz) - 1;
    memset(g[0], 0, sizeof(g[0]));
    g[0][0] = 1;
    for (int i = (0), ed = (son.size() - 1); i <= ed; ++i) {
      memcpy(g[1], g[0], sizeof(g[0]));
      for (int j = 0; j < siz; ++j) {
        int val = f[son[i]][nw[j]];
        if (!val) continue;
        for (int k = all; ~k; --k)
          if (g[0][k] && !((k >> j) & 1) &&
              (!j || nw[j] ^ nw[j - 1] || (k >> (j - 1)) & 1))
            pls(g[1][k | (1 << j)], 1ll * g[0][k] * val % mod);
      }
      memcpy(g[0], g[1], sizeof(g[1]));
    }
    if (g[0][all]) {
      f[u][s] = g[0][all];
      if (length(s) == m + m) pls(ans, g[0][all]);
    }
  }
}
int main() {
  n = read();
  for (int i = (2), ed = (n); i <= ed; ++i) {
    int u = read(), v = read();
    add1(u, v), add1(v, u);
  }
  m = read();
  for (int i = (2), ed = (m); i <= ed; ++i) {
    int u = read(), v = read();
    add2(u, v), add2(v, u);
  }
  for (int i = (1), ed = (m); i <= ed; ++i) Cal(i, 0);
  Dfs(1, 0);
  printf("%d\n", ans);
  return 0;
}
