#include <bits/stdc++.h>
using namespace std;
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
*/
#define int long long
#define REP(i,n) for(int i = 0;i < (int)(n);i++)
#define RREP(i,n) for(int i = (int)n-1;i >= 0;i--)
#define FOR(i,s,n) for(int i = s;i < (int)n;i++)
#define RFOR(i,s,n) for(int i = (int)n-1;i >= s;i--)
#define ALL(a) a.begin(),a.end()
#define IN(a, x, b) (a<=x && x<b)
template<class T>inline bool CHMAX(T&a,T b){if(a<b){a = b;return true;}return false;}
template<class T>inline bool CHMIN(T&a,T b){if(a>b){a = b;return true;}return false;}
template<class T>istream&operator >>(istream&is,vector<T>&vec){for(T&x:vec)is>>x;return is;}
template<class T>inline void in(T&t){cin>>t;}
template<class T,class... Ts>inline void in(T&t,Ts&...ts){cin>>t;in(ts...);}
template<class T>inline void out(T t){cout<<t<<endl;}
template<class T,class... Ts>inline void out(T t,Ts... ts){cout<<t<<" ";out(ts...);}
template<typename T=int>vector<T>mv(size_t a){return vector<T>(a);}
template<typename T=int,typename... Ts>auto mv(size_t a,Ts... ts){return vector<decltype(mv<T>(ts...))>(a,mv<T>(ts...));}
template<typename T,typename V>typename enable_if<is_class<T>::value==0>::type fill(T&t,const V&v){t=v;}
template<typename T,typename V>typename enable_if<is_class<T>::value!=0>::type fill(T&t,const V&v){for(auto &e:t)fill(e,v);}
constexpr long long INF = 1e18;

template<int MOD> struct Fp {
	long long val;
	constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
		if (val < 0) val += MOD;
	}
	constexpr int getmod() { return MOD; }
	constexpr Fp operator - () const noexcept {
		return val ? MOD - val : 0;
	}
	constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }
	constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }
	constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }
	constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }
	constexpr Fp& operator += (const Fp& r) noexcept {
		val += r.val;
		if (val >= MOD) val -= MOD;
		return *this;
	}
	constexpr Fp& operator -= (const Fp& r) noexcept {
		val -= r.val;
		if (val < 0) val += MOD;
		return *this;
	}
	constexpr Fp& operator *= (const Fp& r) noexcept {
		val = val * r.val % MOD;
		return *this;
	}
	constexpr Fp& operator /= (const Fp& r) noexcept {
		long long a = r.val, b = MOD, u = 1, v = 0;
		while (b) {
			long long t = a / b;
			a -= t * b; swap(a, b);
			u -= t * v; swap(u, v);
		}
		val = val * u % MOD;
		if (val < 0) val += MOD;
		return *this;
	}
	constexpr bool operator == (const Fp& r) const noexcept {
		return this->val == r.val;
	}
	constexpr bool operator != (const Fp& r) const noexcept {
		return this->val != r.val;
	}
	friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept {
		return os << x.val;
	}
	friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
		if (n == 0) return 1;
		auto t = modpow(a, n / 2);
		t = t * t;
		if (n & 1) t = t * a;
		return t;
	}
};
 
// 二項係数ライブラリ
template<class T> struct BiCoef {
	vector<T> fact_, inv_, finv_;
	constexpr BiCoef() {}
	constexpr BiCoef(int n) noexcept : fact_(n, 1), inv_(n, 1), finv_(n, 1) {
		init(n);
	}
	constexpr void init(int n) noexcept {
		fact_.assign(n, 1), inv_.assign(n, 1), finv_.assign(n, 1);
		int MOD = fact_[0].getmod();
		for(int i = 2; i < n; i++){
			fact_[i] = fact_[i-1] * i;
			inv_[i] = -inv_[MOD%i] * (MOD/i);
			finv_[i] = finv_[i-1] * inv_[i];
		}
	}
	constexpr T com(int n, int k) const noexcept {
		if (n < k || n < 0 || k < 0) return 0;
		return fact_[n] * finv_[k] * finv_[n-k];
	}
	constexpr T fact(int n) const noexcept {
		if (n < 0) return 0;
		return fact_[n];
	}
	constexpr T inv(int n) const noexcept {
		if (n < 0) return 0;
		return inv_[n];
	}
	constexpr T finv(int n) const noexcept {
		if (n < 0) return 0;
		return finv_[n];
	}
};
 
const int MOD = 1000000007;
// const int MOD = 
using mint = Fp<MOD>;
BiCoef<mint> bc;
// bc.init(500050);

template< typename T >
struct edge {
  int src, to;
  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {
	to = x;
	return *this;
  }

  operator int() const { return to; }
};
template< typename T >
using Edges = vector< edge< T > >;
template< typename T >
using WeightedGraph = vector< Edges< T > >;
using UnWeightedGraph = vector< vector< int > >;
template< typename T >
using Matrix = vector< vector< T > >;
template< typename G >
struct DoublingLowestCommonAncestor {
  const int LOG;
  vector< int > dep;
  const G &g;
  vector< vector< int > > table;

  DoublingLowestCommonAncestor(const G &g) : g(g), dep(g.size()), LOG(32 - __builtin_clz(g.size())) {
	table.assign(LOG, vector< int >(g.size(), -1));
  }

  void dfs(int idx, int par, int d) {
	table[0][idx] = par;
	dep[idx] = d;
	for(auto &to : g[idx]) {
	  if(to != par) dfs(to, idx, d + 1);
	}
  }

  void build() {
	dfs(0, -1, 0);// ここを書き換えれば親を選択できる
	for(int k = 0; k + 1 < LOG; k++) {
	  for(int i = 0; i < table[k].size(); i++) {
		if(table[k][i] == -1) table[k + 1][i] = -1;
		else table[k + 1][i] = table[k][table[k][i]];
	  }
	}
  }
  
  int getDep(int x){return dep[x];};
  int getDist(int a,int b){
	int parDepth = getDep(query(a,b));
	return getDep(a)-parDepth+getDep(b)-parDepth;
  }

  int query(int u, int v) {
	if(dep[u] > dep[v]) swap(u, v);
	for(int i = LOG - 1; i >= 0; i--) {
	  if(((dep[v] - dep[u]) >> i) & 1) v = table[i][v];
	}
	if(u == v) return u;
	for(int i = LOG - 1; i >= 0; i--) {
	  if(table[i][u] != table[i][v]) {
		u = table[i][u];
		v = table[i][v];
	  }
	}
	return table[0][u];
  }
};

signed main(){
	int N;
	in(N);
	UnWeightedGraph g(N);
	map<pair<int,int>,int>mp;
	int count = 0;
	REP(i,N-1){
		int a,b;
		in(a,b);
		a--;b--;
		g[a].push_back(b);
		g[b].push_back(a);
		mp[minmax(a,b)]=count++;
	}
	int M;
	in(M);
	vector<int>a(M),b(M);
	REP(i,M){
		in(a[i],b[i]);
		--a[i];--b[i];
	}
	auto bits = mv(1ll << M);
	auto dfs = [&](auto&&f,int now,int par,int target,int bit)->bool{
		if(now == target)return true;
		int flg = 0;
		for(auto e:g[now]){
			if(e == par)continue;
			if(f(f,e,now,target,bit)){bits[1ll << bit] |= 1ll << mp[minmax(now,e)];flg = 1;}
		}
		return flg;
	};
	REP(i,M){
		dfs(dfs,a[i],-1,b[i],i);
	}
	REP(i,1ll<<M){
		REP(j,M){
			if(i & (1ll << j))continue;
			bits[i ^ (1ll << j)] |= bits[i];
		}
	}
	int ans = 0;
	REP(i,1ll<<M){
		int cnt = __builtin_popcount(i);
		int edges = 0;
		REP(j,N-1)if(bits[i]&(1ll << j))edges++;
		if(cnt % 2)ans -= 1ll << (N - 1ll - edges);
		else ans += 1ll << (N - 1ll - edges);
	}
	out(ans);
}

Measured memory_bytes: 8448