#include <stdio.h>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>

int make_rooted_tree(std::vector<std::vector<long long int> > &G, long long int N, long long int root_index, std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &par);
// subroutine of make_rooted_tree must not be called in other places
int sub_make_rooted_tree(std::vector<std::vector<long long int> > &G, long long int N, long long int root_index, std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &par);

int main(){
  
  // read problem
  long long int N, tmp1, tmp2;
  scanf("%lld", &N);

  std::vector<std::vector<long long int> > G(N), G2(N);
  for(long long int i = 0; i < N; i++){
    for(long long int j = 0;  j < N; j++){
      G[i].push_back(-1);
    }
  }

  for(long long int i = 0; i < N-1; i++){
    scanf("%lld%lld", &tmp1, &tmp2);
    G[tmp1-1][tmp2-1] = i;
    G[tmp2-1][tmp1-1] = i;
    G2[tmp1-1].push_back(tmp2-1);
    G2[tmp2-1].push_back(tmp1-1);
  }

 

  std::vector<std::vector<long long int> > G2_rooted(N);
  std::vector<long long int> par(N);

  make_rooted_tree(G2, N, 0, G2_rooted, par);

  long long int M;
  scanf("%lld", &M);
  std::vector<long long int> u, v;
  for(long long int i = 0; i < M; i++){
    scanf("%lld%lld", &tmp1, &tmp2);
    u.push_back(tmp1-1);
    v.push_back(tmp2-1);
  }

  /*
  std::cerr << "G: " << std::endl;
  for(long long int i = 0; i < N; i++){
    for(long long int j = 0; j < N; j++){
      std::cerr << G[i][j] << " ";
    }std::cerr << std::endl;
  }

  std::cerr << "G2: " << std::endl;
  for(long long int i = 0; i < N; i++){
    std::cerr << i << ": ";
    for(long long int j = 0; j < G2[i].size(); j++){
      std::cerr << G2[i][j] << " ";
    }std::cerr << std::endl;
  } 

  std::cerr << "G2_rooted: " << std::endl;
  for(long long int i = 0; i < N; i++){
    std::cerr << i << ": " << par[i] << ": ";
    for(long long int j = 0; j < G2_rooted[i].size(); j++){
      std::cerr << G2_rooted[i][j] << " ";
    }std::cerr << std::endl;
  } 

  std::cerr << "M: " << M << std::endl;
  std::cerr << "uv: " << std::endl;
  for(long long int i = 0; i < M; i++){
    std::cerr << u[i] << " " << v[i] << std::endl;
  }

  */

  // make constraint table
  std::vector<long long int> tmp_vec1, tmp_vec2;
  std::vector<long long int> constraint_path(M);


  // for all constraints
  for(long long int i = 0; i < M; i++){
    tmp_vec1.clear();
    tmp_vec2.clear();

    tmp1 = u[i];
    while(tmp1 != par[tmp1]){
      tmp_vec1.push_back(G[tmp1][par[tmp1]]);
      tmp1 = par[tmp1];
    }
    
    tmp1 = v[i];
    while(tmp1 != par[tmp1]){
      tmp_vec2.push_back(G[tmp1][par[tmp1]]);
      tmp1 = par[tmp1];
    }

    tmp1 = tmp_vec1.size()-1;
    tmp2 = tmp_vec2.size()-1;
    while(tmp1 >= 0 && tmp2 >= 0 && tmp_vec1[tmp1] == tmp_vec2[tmp2]){
      tmp_vec1[tmp1] = -1;
      tmp_vec2[tmp2] = -1;
      tmp1--;
      tmp2--;
    }

    constraint_path[i] = 0;
    for(int j = 0; j < tmp_vec1.size(); j++){
      if(tmp_vec1[j] >= 0){
        constraint_path[i] += (1LL << tmp_vec1[j]);
      }
      else{
        break;
      }
    }
    for(int j = 0; j < tmp_vec2.size(); j++){
      if(tmp_vec2[j] >= 0){
        //std::cerr << "edge: " << tmp_vec2[j] << std::endl;
        constraint_path[i] += (1LL << tmp_vec2[j]);
      }
      else{
        break;
      }
    }
  }

  /*
  std::cerr << "constraints: " << std::endl;
  for(int i = 0; i < M; i++){
    std::cerr << constraint_path[i] << " ";
  }std::cerr << std::endl;
  */

  // solve problem

  
  long long int ans = 1LL << (N-1);

  long long int n_constraints;
  long long int n_edges;
  long long int S_edges;
  for(long long int S = 1; S < (1LL << M); S++){
    n_constraints = 0;
    n_edges = 0;
    S_edges = 0;
    for(long long int i = 0; i < M; i++){
      if((S>>i)&1){
        n_constraints++;
        S_edges = (S_edges | constraint_path[i]);
      }
    }
    for(long long int i = 0; i < N-1; i++){
      if((S_edges >> i) & 1){
        n_edges++;
      }
    }

    if(n_constraints%2 == 0){
      ans += (1LL << (N-1-n_edges));
    }
    else{
      ans -= (1LL << (N-1-n_edges));
    }
  }

  std::cerr << "Answer: " << std::endl;
  std::cout << ans << std::endl;

  return 0;

}


int make_rooted_tree(std::vector<std::vector<long long int> > &G, long long int N, long long int root_index, std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &par){
  // initialize par and call sub_make_rooted_tree
  par[root_index] = root_index;
  sub_make_rooted_tree(G, N, root_index, G_rooted, par);

  return 0;
}

int sub_make_rooted_tree(std::vector<std::vector<long long int> > &G, long long int N, long long int root_index, std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &par){

  for(long long int i = 0; i < G[root_index].size(); i++){
    // for all connected nodes but parent node
    if(G[root_index][i] != par[root_index]){
      par[G[root_index][i]] = root_index;
      G_rooted[root_index].push_back(G[root_index][i]);
      sub_make_rooted_tree(G, N, G[root_index][i], G_rooted, par);
    }
  }

  return 0;
}

Measured memory_bytes: 256