30 30 10
6 1
8 27
5 1
21 6
24 15
12 5
29 7
22 7
23 17
2 13
23 11
29 6
14 18
29 16
27 25
15 2
27 4
19 30
28 19
17 2
27 16
3 4
9 25
19 16
10 16
18 17
26 11
2 27
16 20
13 23
1 4
27 7
6 20
17 30
1 18
2 17
1 11
5 9
25 13
11 20
14 25
30 21
6 24
12 2
25 12
22 13
10 27
24 29
19 24
28 29
24 23
9 6
12 15
11 15
23 14
12 28
28 25
2 11
19 30
 2 2 1
1 2
2 1
1 2

0 1
#include<bits/stdc++.h>
#define ll long long
#define cri const register int
#define re register
using namespace std;
inline int read(re int a=0,re char ch=getchar()){
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48),ch=getchar();
	return a;
}
int tot;
struct node{
	int ls,rs,da;
}T[5000010];
void A(int &k,cri l,cri r,cri x){
	if(!k) k=++tot;T[k].da++;
	if(l==r) return;
	cri mid=l+r>>1;
	if(x<=mid) A(T[k].ls,l,mid,x);
	else A(T[k].rs,mid+1,r,x);
}
int G(cri k,cri l,cri r,cri L,cri R){
	if(l>=L&&r<=R||!k) return T[k].da;
	cri mid=l+r>>1;int ans=0;
	if(L<=mid) ans+=G(T[k].ls,l,mid,L,R);
	if(R>mid) ans+=G(T[k].rs,mid+1,r,L,R);
	return ans;
}
int fa[150010],to[300010],la[300010],in[150010],out[150010],dep[150010],pre[19][300010],bin[300010],cnt,num;
int f[19][150010],t[150010],sta[150010],top,rt,c[300010];
int Fa[150010],To[150010],La[150010],n,m,k,Rt[150010];
inline void add(cri x,cri y){
	for(int i=x;i<=num;i+=i&-i) c[i]+=y;
}
inline int get(cri x,int ans=0){
	for(int i=x;i;i-=i&-i) ans+=c[i];
	return ans;
}
inline void adde(cri x,cri y){
	to[++cnt]=y,la[cnt]=fa[x],fa[x]=cnt;
	to[++cnt]=x,la[cnt]=fa[y],fa[y]=cnt;
}
inline void addE(cri x,cri y){
	To[++cnt]=y,La[cnt]=Fa[x],Fa[x]=cnt;
	To[++cnt]=x,La[cnt]=Fa[y],Fa[y]=cnt;
}

vector<int>son[150010],oth[150010];
void pre_dfs(cri x,cri ff){
	pre[0][++num]=x;in[x]=num;dep[x]=dep[ff]+1;
	f[0][x]=ff;
	//cout<<x<<" "<<num<<endl;
	for(int i=1;(1<<i)<=dep[x];i++) f[i][x]=f[i-1][f[i-1][x]];
	for(int i=fa[x];i;i=la[i]) if(to[i]!=ff)
		pre_dfs(to[i],x),pre[0][++num]=x,son[x].push_back(in[to[i]]);
	out[x]=num;
}
inline int jmp(int x,cri d){
	for(int i=18;~i;i--) if((d>>i)&1) x=f[i][x];
	return x;
}
inline int wt(cri x,cri y){
	return upper_bound(son[x].begin(),son[x].end(),in[y])-son[x].begin();
}
inline int Min(cri x,cri y){
	return dep[x]<dep[y]?x:y;
}
inline int lca(int x,int y){
	x=in[x];y=in[y];
	if(x>y) swap(x,y);
	cri b=bin[y-x+1];
	return Min(pre[b][y],pre[b][x+(1<<b)-1]);
}
ll ans;
vector<pair<int,int> >has[150010];
inline char as(const pair<int,int>&A,const pair<int,int>&B){
	return in[A.first]<in[B.first];
}
inline void insert(cri x){
	if(top==1) return sta[++top]=x,void();
	cri L=lca(x,sta[top]);
	if(L==sta[top]) return sta[++top]=x,void(); 
	while(top>1&&in[sta[top-1]]>=in[L]) addE(sta[top-1],sta[top]),top--;
	if(L!=sta[top]) addE(sta[top],L),sta[top]=L;
	sta[++top]=x;
}
void dfss(cri x,cri ff){//cout<<x<<endl;
	for(int i=Fa[x];i;i=La[i])
		if(To[i]!=ff) dfss(To[i],x);
	for(int i=0;i<oth[x].size();i++){
		cri y=oth[x][i];int z;
		if(dep[x]-dep[rt]>=k) z=jmp(x,k);
		else z=jmp(y,dep[y]-dep[rt]-(k-(dep[x]-dep[rt])));
		ans+=G(Rt[x],1,num,in[z],out[z]);A(Rt[x],1,num,in[y]);
	}
	for(int i=Fa[x];i;i=La[i])if(To[i]!=ff){
		cri y=To[i];
		if(oth[x].size()<oth[y].size())swap(oth[x],oth[y]),swap(Rt[x],Rt[y]);
		for(int j=0;j<oth[y].size();j++){
			cri p=oth[y][j];int z;
			if(dep[x]-dep[rt]>=k) z=jmp(x,k);
			else z=jmp(p,dep[p]-dep[rt]-(k-(dep[x]-dep[rt])));
			//cout<<p<<" "<<z<<endl;
			ans+=G(Rt[x],1,num,in[z],out[z]);A(Rt[x],1,num,in[p]);
			oth[x].push_back(p);
		}
		Rt[y]=0;oth[y].clear();
	}
	Fa[x]=0;
}
void dfs(cri x,cri ff){
	for(int i=fa[x];i;i=la[i]) if(to[i]!=ff) dfs(to[i],x);
	sort(has[x].begin(),has[x].end(),as);
	int lst=t[0]=0;t[++t[0]]=x;
	for(int i=0;i<has[x].size();i++){	
		if(i&&wt(x,has[x][i].first)!=wt(x,has[x][i-1].first))
			while(lst<i) {
				cri a=has[x][lst].first,b=has[x][lst].second;
				if(dep[a]-dep[x]>=k) {
					cri c=jmp(a,(dep[a]-dep[x])-k);
					add(in[c],1);add(out[c]+1,-1);//cout<<a<<" "<<c<<endl;
				}
				if(dep[b]-dep[x]>=k) {
					cri c=jmp(b,(dep[b]-dep[x])-k);
					add(in[c],1);add(out[c]+1,-1);//cout<<b<<" "<<c<<endl;
				}
				lst++;
			}
		ans+=get(in[has[x][i].first])+get(in[has[x][i].second]);
		oth[has[x][i].first].push_back(has[x][i].second);t[++t[0]]=has[x][i].first;
	}//cout<<x<<endl;
	while(lst<has[x].size()){
		cri a=has[x][lst].first,b=has[x][lst].second;
		if(dep[a]-dep[x]>=k) {
			cri c=jmp(a,(dep[a]-dep[x])-k);//cout<<a<<" "<<c<<endl;
			add(in[c],1);add(out[c]+1,-1);
		}
		if(dep[b]-dep[x]>=k) {
			cri c=jmp(b,(dep[b]-dep[x])-k);//cout<<b<<" "<<c<<endl;
			add(in[c],1);add(out[c]+1,-1);
		}
		lst++;
	}
	t[0]=unique(t+1,t+t[0]+1)-t-1;
	sta[++top]=rt=t[1];
	for(int i=2;i<=t[0];i++) insert(t[i]);//,cout<<t[i]<<" ";puts("");
	while(top>1) addE(sta[top-1],sta[top]),top--;
	//cout<<ans<<"->"<<endl;
	dfss(x,0);Rt[x]=cnt=top=0;//cout<<"->"<<ans<<endl;
	while(tot) T[tot].ls=T[tot].rs=T[tot].da=0,tot--;
}
int main(){
	n=read(),m=read(),k=read();
	for(int i=1;i<n;i++) adde(read(),read());cnt=0;
	pre_dfs(1,0);//cout<<1<<endl;
	for(int i=2;i<=num;i++) bin[i]=bin[i>>1]+1;
	for(int i=1;i<=num;i++)
		for(int j=1;(1<<j)<=i;j++)
			pre[j][i]=Min(pre[j-1][i],pre[j-1][i-(1<<j-1)]);
	for(int i=1;i<=m;i++){
		int s=read(),t=read(),p=lca(s,t);
		if(in[s]>in[t]) swap(s,t);
		//cout<<s<<" "<<t<<" "<<lca(s,t)<<endl;
		if(dep[s]+dep[t]-2*dep[p]<k) {
			i--;m--;
			continue;
		}
		has[p].push_back(make_pair(s,t));
	}
	dfs(1,0);
	cout<<ans<<endl;
}
