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;
int n, m, K;
long long ans;
int info[150006], Prev[150006 << 1], to[150006 << 1], cnt_e;
void Node(int u, int v) {
  Prev[++cnt_e] = info[u], info[u] = cnt_e, to[cnt_e] = v;
}
int sx[150006], ty[150006], ds[150006];
vector<int> G[150006];
int f[18][150006], tf[150006 << 4], *fl[150006], dep[150006], st[150006],
    ed[150006], tot;
int len[150006], son[150006], tp[150006], lg[150006];
void dfs0(int u, int ff) {
  dep[u] = dep[f[0][u] = ff] + 1;
  st[u] = ++tot;
  for (int i = info[u], v; i; i = Prev[i])
    if ((v = to[i]) ^ ff) dfs0(v, u), (len[son[u]] < len[v]) && (son[u] = v);
  len[u] = len[son[u]] + 1;
  ed[u] = tot;
}
void dfs1(int u, int ff) {
  if (son[u]) {
    fl[son[u]] = fl[u] + 1;
    tp[son[u]] = tp[u];
    dfs1(son[u], u);
  }
  for (int i = info[u], v; i; i = Prev[i])
    if ((v = to[i]) ^ ff && v != son[u]) {
      fl[v] = fl[0] + len[v], fl[0] += len[v] * 2;
      dfs1(tp[v] = v, u);
    }
  if (tp[u] == u) {
    for (int i = 0, v = u; v; i++, v = son[v]) *(fl[u] + i) = v;
    for (int i = -1, v = f[0][u]; v && abs(i) <= len[u]; i--, v = f[0][v])
      *(fl[u] + i) = v;
  }
}
int Lca(int u, int v) {
  if (dep[u] > dep[v]) swap(u, v);
  for (int i = 0; dep[u] ^ dep[v]; i++)
    if (dep[v] - dep[u] >> i & 1) v = f[i][v];
  if (u == v) return u;
  for (int i = 18 - 1; i >= 0; i--)
    if (f[i][u] ^ f[i][v]) u = f[i][u], v = f[i][v];
  return f[0][u];
}
int kthf(int u, int k) {
  if (k == 0) return u;
  int t = lg[k];
  u = f[t][u];
  return *(fl[u] - k + (1 << t));
}
int tr[150006];
void upd(int u, int v) {
  for (; u <= n; u += u & -u) tr[u] += v;
}
int qry(int u) {
  int r = 0;
  for (; u; u -= u & -u) r += tr[u];
  return r;
}
void dfs2(int u, int ff) {
  for (int i = (0), LIM = (G[u].size() - 1); i <= LIM; i++) {
    int v = G[u][i];
    if (dep[sx[v]] - dep[u] >= K) {
      int t = kthf(sx[v], dep[sx[v]] - dep[u] - K);
      ans += qry(ed[t]) - qry(st[t] - 1);
    }
    if (dep[ty[v]] - dep[u] >= K) {
      int t = kthf(ty[v], dep[ty[v]] - dep[u] - K);
      ans += qry(ed[t]) - qry(st[t] - 1);
    }
  }
  for (int i = (0), LIM = (G[u].size() - 1); i <= LIM; i++) {
    int v = G[u][i];
    upd(st[sx[v]], 1);
    upd(st[ty[v]], 1);
  }
  for (int i = info[u], v; i; i = Prev[i])
    if ((v = to[i]) ^ ff) dfs2(v, u);
  for (int i = (0), LIM = (G[u].size() - 1); i <= LIM; i++) {
    int v = G[u][i];
    upd(st[sx[v]], -1);
    upd(st[ty[v]], -1);
  }
}
int fir[150006], nxt[150006 << 1], tar[150006 << 1], cnte;
void add(int u, int v) { nxt[++cnte] = fir[u], fir[u] = cnte, tar[cnte] = v; }
bool cmp(const int &u, const int &v) { return st[u] < st[v]; }
vector<int> P[150006];
vector<int> op[150006];
int rt[150006], lc[150006 * 30], rc[150006 * 30], sz[150006 * 30];
void merge(int &u, int l, int r) {
  if (!l || !r) return (void)(u = l + r);
  u = ++tot;
  lc[u] = rc[u] = 0;
  sz[u] = sz[l] + sz[r];
  merge(lc[u], lc[l], lc[r]), merge(rc[u], rc[l], rc[r]);
}
int qry(int u, int l, int r, int ql, int qr) {
  if (!u || ql > r || l > qr) return 0;
  if (ql <= l && r <= qr) return sz[u];
  int m = l + r >> 1;
  return qry(lc[u], l, m, ql, qr) + qry(rc[u], m + 1, r, ql, qr);
}
void ins(int &u, int l, int r, int p) {
  if (!u) u = ++tot, lc[u] = rc[u] = sz[u] = 0;
  sz[u]++;
  if (l == r) return;
  int m = l + r >> 1;
  p <= m ? ins(lc[u], l, m, p) : ins(rc[u], m + 1, r, p);
}
void dfs3(int u, int ff) {
  for (int i = (0), LIM = (op[u].size() - 1); i <= LIM; i++) {
    int v = kthf(ty[op[u][i]], ds[op[u][i]] - K);
    if (!v) v = 1;
    ans += qry(rt[u], 1, n, st[v], ed[v]);
    ins(rt[u], 1, n, st[ty[op[u][i]]]);
    P[u].push_back(op[u][i]);
  }
  for (int i = fir[u], v; i; i = nxt[i])
    if ((v = tar[i]) ^ ff) {
      dfs3(v, u);
      if (P[u].size() < P[v].size()) P[u].swap(P[v]), swap(rt[u], rt[v]);
      for (int j = (0), LIM = (P[v].size() - 1); j <= LIM; j++)
        if (dep[sx[P[v][j]]] - dep[u] + K <= ds[P[v][j]]) {
          P[u].push_back(P[v][j]);
          int t =
              kthf(ty[P[v][j]], ds[P[v][j]] - (dep[sx[P[v][j]]] - dep[u] + K));
          if (!t) t = 1;
          ans += qry(rt[u], 1, n, st[t], ed[t]);
        }
      merge(rt[u], rt[u], rt[v]);
    }
}
bool cmp1(const int &u, const int &v) { return st[sx[u]] < st[sx[v]]; }
int main() {
  fl[0] = tf;
  scanf("%d%d%d", &n, &m, &K);
  for (int i = (1), LIM = (n - 1); i <= LIM; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    Node(u, v), Node(v, u);
  }
  dfs0(1, 0);
  for (int j = (1), LIM = (18 - 1); j <= LIM; j++)
    for (int i = (1), LIM = (n); i <= LIM; i++) f[j][i] = f[j - 1][f[j - 1][i]];
  for (int i = (2), LIM = (n); i <= LIM; i++) lg[i] = lg[i >> 1] + 1;
  fl[1] = fl[0] + len[1], fl[0] += 2 * len[1];
  dfs1(tp[1] = 1, 0);
  for (int i = (1), LIM = (m); i <= LIM; i++) {
    scanf("%d%d", &sx[i], &ty[i]);
    int t = Lca(sx[i], ty[i]);
    ds[i] = dep[sx[i]] + dep[ty[i]] - 2 * dep[t];
    if (st[sx[i]] > st[ty[i]]) swap(sx[i], ty[i]);
    if (ds[i] >= K) G[t].push_back(i);
  }
  dfs2(1, 0);
  tot = 0;
  for (int i = (1), LIM = (n); i <= LIM; i++) {
    static int st[150006], ar[150006], tp, pt[150006];
    pt[0] = 0;
    for (int j = (0), LIM = (G[i].size() - 1); j <= LIM; j++)
      op[sx[G[i][j]]].push_back(G[i][j]), ar[j] = sx[G[i][j]];
    sort(ar, ar + G[i].size(), cmp);
    int L = unique(ar, ar + G[i].size()) - ar - 1;
    for (int j = (0), LIM = (L); j <= LIM; j++) {
      if (tp) {
        int t = Lca(st[tp], ar[j]), p = 0;
        for (; tp && dep[st[tp]] > dep[t]; p = st[tp--])
          if (p) add(st[tp], p);
        if (st[tp] ^ t) st[++tp] = pt[++pt[0]] = t;
        if (p) add(st[tp], p);
      }
      st[++tp] = pt[++pt[0]] = ar[j];
    }
    for (int p = 0; tp; p = st[tp--])
      if (p) add(st[tp], p);
    dfs3(st[1], 0);
    cnte = tot = 0;
    for (int j = (1), LIM = (pt[0]); j <= LIM; j++)
      P[pt[j]].clear(), op[pt[j]].clear(), fir[pt[j]] = rt[pt[j]] = 0;
    for (int j = (1), LIM = (tot); j <= LIM; j++) lc[j] = rc[j] = sz[j] = 0;
    P[0].clear();
  }
  for (int i = (1), LIM = (n); i <= LIM; i++) {
    sort(G[i].begin(), G[i].end(), cmp1);
    for (int j = (0), LIM = (G[i].size() - 1); j <= LIM; j++) {
      int v = G[i][j];
      if (dep[sx[v]] - dep[i] >= K) {
        int t = kthf(sx[v], dep[sx[v]] - dep[i] - K);
        ans += qry(ed[t]) - qry(st[t] - 1);
      }
      upd(st[ty[v]], 1);
    }
    for (int j = (0), LIM = (G[i].size() - 1); j <= LIM; j++)
      upd(st[ty[G[i][j]]], -1);
  }
  printf("%lld\n", ans);
}
