#include <bits/stdc++.h>   using namespace std;   inline void read(int &x) {     int v = 0, f = 1;     char c = getchar();     while (!isdigit(c) && c !=  - ) c = getchar();     if (c ==  - )       f = -1;     else       v = (c & 15);     while (isdigit(c = getchar())) v = (v << 1) + (v << 3) + (c & 15);     x = v * f;   }   inline void read(long long &x) {     long long v = 0ll, f = 1ll;     char c = getchar();     while (!isdigit(c) && c !=  - ) c = getchar();     if (c ==  - )       f = -1;     else       v = (c & 15);     while (isdigit(c = getchar())) v = (v << 1) + (v << 3) + (c & 15);     x = v * f;   }   inline void readc(char &x) {     char c;     while (((c = getchar()) ==    ) || c ==   n )       ;     x = c;   }   long long ans;   int n, m, k, i, j, fa[150005][19], dep[150005], first[150005], ed[150005], ti,       px[150005], py[150005];   int tt, lst[150005], stk[150005], tp;   vector<int> ne[150005];   vector<int> e[150005];   vector<int> v[150005];   vector<int> add[150005];   void addedg(int x, int y) {     if (lst[x] != tt) {       lst[x] = tt;       ne[x].clear();     }     if (lst[y] != tt) {       lst[y] = tt;       ne[y].clear();     }     ne[x].push_back(y);   }   bool cmp(int x, int y) { return first[x] < first[y]; }   void dfs1(int x, int p) {     fa[x][0] = p;     first[x] = ++ti;     for (__typeof((e[x]).begin()) it = (e[x]).begin(); it != (e[x]).end(); it++)       if (*it != p) {         dep[*it] = dep[x] + 1;         dfs1(*it, x);       }     ed[x] = ti;   }   int lca(int x, int y) {     if (dep[x] < dep[y]) swap(x, y);     int t = dep[x] - dep[y], i;     for ((i) = (18); (i) >= (0); (i)--)       if ((t >> i) & 1) x = fa[x][i];     if (x == y) return x;     for ((i) = (18); (i) >= (0); (i)--)       if (fa[x][i] != fa[y][i]) {         x = fa[x][i];         y = fa[y][i];       }     return fa[x][0];   }   int gtf(int x, int y) {     int i;     for ((i) = (18); (i) >= (0); (i)--)       if ((y >> i) & 1) x = fa[x][i];     return x;   }   struct bit {     int c[150005];     void add(int x, int y) {       while (x <= n) {         c[x] += y;         x += (x & -x);       }     }     int query(int x) {       int s = 0;       while (x) {         s += c[x];         x -= (x & -x);       }       return s;     }   } tr;   void dfs2(int x) {     for (__typeof((v[x]).begin()) it = (v[x]).begin(); it != (v[x]).end(); it++) {       if (dep[px[*it]] - dep[x] >= k) {         int t = gtf(px[*it], dep[px[*it]] - dep[x] - k);         ans += tr.query(ed[t]) - tr.query(first[t] - 1);       }       if (dep[py[*it]] - dep[x] >= k) {         int t = gtf(py[*it], dep[py[*it]] - dep[x] - k);         ans += tr.query(ed[t]) - tr.query(first[t] - 1);       }     }     for (__typeof((v[x]).begin()) it = (v[x]).begin(); it != (v[x]).end(); it++) {       tr.add(first[px[*it]], 1);       tr.add(first[py[*it]], 1);     }     for (__typeof((e[x]).begin()) it = (e[x]).begin(); it != (e[x]).end(); it++)       if (*it != fa[x][0]) {         dfs2(*it);       }     for (__typeof((v[x]).begin()) it = (v[x]).begin(); it != (v[x]).end(); it++) {       tr.add(first[px[*it]], -1);       tr.add(first[py[*it]], -1);     }   }   void ins(int x) {     if (x == 1) return;     int z = lca(x, stk[tp]);     if (z == stk[tp]) {       stk[++tp] = x;       return;     }     while (tp > 1 && first[stk[tp - 1]] >= first[z]) {       addedg(stk[tp - 1], stk[tp]);       tp--;     }     if (stk[tp] != z) {       addedg(z, stk[tp]);       stk[tp] = z;     }     stk[++tp] = x;   }   multiset<int> s[150005];   int rt[150005], tot, lc[3000005], rc[3000005], sum[3000005];   void update(int &x, int l, int r, int y) {     if (!x) {       x = ++tot;       lc[x] = rc[x] = sum[x] = 0;     }     sum[x]++;     if (l == r) return;     int mid = (l + r) / 2;     if (y <= mid)       update(lc[x], l, mid, y);     else       update(rc[x], mid + 1, r, y);   }   void merge(int &x, int y, int l, int r) {     if (!x || !y) {       x = x + y;       return;     }     if (l == r) {       sum[x] += sum[y];       return;     }     int mid = (l + r) / 2;     merge(lc[x], lc[y], l, mid);     merge(rc[x], rc[y], mid + 1, r);     sum[x] = sum[lc[x]] + sum[rc[x]];   }   int query(int x, int l, int r, int ql, int qr) {     if (!x) return 0;     if (ql <= l && r <= qr) return sum[x];     int mid = (l + r) / 2, s = 0;     if (ql <= mid) s += query(lc[x], l, mid, ql, qr);     if (qr > mid) s += query(rc[x], mid + 1, r, ql, qr);     return s;   }   void dfs3(int x) {     if (dep[x] - dep[i] >= k) {       int t = gtf(x, dep[x] - dep[i] - k);       ans += 1ll * add[x].size() * (tr.query(ed[t]) - tr.query(first[t] - 1));     }     for (__typeof((add[x]).begin()) it = (add[x]).begin(); it != (add[x]).end();          it++) {       tr.add(first[*it], 1);     }     rt[x] = 0;     s[x].clear();     for (__typeof((add[x]).begin()) it = (add[x]).begin(); it != (add[x]).end();          it++) {       s[x].insert(*it);       if (dep[x] - dep[i] >= k) {         int t = gtf(x, k - 1);         if (first[t] > 1) ans += query(rt[x], 1, n, 1, first[t] - 1);         if (ed[t] < n) ans += query(rt[x], 1, n, ed[t] + 1, n);       } else {         if (dep[x] - dep[i] + dep[*it] - dep[i] < k) continue;         int t = gtf(*it, dep[*it] - dep[i] - (k - (dep[x] - dep[i])));         ans += query(rt[x], 1, n, first[t], ed[t]);       }       update(rt[x], 1, n, first[*it]);     }     for (__typeof((ne[x]).begin()) it = (ne[x]).begin(); it != (ne[x]).end();          it++) {       dfs3(*it);       if (s[x].size() < s[*it].size()) {         swap(s[x], s[*it]);         swap(rt[x], rt[*it]);       }       for (__typeof((s[*it]).begin()) it2 = (s[*it]).begin();            it2 != (s[*it]).end(); it2++) {         if (dep[x] - dep[i] >= k) {           int t = gtf(x, k - 1);           if (first[t] > 1) ans += query(rt[x], 1, n, 1, first[t] - 1);           if (ed[t] < n) ans += query(rt[x], 1, n, ed[t] + 1, n);         } else {           if (dep[x] - dep[i] + dep[*it2] - dep[i] < k) continue;           int t = gtf(*it2, dep[*it2] - dep[i] - (k - (dep[x] - dep[i])));           ans += query(rt[x], 1, n, first[t], ed[t]);         }         s[x].insert(*it2);       }       merge(rt[x], rt[*it], 1, n);     }   }   int main() {     read(n);     read(m);     read(k);     for (((i)) = (1); ((i)) <= ((n - 1)); ((i))++) {       int x, y;       read(x);       read(y);       e[x].push_back(y);       e[y].push_back(x);     }     dfs1(1, 0);     for (((j)) = (1); ((j)) <= ((18)); ((j))++)       for (((i)) = (1); ((i)) <= ((n)); ((i))++)         fa[i][j] = fa[fa[i][j - 1]][j - 1];     for (((i)) = (1); ((i)) <= ((m)); ((i))++) {       read(px[i]);       read(py[i]);       if (first[px[i]] > first[py[i]]) swap(px[i], py[i]);       v[lca(px[i], py[i])].push_back(i);     }     dfs2(1);     for (((i)) = (1); ((i)) <= ((n)); ((i))++) {       for (__typeof((v[i]).begin()) it = (v[i]).begin(); it != (v[i]).end();            it++) {         add[px[*it]].push_back(py[*it]);       }       vector<int> a;       for (__typeof((v[i]).begin()) it = (v[i]).begin(); it != (v[i]).end();            it++) {         a.push_back(px[*it]);         a.push_back(py[*it]);       }       a.push_back(1);       sort((a).begin(), (a).end(), cmp);       a.resize(unique((a).begin(), (a).end()) - a.begin());       tt++;       ne[1].clear();       stk[tp = 1] = 1;       for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++) {         ins(*it);       }       while (tp > 1) {         addedg(stk[tp - 1], stk[tp]);         tp--;       }       tot = 0;       dfs3(1);       for (__typeof((v[i]).begin()) it = (v[i]).begin(); it != (v[i]).end();            it++) {         add[px[*it]].clear();       }       for (__typeof((v[i]).begin()) it = (v[i]).begin(); it != (v[i]).end();            it++) {         tr.add(first[py[*it]], -1);       }     }     cout << ans << endl;     return 0;   }