#include<iostream>
#include<cstring>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define int long long
using namespace std;
inline int read(){
	int f=1,ans=0; char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
	return f*ans;
}
const int MAXN=3e5+11;
vector<int> vec[MAXN]; 
int N,M,fa[MAXN][21],dep[MAXN],dfn[MAXN],siz[MAXN],Ans; struct node{int u,v,Lca,a,b;}Q[MAXN];
struct BIT{
	int Ans[MAXN];
	int lowbit(int x){return x&-x;}
	void Modify(int x,int w){for(;x<=N;x+=lowbit(x)) Ans[x]+=w;return;}
	int Query(int x){int res=0; for(;x;x-=lowbit(x)) res+=Ans[x]; return res;}
	int Qsum(int l,int r){return Query(r)-Query(l-1);}
}S;
void dfs(int u,int fath){
	dep[u]=dep[fath]+1,fa[u][0]=fath; dfn[u]=++dfn[0],siz[u]=1; for(int i=1;(1<<i)<=dep[u];i++) fa[u][i]=fa[fa[u][i-1]][i-1];
	for(auto v:vec[u]) if(v!=fath) dfs(v,u),siz[u]+=siz[v]; return;
}
int QLca(int u,int v){
	if(dep[u]<dep[v]) swap(u,v); for(int i=20;i>=0;i--) if(dep[fa[u][i]]>=dep[v]) u=fa[u][i];
	if(u==v) return u; for(int i=20;i>=0;i--) if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i]; return fa[u][0];
}
int QGo(int u,int fath){
	if(u==fath) return -1;
	for(int i=20;i>=0;i--) if(dep[fa[u][i]]>dep[fath]) u=fa[u][i]; return u;
}
vector<pii> Vec[MAXN];
int Num[MAXN]; map<pii,int> Ma;
void Solve1(){
	for(int i=1;i<=M;i++) Vec[Q[i].Lca].pb(mp(Q[i].a,Q[i].b));
	
	for(int i=1;i<=N;i++){
		int siz=Vec[i].size();
		Ans+=(siz*(siz-1))/2; Ma.clear();
		for(auto pp:Vec[i]){
			if(pp.fi!=-1) Ans-=Num[pp.fi],Num[pp.fi]++;
			if(pp.se!=-1) Ans-=Num[pp.se],Num[pp.se]++;
			if(pp.fi!=-1&&pp.se!=-1) Ans+=Ma[mp(pp.fi,pp.se)],Ma[mp(pp.fi,pp.se)]++;
		}
		for(auto pp:Vec[i]){
			if(pp.fi!=-1) Num[pp.fi]=0;
			if(pp.se!=-1) Num[pp.se]=0;
		}
	}
}
vector<int> buc[MAXN];
void Solve2(){
	for(int i=1;i<=M;i++) buc[dep[Q[i].Lca]].pb(i),S.Modify(dfn[Q[i].u],1),S.Modify(dfn[Q[i].v],1);
	for(int i=N;i>=1;i--){
		for(auto id:buc[i]) S.Modify(dfn[Q[id].u],-1),S.Modify(dfn[Q[id].v],-1);
		for(auto id:buc[i]){
			Ans+=S.Qsum(dfn[Q[id].Lca],dfn[Q[id].Lca]+siz[Q[id].Lca]-1);
			if(Q[id].a!=-1) Ans-=S.Qsum(dfn[Q[id].a],dfn[Q[id].a]+siz[Q[id].a]-1);
			if(Q[id].b!=-1) Ans-=S.Qsum(dfn[Q[id].b],dfn[Q[id].b]+siz[Q[id].b]-1);
		}
	}return;
}
signed main(){
	//freopen("3.in","r",stdin);
	N=read(); for(int i=1;i<N;i++){int u=read(),v=read();vec[u].pb(v),vec[v].pb(u);}
	dfs(1,0); M=read();
	for(int i=1;i<=M;i++){
		Q[i].u=read(),Q[i].v=read(),Q[i].Lca=QLca(Q[i].u,Q[i].v);
		Q[i].a=QGo(Q[i].u,Q[i].Lca),Q[i].b=QGo(Q[i].v,Q[i].Lca);
		if(Q[i].a>Q[i].b) swap(Q[i].u,Q[i].v),swap(Q[i].a,Q[i].b);
	}
	Solve1(); Solve2();
	printf("%lld\n",Ans); return 0;
}