#include <bits/stdc++.h>
#define debug(x) cout << #x << " = " << x << endl
#define REP(i, n) for (Long i = 0; i < (Long)n; i++)
using namespace std;

typedef long long Long;

const int MX = 3e5;
vector<Long> adj[MX];
set<pair<Long,Long>> queries[MX];
Long saved[MX];
Long single[MX];
Long cnt[2 * MX + 8];
Long ans = 0;

void merge(Long u, Long v, Long gU, Long gV, Long lowLimit, Long &curGroup, map<pair<Long, Long>, Long> &crossedCnt) {
	//u to v
	if (queries[saved[u]].size() > queries[saved[v]].size()) {
		swap(u, v);
		swap(gU, gV);
	} 
	for (auto p : queries[saved[u]]) {
		Long x = p.first;
		auto it = queries[saved[v]].lower_bound({x, -1});
		if (it != queries[saved[v]].end() && it->first == x) {
			pair<Long, Long> pairIndex = {p.second, it->second};
			queries[saved[v]].erase(it);
			if (pairIndex.first < lowLimit) {
				pairIndex.first = gU;
			}
			if (pairIndex.second < lowLimit) {
				pairIndex.second = gV;
			}
		
			Long a = min(pairIndex.first, pairIndex.second);
			Long b = max(pairIndex.first, pairIndex.second);
			if (a != lowLimit) {
				crossedCnt[{a, b}]++;
				cnt[a]--;
				cnt[b]--;
			} else {
				cnt[b]--;
			}
			
		} else {
			Long gInsert = p.second;
			if (gInsert < lowLimit) {
				gInsert = gU;
			}
			queries[saved[v]].insert({x, gInsert});
		}
	}
	curGroup = gV;
	saved[u] = saved[v];
}

Long groups = 1;
void dfs(Long u, Long p = -1) {
	Long sz = queries[u].size();
	Long T = 2 * single[u] + sz;
	Long cur = 0;
	
	map<pair<Long, Long>, Long> crossedCnt;
	
	for (Long v : adj[u]) {
		if (v != p) {
			dfs(v, u);
		}
	}
	Long lowLimit = groups;
	groups++;
	Long curGroup = lowLimit;;
	for (Long v : adj[u]) {
		if (v != p) {
			sz = queries[saved[v]].size();
			T += sz;
			cur -= sz * (sz - 1) / 2;
			Long g = groups++;
			cnt[g] += sz;
			Long gU = curGroup;
			merge(u, v, gU, g, lowLimit, curGroup, crossedCnt);
		}
	}
	sz = queries[saved[u]].size();
	T += sz;
	cur -= sz * (sz - 1) / 2;
	assert(T % 2 == 0);
	T /= 2;
	
	cur += T * (T - 1) / 2;
	for (auto crossed : crossedCnt) {
		sz = crossed.second;
		cur += sz * (sz - 1) / 2;
	}
	for (Long i = lowLimit + 1; i < groups; i++) {
		cur += cnt[i] * (cnt[i] - 1) / 2;
	}
	ans += cur;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	Long n;
	cin >> n;
	REP(i , n - 1) {
		Long u, v;
		cin >> u >> v;
		u--;
		v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	REP(i , n) {
		saved[i] = i;
	}
	Long m;
	cin >> m;
	
	REP(i, m) {
		Long u , v;
		cin >> u >> v;
		u--;
		v--;
		if (u != v) {
			queries[u].insert({i, 0});
			queries[v].insert({i, 0});
		} else {
			single[u]++;
		}

	}
	dfs(0);
	assert(groups <= 2 * n);
	cout << ans << "\n";


	return 0;
}
