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>
typedef long long ll;
ll gi(){
	ll x=0,f=1;
	char ch=getchar();
	while(!isdigit(ch))f^=ch=='-',ch=getchar();
	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
	return f?x:-x;
}
std::mt19937 rnd(time(NULL));
#define rand rnd
#define pr std::pair<int,int>
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
template<class T>void cxk(T&a,T b){a=a>b?a:b;}
template<class T>void cnk(T&a,T b){a=a<b?a:b;}
#ifdef mod
int pow(int x,int y){
	int ret=1;
	while(y){
		if(y&1)ret=1ll*ret*x%mod;
		x=1ll*x*x%mod;y>>=1;
	}
	return ret;
}
template<class Ta,class Tb>void inc(Ta&a,Tb b){a=a+b>=mod?a+b-mod:a+b;}
template<class Ta,class Tb>void dec(Ta&a,Tb b){a=a>=b?a-b:a+mod-b;}
#endif
int n,m,K,fir[150010],dis[300010],nxt[300010],id;
ll ans;
void link(int a,int b){nxt[++id]=fir[a],fir[a]=id,dis[id]=b;}
int siz[150010],dep[150010],son[150010],top[150010],fa[150010],dfn[150010],end[150010];
void dfs(int x){
	siz[x]=1;
	for(int i=fir[x];i;i=nxt[i]){
		if(fa[x]==dis[i])continue;
		fa[dis[i]]=x;
		dep[dis[i]]=dep[x]+1;
		dfs(dis[i]);
		siz[x]+=siz[dis[i]];
		if(siz[son[x]]<siz[dis[i]])son[x]=dis[i];
	}
}
void dfs(int x,int tp){
	dfn[x]=++dfn[0];top[x]=tp;if(son[x])dfs(son[x],tp);
	for(int i=fir[x];i;i=nxt[i])if(fa[x]!=dis[i]&&son[x]!=dis[i])dfs(dis[i],dis[i]);
	end[x]=dfn[0];
}
int LCA(int x,int y){
	while(top[x]^top[y]){
		if(dep[top[x]]>dep[top[y]])x=fa[top[x]];
		else y=fa[top[y]];
	}
	return dep[x]<dep[y]?x:y;
}
int dist(int x,int y){return dep[x]+dep[y]-2*dep[LCA(x,y)];}
bool isAnc(int x,int y){return dfn[x]<=dfn[y]&&dfn[y]<=end[x];}
int pa[150010],pb[150010],pl[150010],pA[150010],pB[150010],pja[150010],pjb[150010],st[18][150010];
int jump(int x,int k){
	for(int i=17;~i;--i)if(k>>i&1)x=st[i][x];
	return x;
}
int jumpto(int x,int y,int z){
	if(dep[x]+dep[y]-2*dep[z]<K)return 0;
	return jump(y,dep[x]+dep[y]-2*dep[z]-K);
}
std::vector<int>vec[150010],vec2[150010],vec3[150010];
int ls[20000010],rs[20000010],sum[20000010],cnt;
#define mid ((l+r)>>1)
void update(int&x,int l,int r,int p,int d){
	if(!x)x=++cnt,ls[x]=rs[x]=sum[x]=0;sum[x]+=d;if(l==r)return;
	if(p<=mid)update(ls[x],l,mid,p,d);
	else update(rs[x],mid+1,r,p,d);
}
int query(int x,int l,int r,int L,int R){
	if(L<=l&&r<=R)return sum[x];
	if(L<=mid)
		if(mid<R)return query(ls[x],l,mid,L,R)+query(rs[x],mid+1,r,L,R);
		else return query(ls[x],l,mid,L,R);
	else return query(rs[x],mid+1,r,L,R);
}
int merge(int x,int y){
	if(!x||!y)return x+y;
	sum[x]+=sum[y];
	ls[x]=merge(ls[x],ls[y]);
	rs[x]=merge(rs[x],rs[y]);
	return x;
}
#undef mid
namespace sp1{
	int rt[150010],rt2[150010];
	void DFS(int x){
		for(int i=fir[x];i;i=nxt[i])if(fa[x]!=dis[i])DFS(dis[i]),rt[x]=merge(rt[x],rt[dis[i]]),rt2[x]=merge(rt2[x],rt2[dis[i]]);
		for(int i:vec[x]){
			update(rt[x],1,n,dfn[pl[i]],1);
			if(x==pa[i]?pjb[i]:pja[i])update(rt2[x],1,n,x==pa[i]?pjb[i]:pja[i],1);
		}
		for(int i:vec2[x]){
			update(rt[x],1,n,dfn[pl[i]],-2);
			if(pja[i])update(rt2[x],1,n,pja[i],-1);
			if(pjb[i])update(rt2[x],1,n,pjb[i],-1);
		}
		for(int i:vec3[x]){
			ans+=query(rt[x],1,n,dfn[pl[i]],dfn[pl[i]]);
			if(x==pA[i]?pjb[i]:pja[i])ans-=query(rt2[x],1,n,x==pA[i]?pjb[i]:pja[i],x==pA[i]?pjb[i]:pja[i]);
			for(int y=fa[pl[i]];y;y=fa[top[y]])ans+=query(rt[x],1,n,dfn[top[y]],dfn[y])*2;
		}
	}
}
namespace sp2{
	int num[150010],FA[150010],X;
	std::vector<int>G[150010];
	std::set<int>set[150010];
	int rt[150010];
	void DFS(int x){
		for(int i:vec[num[x]])
			if(pa[i]!=pl[i]&&pb[i]!=pl[i]&&dist(pa[i],pb[i])>=K){
				int y=dep[num[x]]-dep[X]<K?jumpto(num[x],isAnc(num[x],pa[i])?pb[i]:pa[i],X):(isAnc(num[x],pa[i])?pjb[i]:pja[i]);
				if(y)ans+=query(rt[x],1,n,dfn[y],end[y]);
				update(rt[x],1,n,dfn[num[x]==pa[i]?pb[i]:pa[i]],1),set[x].insert(i);
			}
		for(int i:G[x]){
			DFS(i);
			if(set[x].size()<set[i].size())std::swap(rt[x],rt[i]),set[x].swap(set[i]);
			if(x!=1){
				for(int j:set[i]){
					int y=dep[num[x]]-dep[X]<K?jumpto(num[x],isAnc(num[x],pa[j])?pb[j]:pa[j],X):(isAnc(num[x],pa[j])?pjb[j]:pja[j]);
					if(y)ans+=query(rt[x],1,n,dfn[y],end[y]);
					set[x].insert(j);
				}
				rt[x]=merge(rt[x],rt[i]);
			}
		}
	}
}
int main(){
#ifdef LOCAL
	freopen("in.in","r",stdin);
	//freopen("out.out","w",stdout);
#endif
	n=gi(),m=gi();K=gi();int u,v;
	for(int i=1;i<n;++i)u=gi(),v=gi(),link(u,v),link(v,u);
	dep[1]=1;dfs(1);dfs(1,1);
	for(int i=1;i<=n;++i)st[0][i]=fa[i];
	for(int i=1;i<18;++i)
		for(int j=1;j<=n;++j)
			st[i][j]=st[i-1][st[i-1][j]];
	{
		using namespace sp1;
		for(int i=1;i<=m;++i){
			pa[i]=gi(),pb[i]=gi(),pl[i]=LCA(pa[i],pb[i]);
			pja[i]=jump(pa[i],dep[pa[i]]-dep[pl[i]]-1);
			pjb[i]=jump(pb[i],dep[pb[i]]-dep[pl[i]]-1);
			if((pa[i]==pl[i]||pb[i]==pl[i])&&dist(pa[i],pb[i])>=K)ans-=1;
			vec[pa[i]].push_back(i),vec[pb[i]].push_back(i);
			vec2[pl[i]].push_back(i);
			if(dep[pa[i]]-dep[pl[i]]>=K)vec3[pA[i]=jump(pa[i],dep[pa[i]]-dep[pl[i]]-K)].push_back(i);
			if(dep[pb[i]]-dep[pl[i]]>=K)vec3[pB[i]=jump(pb[i],dep[pb[i]]-dep[pl[i]]-K)].push_back(i);
		}
		DFS(1);cnt=0;
	}
	for(int i=1;i<=n;++i)vec[i].clear();
	using namespace sp2;
	for(X=1;X<=n;++X){
		int m=0;
		for(int i:vec2[X])num[++m]=pa[i],num[++m]=pb[i],vec[pa[i]].push_back(i),vec[pb[i]].push_back(i);
		if(!m)continue;
		std::sort(num+1,num+m+1,[&](int a,int b){return dfn[a]<dfn[b];});
		for(int i=1;i<m;++i)num[i+m]=LCA(num[i],num[i+1]);
		m+=m-1;std::sort(num+1,num+m+1,[&](int a,int b){return dfn[a]<dfn[b];});
		m=std::unique(num+1,num+m+1)-num-1;
		static int stk[150010],tp;tp=0;
		for(int i=1;i<=m;++i){
			while(tp&&!isAnc(num[stk[tp]],num[i]))--tp;
			FA[i]=stk[tp];stk[++tp]=i;
			if(FA[i])G[FA[i]].push_back(i);
		}
		DFS(1);
		for(int i=1;i<=m;++i)G[i].clear(),set[i].clear(),rt[i]=0;
		cnt=0;
		for(int i:vec2[X])vec[pa[i]].clear(),vec[pb[i]].clear();
	}
	printf("%lld\n",ans>>1);
	return 0;
}
