#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <vector>
using namespace std;
using ll = long long;
#define fst first
#define snd second

/* clang-format off */
template <class T, size_t D> struct _vec { using type = vector<typename _vec<T, D - 1>::type>; };
template <class T> struct _vec<T, 0> { using type = T; };
template <class T, size_t D> using vec = typename _vec<T, D>::type;
template <class T> vector<T> make_v(size_t size, const T& init) { return vector<T>(size, init); }
template <class... Ts> auto make_v(size_t size, Ts... rest) { return vector<decltype(make_v(rest...))>(size, make_v(rest...)); }
template <class T> inline void chmin(T &a, const T& b) { if (b < a) a = b; }
template <class T> inline void chmax(T &a, const T& b) { if (b > a) a = b; }
/* clang-format on */

#define all(c) ((c).begin()), ((c).end())

struct tree {
  int n;
  vector<vector<int>> adj;
  tree(int n)
      : n(n), adj(n) {
  }
  void add_edge(int s, int t) {
    adj[s].push_back(t);
    adj[t].push_back(s);
  }
  vector<int> pos, tour, depth;
  vector<vector<int>> table;
  int argmin(int i, int j) {
    return depth[i] < depth[j] ? i : j;
  }
  void rootify(int r) {
    pos.resize(n);
    function<void(int, int, int)> dfs = [&](int u, int p, int d) {
      pos[u] = depth.size();
      tour.push_back(u);
      depth.push_back(d);
      for (int v : adj[u]) {
        if (v != p) {
          dfs(v, u, d + 1);
          tour.push_back(u);
          depth.push_back(d);
        }
      }
    };
    dfs(r, r, 0);
    int logn = sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(tour.size());  // log2
    table.resize(logn + 1, vector<int>(tour.size()));
    iota(all(table[0]), 0);
    for (int h = 0; h < logn; ++h)
      for (int i = 0; i + (1 << h) < tour.size(); ++i)
        table[h + 1][i] = argmin(table[h][i], table[h][i + (1 << h)]);
  }
  int lca(int u, int v) {
    int i = pos[u], j = pos[v];
    if (i > j) swap(i, j);
    int h = sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(j - i);  // = log2
    return i == j ? u : tour[argmin(table[h][i], table[h][j - (1 << h)])];
  }
  bool is_in_path(int u, int v, int x) {
    int l = lca(u, v);
    if (lca(l, x) != l) return false;
    return (lca(u, x) == x) || (lca(v, x) == x);
  }
};

using pii = pair<int, int>;

int main() {
#ifdef DEBUG
  ifstream ifs("in.txt");
  cin.rdbuf(ifs.rdbuf());
#endif
  int N;
  while (cin >> N) {
    tree G(N);
    vector<pii> edges;
    for (int i = 0; i < N - 1; i++) {
      int a, b;
      cin >> a >> b;
      --a;
      --b;
      G.add_edge(a, b);
      edges.emplace_back(a, b);
    }
    int M;
    cin >> M;
    vector<pii> rule;
    for (int i = 0; i < M; i++) {
      int a, b;
      cin >> a >> b;
      --a;
      --b;
      rule.emplace_back(a, b);
    }
    G.rootify(0);
    vector<int> mask(N - 1);
    for (int i = 0; i < N - 1; i++) {
      int x = edges[i].fst, y = edges[i].snd;
      for (int j = 0; j < M; j++) {
        int u = rule[j].fst, v = rule[j].snd;
        if (G.is_in_path(u, v, x) && G.is_in_path(u, v, y)) {
          mask[i] |= 1 << j;
        }
      }
    }
    vector<ll> dp(1 << M, 0);
    dp[0] = 1;
    for (int i = 0; i < N - 1; i++) {
      for (int m = (1 << M) - 1; m >= 0; m--) {
        dp[m | mask[i]] += dp[m];
      }
    }
    cout << dp.back() << endl;
  }
  return 0;
}


Measured memory_bytes: 8448