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>
using namespace std;
const int N = 2e5 + 7, M = 20, K = 1e7 + 7;
long long ans, sum;
vector<int> v[N], qt[N], vw[N], vt[N];
int n, m, k, kt, rt, opt, tot, fa[N], ft[N], dep[N], siz[N], rq[N], dfa[N],
    dfb[N], res[N], e[N][M], pt[N << 1], gt[N], ch[K][2], va[K];
struct query {
  int u, v, t;
} f[N];
inline void dfs(int u) {
  e[u][0] = fa[u], dfa[u] = dfb[u] = ++opt, ft[opt] = u;
  for (int i = 1; i <= 18; i++) e[u][i] = e[e[u][i - 1]][i - 1];
  for (int i = 0; i < v[u].size(); i++) {
    int x = v[u][i];
    if (fa[u] == x) continue;
    fa[x] = u, dep[x] = dep[u] + 1, dfs(x), dfb[u] = dfb[x];
  }
}
inline int lca(int u, int t) {
  if (dep[u] < dep[t]) swap(u, t);
  int z = dep[u] - dep[t];
  for (int i = 18; i >= 0; i--)
    if ((1 << i) & z) u = e[u][i];
  if (u == t) return u;
  for (int i = 18; i >= 0; i--)
    if (e[u][i] != e[t][i]) u = e[u][i], t = e[t][i];
  return fa[u];
}
inline int jmp(int u, int t) {
  for (int i = 18; i >= 0; i--)
    if ((1 << i) & t) u = e[u][i];
  return u;
}
inline int lowbit(int u) { return (u & (-u)); }
inline void adds(int u, int c) {
  while (u <= n) res[u] += c, u += lowbit(u);
}
inline int getsum(int u) {
  int ans = 0;
  while (u > 0) ans += res[u], u -= lowbit(u);
  return ans;
}
inline bool cmp(query a, query b) { return dfa[a.t] < dfa[b.t]; }
inline bool tmp(int a, int b) { return dfa[a] < dfa[b]; }
inline int merge(int u, int t, int l, int r) {
  if (!u || !t) return (u + t);
  if (l == r) {
    va[u] += va[t];
    return u;
  }
  int d = (l + r) >> 1;
  ch[u][0] = merge(ch[u][0], ch[t][0], l, d);
  ch[u][1] = merge(ch[u][1], ch[t][1], d + 1, r);
  va[u] = va[ch[u][0]] + va[ch[u][1]];
  return u;
}
inline int getans(int l, int r, int t, int ql, int qr) {
  if (l == ql && r == qr) return va[t];
  int d = (l + r) >> 1;
  int sum = 0;
  if (ql <= d && ch[t][0]) sum += getans(l, d, ch[t][0], ql, min(d, qr));
  if (d + 1 <= qr && ch[t][1])
    sum += getans(d + 1, r, ch[t][1], max(d + 1, ql), qr);
  return sum;
}
inline void getval(int u, int t, int l, int r) {
  if (l == r) {
    int z = u;
    u = ft[l];
    if (dep[u] - dep[rt] >= kt) {
      u = jmp(u, dep[u] - dep[rt] - kt);
      sum = sum + 1ll * getans(1, n, t, dfa[u], dfb[u]) * va[z];
    }
    return;
  }
  int d = (l + r) >> 1;
  if (ch[u][0]) getval(ch[u][0], t, l, d);
  if (ch[u][1]) getval(ch[u][1], t, d + 1, r);
}
inline void addx(int l, int r, int t, int s) {
  if (l == r) {
    va[t]++;
    return;
  }
  int d = (l + r) >> 1;
  if (s <= d) {
    if (!ch[t][0]) ch[t][0] = ++tot;
    addx(l, d, ch[t][0], s);
  } else {
    if (!ch[t][1]) ch[t][1] = ++tot;
    addx(d + 1, r, ch[t][1], s);
  }
  va[t] = va[ch[t][0]] + va[ch[t][1]];
}
inline void dft(int u) {
  rq[u] = 0;
  for (int i = 0; i < vw[u].size(); i++) {
    int x = vw[u][i];
    dft(x);
    kt = max(k - (dep[u] - dep[rt]), 0);
    if (siz[x] > siz[u]) swap(siz[u], siz[x]), swap(rq[u], rq[x]);
    getval(rq[x], rq[u], 1, n), rq[u] = merge(rq[u], rq[x], 1, n),
                                siz[u] += siz[x];
  }
  kt = max(k - (dep[u] - dep[rt]), 0);
  for (int i = 0; i < vt[u].size(); i++) {
    int x = vt[u][i];
    if (dep[x] - dep[rt] >= kt) {
      int z = jmp(x, dep[x] - dep[rt] - kt);
      sum = sum + getans(1, n, rq[u], dfa[z], dfb[z]);
    }
    if (!rq[u]) rq[u] = ++tot;
    addx(1, n, rq[u], dfa[x]), siz[u]++;
  }
}
int main() {
  cin >> n >> m >> k;
  int u, t;
  for (int i = 1; i < n; i++)
    scanf("%d%d", &u, &t), v[u].push_back(t), v[t].push_back(u);
  dfs(1);
  for (int i = 1; i <= m; i++)
    scanf("%d%d", &f[i].u, &f[i].v), f[i].t = lca(f[i].u, f[i].v);
  sort(f + 1, f + m + 1, cmp);
  for (int i = 1; i <= m; i++) {
    int l = 1, r = m, pos = 0;
    while (l <= r) {
      int d = (l + r) >> 1;
      if (dfa[f[d].t] < dfa[f[i].t])
        pos = d, l = d + 1;
      else
        r = d - 1;
    }
    qt[pos].push_back(i);
    l = 1, r = m, pos = 0;
    while (l <= r) {
      int d = (l + r) >> 1;
      if (dfa[f[d].t] <= dfb[f[i].t])
        pos = d, l = d + 1;
      else
        r = d - 1;
    }
    qt[pos].push_back(i);
  }
  for (int i = 1; i <= m; i++) {
    adds(dfa[f[i].u], 1), adds(dfa[f[i].v], 1);
    for (int x = 0; x < qt[i].size(); x++) {
      int c = qt[i][x];
      if (dfa[f[i].t] < dfa[f[c].t]) {
        if (dep[f[c].u] - dep[f[c].t] >= k) {
          int z = jmp(f[c].u, dep[f[c].u] - dep[f[c].t] - k);
          ans = ans + (getsum(dfb[z]) - getsum(dfa[z] - 1));
        }
        if (dep[f[c].v] - dep[f[c].t] >= k) {
          int z = jmp(f[c].v, dep[f[c].v] - dep[f[c].t] - k);
          ans = ans + (getsum(dfb[z]) - getsum(dfa[z] - 1));
        }
      } else {
        if (dep[f[c].u] - dep[f[c].t] >= k) {
          int z = jmp(f[c].u, dep[f[c].u] - dep[f[c].t] - k);
          ans = ans - (getsum(dfb[z]) - getsum(dfa[z] - 1));
        }
        if (dep[f[c].v] - dep[f[c].t] >= k) {
          int z = jmp(f[c].v, dep[f[c].v] - dep[f[c].t] - k);
          ans = ans - (getsum(dfb[z]) - getsum(dfa[z] - 1));
        }
      }
    }
  }
  for (int c = 1; c <= m; c++) {
    if (dep[f[c].u] - dep[f[c].t] >= k) {
      int z = jmp(f[c].u, dep[f[c].u] - dep[f[c].t] - k);
      ans = ans + (getsum(dfb[z]) - getsum(dfa[z] - 1));
    }
    if (dep[f[c].v] - dep[f[c].t] >= k) {
      int z = jmp(f[c].v, dep[f[c].v] - dep[f[c].t] - k);
      ans = ans + (getsum(dfb[z]) - getsum(dfa[z] - 1));
    }
  }
  for (int i = 1; i <= m; i++) {
    int x = i;
    while (f[i].t == f[x + 1].t) x++;
    pt[pt[0] = 1] = f[i].t;
    for (int z = i; z <= x; z++) pt[++pt[0]] = f[z].u, pt[++pt[0]] = f[z].v;
    sort(pt + 1, pt + pt[0] + 1, tmp);
    for (int z = 1; z <= pt[0]; z++) vw[pt[z]].resize(0), vt[pt[z]].resize(0);
    int len = 0;
    for (int z = i; z <= x; z++)
      vt[f[z].u].push_back(f[z].v), vt[f[z].v].push_back(f[z].u);
    gt[len = 1] = pt[1];
    for (int z = 2; z <= pt[0]; z++) {
      if (pt[z] == gt[len]) continue;
      if (len == 1) {
        gt[++len] = pt[z];
        continue;
      }
      int c = lca(pt[z], gt[len]);
      while (dep[c] < dep[gt[len]]) {
        if (dep[gt[len - 1]] >= dep[c]) {
          vw[gt[len - 1]].push_back(gt[len]);
          len--;
        } else {
          vw[c].resize(0);
          vt[c].resize(0);
          vw[c].push_back(gt[len]);
          gt[len] = c;
          break;
        }
      }
      if (pt[z] == gt[len]) continue;
      gt[++len] = pt[z];
    }
    for (int z = 1; z < len; z++) vw[gt[z]].push_back(gt[z + 1]);
    rt = f[i].t, dft(rt);
    i = x;
  }
  cout << ans + sum / 2 << endl;
  return 0;
}
