#include <bits/stdc++.h>
using namespace std;
const int M = 13, N = 1e3 + 3;
const long long Pr = 1e9 + 7;
vector<int> Hs, val;
vector<int> mtr;
map<pair<int, int>, int> cb;
map<int, int> to, sz;
int bg[M], ed[M], m;
void init() {
  Hs.push_back(0);
  mtr.push_back(0);
  bg[0] = ed[0] = 0;
  Hs.push_back(2);
  mtr.push_back(0);
  to[2] = sz[2] = bg[1] = ed[1] = 1;
  for (int no = 2; no <= m; ++no) {
    bg[no] = ed[no - 1] + 1;
    int lt = no - 1, rt = 1;
    while (rt <= m && lt >= 1) {
      val.clear();
      for (int i = bg[rt]; i <= ed[rt]; ++i) val.push_back(Hs[i]);
      sort(val.begin(), val.end());
      int L = bg[lt] - 1;
      for (int i = 0; i <= val.size() - 1; ++i) {
        int MT = val[i];
        while (L < ed[lt] && mtr[L + 1] <= MT) ++L;
        for (int j = bg[lt]; j <= L; ++j) {
          mtr.push_back(MT);
          int ha = Hs[j];
          ha ^= (1 << (lt + lt - 1));
          Hs.push_back((MT << (lt + lt - 1)) + (1 << (no + no - 1)) + ha);
          to[Hs.back()] = Hs.size() - 1;
        }
      }
      lt--, rt++;
    }
    ed[no] = Hs.size() - 1;
    for (int i = bg[no]; i <= ed[no]; ++i) sz[Hs[i]] = no;
  }
  for (int i = 1; i <= ed[m - 1]; ++i) {
    val.clear();
    int ha = Hs[i], I, len = (sz[ha] << 1);
    while (mtr[I = to[ha]] > 0) {
      val.push_back(mtr[I]);
      len -= (sz[val.back()] << 1);
      ha &= ((1 << len) - 1);
      ha |= (1 << (len - 1));
    }
    ha = Hs[i];
    for (int j = ed[m - sz[ha]]; j >= 1; --j) {
      int hb = Hs[j], K = val.size();
      int ad = 1;
      for (int k = 0; k <= (int)val.size() - 1; ++k) {
        int sbt = val[k];
        if (sbt < hb) {
          ad <<= (sz[hb] << 1);
          ad |= hb;
          K = k;
          break;
        } else {
          ad <<= (sz[sbt] << 1);
          ad |= sbt;
        }
      }
      if (K == val.size()) {
        ad <<= (sz[hb] << 1);
        ad |= hb;
      }
      for (int k = K; k <= (int)val.size() - 1; ++k) {
        int sbt = val[k];
        (ad <<= (sz[sbt] << 1)) |= sbt;
      }
      ad <<= 1;
      cb[make_pair(ha, hb)] = ad;
    }
  }
}
int n, tr[N];
long long ans;
vector<int> s[N], t[N], has;
vector<int>::iterator it;
map<int, long long> dp[N];
void dfs(int fa, int anc) {
  tr[fa] = 1;
  dp[fa][2] = 1;
  for (int i = s[fa].size() - 1; i >= 0; --i) {
    int son = s[fa][i];
    if (son != anc) {
      dfs(son, fa);
      for (int sum = m; sum >= 2; --sum)
        for (int cta = 1; cta <= sum - 1; ++cta) {
          int ctb = sum - cta;
          if (cta > tr[fa] || ctb > tr[son]) continue;
          for (int I = bg[cta]; I <= ed[cta]; ++I)
            for (int J = bg[ctb]; J <= ed[ctb]; ++J) {
              int A = Hs[I], B = Hs[J];
              (dp[fa][cb[make_pair(A, B)]] += dp[fa][A] * dp[son][B] % Pr) %=
                  Pr;
            }
        }
      tr[fa] += tr[son];
    }
  }
  for (int i = has.size() - 1; i >= 0; --i) (ans += dp[fa][has[i]]) %= Pr;
}
int ctalc(int fa, int anc) {
  tr[fa] = 1;
  vector<pair<int, int> > vct;
  vct.clear();
  for (int i = t[fa].size() - 1; i >= 0; --i) {
    int son = t[fa][i];
    if (son != anc) {
      vct.push_back(make_pair(ctalc(son, fa), son));
      tr[fa] += tr[son];
    }
  }
  int ans = 1;
  sort(vct.begin(), vct.end());
  for (int i = (int)vct.size() - 1; i >= 0; --i) {
    ans <<= (tr[vct[i].second] << 1);
    ans |= vct[i].first;
  }
  ans <<= 1;
  return ans;
}
int main() {
  scanf("%d", &n);
  for (int i = 2; i <= n; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    s[u].push_back(v);
    s[v].push_back(u);
  }
  scanf("%d", &m);
  for (int i = 2; i <= m; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    t[u].push_back(v);
    t[v].push_back(u);
  }
  init();
  for (int i = 1; i <= m; ++i) has.push_back(ctalc(i, 0));
  sort(has.begin(), has.end());
  it = unique(has.begin(), has.end());
  has.resize(distance(has.begin(), it));
  dfs(1, 0);
  printf("%lld\n", ans);
  return 0;
}
