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;
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;
}
