#include <bits/stdc++.h>
using namespace std;
const int inf = 1.01e9;
const double eps = 1e-9;
const int N = 2010;
struct graph {
  int head[N], next[N], to[N], ec;
  int n;
  graph() { ec = 1; }
  inline void add(int x, int y) {
    ec += 1;
    to[ec] = y;
    next[ec] = head[x];
    head[x] = ec;
  }
  void read() {
    scanf("%d", &n);
    for (int i = 0; (i) < (n - 1); ++i) {
      int x, y;
      scanf("%d%d", &x, &y);
      --x, --y;
      add(x, y);
      add(y, x);
    }
  }
};
const int mod = 1e9 + 7;
int mpow(int a, int b) {
  int res = 1;
  while (b) {
    if (b & 1) res = (res * (long long)a) % mod;
    a = (a * (long long)a) % mod;
    b >>= 1;
  }
  return res;
}
int mem[N][30];
graph g1, g2;
int d[13][(int)1e4];
int d2[13][(int)1e4];
int fact[13];
int get(int e1, int e2) {
  int &res = mem[e1][e2];
  if (res != -1) return res;
  vector<int> want;
  int ones = 0;
  for (int e = g2.head[g2.to[e2]]; e; e = g2.next[e])
    if ((e ^ e2) != 1) {
      if (g2.next[g2.head[g2.to[e]]] == 0)
        ones++;
      else
        want.push_back(e);
    }
  for (int e = g1.head[g1.to[e1]]; e; e = g1.next[e])
    if ((e ^ e1) != 1) {
      for (int i = 0; (i) < (((int)(want).size())); ++i) {
        int ee = want[i];
        get(e, ee);
      }
    }
  int SZ = (1LL << (((int)(want).size())));
  for (int j = 0; (j) < (ones + 1); ++j)
    for (int i = 0; (i) < (SZ); ++i) d[j][i] = 0;
  d[0][0] = 1;
  for (int e = g1.head[g1.to[e1]]; e; e = g1.next[e])
    if ((e ^ e1) != 1) {
      for (int z = 0; (z) < (ones + 1); ++z)
        for (int j = 0; (j) < (SZ); ++j) d2[z][j] = d[z][j];
      for (int i = 0; (i) < (((int)(want).size())); ++i) {
        int ee = want[i];
        int cnt = get(e, ee);
        if (cnt)
          for (int z = 0; (z) < (ones + 1); ++z)
            for (int j = 0; (j) < (SZ); ++j)
              if (!(j & (1LL << (i))))
                d2[z][j | (1LL << (i))] =
                    (d2[z][j | (1LL << (i))] + d[z][j] * (long long)cnt) % mod;
      }
      for (int z = 0; (z) < (ones); ++z)
        for (int j = 0; (j) < (SZ); ++j)
          d2[z + 1][j] = (d2[z + 1][j] + d[z][j] * (long long)(z + 1)) % mod;
      for (int z = 0; (z) < (ones + 1); ++z)
        for (int j = 0; (j) < (SZ); ++j) d[z][j] = d2[z][j];
    }
  return res = d[ones][SZ - 1];
}
int calc(graph gg1, graph gg2) {
  g1 = gg1, g2 = gg2;
  if (g2.n == 1) return g1.n;
  memset(mem, -1, sizeof mem);
  int res = 0;
  int fst = 0;
  for (int i = 0; (i) < (g2.n); ++i)
    if (g2.next[g2.head[i]] == 0) {
      fst = g2.head[i];
    }
  for (int e = 2; e <= g1.ec; ++e) {
    res = (res + get(e, fst)) % mod;
  }
  return res;
}
graph second, T;
int main() {
  fact[0] = 1;
  for (int i = 1; i < 13; ++i) fact[i] = fact[i - 1] * (long long)i % mod;
  second.read();
  T.read();
  int direct = calc(second, T);
  int indirect = calc(T, T);
  int res = direct * (long long)mpow(indirect, mod - 2) % mod;
  printf("%d\n", res);
  return 0;
}
