//
//  main.cpp
//

#include <algorithm>
#include <array>
#include <assert.h>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <memory>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ll = int64_t;
using ull = uint64_t;
constexpr ll LL_MAX = numeric_limits<ll>::max();
constexpr ull ULL_MAX = numeric_limits<ull>::max();

template<typename T>
vector<T> make_vec_nd(T init, ll size) {
	return vector<T>(size, init);
}
template<typename T, typename... Args>
auto make_vec_nd(T init, ll size, Args... rest) {
	auto inner = make_vec_nd(init, rest...);
	return vector<decltype(inner)>(size, inner);
}

#define rep(i, a, b) for (ll i = (a); i < (b); i++)
#define rrep(i, a, b) for (ll i = (a)-1; i >= (b); i--)

struct RootTree {
    struct Node {
        size_t parent = -1;
        vector<size_t> child;
    };
    vector<Node> nodes;
    RootTree(size_t n) { nodes = vector<Node>(n, Node{(size_t)-1, {}}); }
    void set_child(size_t p, size_t c) {
        assert(0 <= p && p < nodes.size());
        assert(0 <= c && c < nodes.size());
        assert(nodes[c].parent == -1);
        nodes[p].child.push_back(c);
        nodes[c].parent = p;
    }
    vector<vector<size_t>> doubling_parents_table() {
        // return[k][i] = ノードiから2^k登ったところにあるノード（ルートを超える時は-1）
        vector<vector<size_t>> ans;
        int k = 0;
        while (true) {
            ans.push_back(vector<size_t>(nodes.size(), -1));
            bool proceed = false;
            for (int i = 0; i < nodes.size(); i++) {
                if (k == 0) {
                    ans[k][i] = nodes[i].parent;
                } else {
                    size_t half = ans[k - 1][i];
                    if (half == -1) {
                        ans[k][i] = -1;
                    } else {
                        ans[k][i] = ans[k - 1][half];
                    }
                }
                if (ans[k][i] != -1) {
                    proceed = true;
                }
            }
            if (!proceed) {
                break;
            }
            k++;
        }
        return ans;
    }
    vector<size_t> depth_table(size_t root) {
        // return[i] = ノードiの深さ
        vector<size_t> ans(nodes.size(), -1);
        vector<size_t> stack;
        stack.push_back(root);
        ans[root] = 0;
        while (stack.size() > 0) {
            size_t node = stack.back();
            stack.pop_back();
            assert(ans[node] != -1);
            for (size_t child : nodes[node].child) {
                ans[child] = ans[node] + 1;
                stack.push_back(child);
            }
        }
        return ans;
    }
    size_t lca(size_t a, size_t b, const vector<size_t>& depth,
               const vector<vector<size_t>>& parent) {
        assert(0 <= a && a < nodes.size());
        assert(0 <= b && b < nodes.size());
        if (depth[a] != depth[b]) {
            if (depth[a] < depth[b]) {
                swap(a, b);
            }
            size_t diff = depth[a] - depth[b];
            while (diff != 0) {
                int n = 0;
                while (true) {
                    if (diff < (1 << (n + 1))) {
                        break;
                    }
                    n++;
                }
                assert(diff >= (1 << n));
                a = parent[n][a];
                diff = depth[a] - depth[b];
            }
        }
        while (true) {
            if (a == b) {
                return a;
            }
            if (parent[0][a] == parent[0][b]) {
                return parent[0][a];
            }
            int n = 0;
            while (true) {
                if (parent[n + 1][a] == parent[n + 1][b]) {
                    break;
                }
                n++;
            }
            a = parent[n][a];
            b = parent[n][b];
        }
    }
};

void create_tree(vector<vector<ll>>& graph, vector<bool> visited, RootTree& tree, ll now) {
    if (visited[now]) {
        return;
    }
    visited[now] = true;
    for (ll to : graph[now]) {
        if (visited[to]) {
            continue;
        }
        tree.set_child(now, to);
        create_tree(graph, visited, tree, to);
    }
}

int main() {
    ll N;
    cin >> N;
    struct Edge {
        ll a;
        ll b;
        Edge(ll aa, ll ab) : a(aa), b(ab) {
            if (a > b) {
                swap(a, b);
            }
        }
        uint64_t encode() {
            return (b << 32) | a;
        }
    };
    vector<Edge> edges(N-1, Edge(0, 0));
    unordered_map<uint64_t, ll> edge_to_idx;
    vector<vector<ll>> graph(N);
    rep(i,0,N-1) {
        ll a, b;
        cin >> a >> b;
        a--;
        b--;
        Edge e = Edge(a, b);
        edges[i] = e;
        edge_to_idx[e.encode()] = i;
        graph[a].push_back(b);
        graph[b].push_back(a);
    }
    ll M;
    cin >> M;
    struct Range {
        ll u;
        ll v;
    };
    vector<Range> ranges(M);
    rep(i,0,M) {
        ll u, v;
        cin >> u >> v;
        u--;
        v--;
        ranges[i] = Range{u, v};
    }
    RootTree tree(N);
    vector<bool> visited(N);
    create_tree(graph, visited, tree, 0);
    vector<uint32_t> masks(N-1);
    vector<vector<size_t>> parents_table = tree.doubling_parents_table();
    vector<size_t> depth_table = tree.depth_table(0);
    rep(i,0,M) {
        Range range = ranges[i];
        ll u = range.u;
        ll v = range.v;
        ll lca = tree.lca(u, v, depth_table, parents_table);
        for (ll now : {u, v}) {
            while (now != lca) {
                ll p = tree.nodes[now].parent;
                masks[edge_to_idx[Edge(now, p).encode()]] |= 1 << i;
                now = p;
            }
        }
    }
    auto dp = make_vec_nd((ll)0, N, 1<<M);
    dp[0][0] = 1;
    rep(edge_cnt,0,N-1) {
        rep(flag,0,1<<M) {
            dp[edge_cnt+1][flag] += dp[edge_cnt][flag];
            dp[edge_cnt+1][flag | masks[edge_cnt]] += dp[edge_cnt][flag];
        }
    }
    cout << dp[N-1][(1<<M) - 1] << endl;
}


Measured memory_bytes: 418304