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;
int dep[N], tp[N], dfn[N], size[N], son[N], fa[N], dfs_cnt, root[N], nid[N];
vector<int> e[N], te[N];
struct Chain {
  int u, v;
};
vector<Chain> c[N], tc[N];
int q[N], K, n, m;
long long ans;
struct BIT {
  int a[N];
  int query(int x) {
    int ans = 0;
    for (; x; x -= x & -x) ans += a[x];
    return ans;
  }
  void update(int x, int w) {
    for (; x <= n; x += x & -x) a[x] += w;
  }
} s1;
int s[N * 20], ch[N * 20][2], seg_node;
int lca(int u, int v) {
  for (; tp[u] != tp[v];
       dep[tp[u]] < dep[tp[v]] ? v = fa[tp[v]] : u = fa[tp[u]])
    ;
  return dep[u] < dep[v] ? u : v;
}
void dfs1(int u, int Fa) {
  dep[u] = dep[Fa] + 1, fa[u] = Fa, size[u] = 1;
  int mx = 0;
  for (vector<int>::iterator i = e[u].begin(); i != e[u].end(); i++) {
    int v = *i;
    if (v == Fa) continue;
    dfs1(v, u);
    size[u] += size[v];
    if (size[v] > mx) mx = size[v], son[u] = v;
  }
}
void dfs2(int u, int top) {
  tp[u] = top;
  dfn[u] = ++dfs_cnt, nid[dfs_cnt] = u;
  if (son[u]) dfs2(son[u], top);
  for (vector<int>::iterator i = e[u].begin(); i != e[u].end(); i++) {
    int v = *i;
    if (v == fa[u] || v == son[u]) continue;
    dfs2(v, v);
  }
}
int getkfa(int u, int k) {
  while (k >= dep[u] - dep[fa[tp[u]]])
    k -= dep[u] - dep[fa[tp[u]]], u = fa[tp[u]];
  return nid[dfn[u] - k];
}
void solve1(int u, int Fa) {
  for (vector<int>::iterator i = e[u].begin(); i != e[u].end(); i++) {
    int v = *i;
    if (v == Fa) continue;
    solve1(v, u);
  }
  for (vector<Chain>::iterator i = c[u].begin(); i != c[u].end(); i++) {
    int s = i->u, t = i->v;
    ans += s1.query(dfn[s]), ans += s1.query(dfn[t]);
  }
  for (vector<Chain>::iterator i = c[u].begin(); i != c[u].end(); i++) {
    int s = i->u, t = i->v;
    if (dep[s] - dep[u] >= K) {
      int l = getkfa(s, dep[s] - dep[u] - K);
      s1.update(dfn[l], 1), s1.update(dfn[l] + size[l], -1);
    }
    if (dep[t] - dep[u] >= K) {
      int l = getkfa(t, dep[t] - dep[u] - K);
      s1.update(dfn[l], 1), s1.update(dfn[l] + size[l], -1);
    }
  }
}
void ade(int u, int v) { te[u].push_back(v); }
int cmp(const Chain &a, const Chain &b) { return dfn[a.u] < dfn[b.u]; }
int build(vector<Chain> tmp) {
  sort(tmp.begin(), tmp.end(), cmp);
  int n = tmp.size();
  int top = 1;
  q[1] = tmp[0].u;
  tc[q[1]].clear();
  root[q[1]] = 0;
  te[q[1]].clear();
  for (int i = 1; i < n; i++) {
    if (tmp[i].u == tmp[i - 1].u) continue;
    int t = lca(q[top], tmp[i].u);
    while (top > 1 && dep[q[top - 1]] > dep[t]) ade(q[top - 1], q[top]), --top;
    if (dep[q[top]] > dep[t]) {
      ade(q[top], t);
      --top;
      if (q[top] != t) q[++top] = t;
      tc[t].clear();
      root[t] = 0;
      te[t].clear();
    }
    q[++top] = tmp[i].u;
    tc[tmp[i].u].clear();
    root[tmp[i].u] = 0;
    te[tmp[i].u].clear();
  }
  while (top > 1) ade(q[top - 1], q[top]), --top;
  return q[1];
}
int merge(int u, int v) {
  if (!u || !v) return u | v;
  s[u] += s[v];
  ch[u][0] = merge(ch[u][0], ch[v][0]), ch[u][1] = merge(ch[u][1], ch[v][1]);
  return u;
}
int newnode() {
  int u = ++seg_node;
  s[u] = ch[u][0] = ch[u][1] = 0;
  return u;
}
void update(int &rot, int lt, int rt, int q) {
  if (!rot) rot = newnode();
  ++s[rot];
  if (lt == rt) return;
  int mid = (lt + rt) >> 1;
  if (q <= mid)
    update(ch[rot][0], lt, mid, q);
  else
    update(ch[rot][1], mid + 1, rt, q);
}
int query(int rot, int lt, int rt, int lq, int rq) {
  if (!rot) return 0;
  if (lt >= lq && rt <= rq) return s[rot];
  int mid = (lt + rt) >> 1;
  if (rq <= mid) return query(ch[rot][0], lt, mid, lq, rq);
  if (lq > mid) return query(ch[rot][1], mid + 1, rt, lq, rq);
  return query(ch[rot][0], lt, mid, lq, mid) +
         query(ch[rot][1], mid + 1, rt, mid + 1, rq);
}
void dfs3(int u, int anc) {
  for (vector<int>::iterator i = te[u].begin(); i != te[u].end(); i++) {
    int v = *i;
    dfs3(v, anc);
    if (tc[u].size() < tc[v].size()) swap(tc[u], tc[v]), swap(root[u], root[v]);
    for (vector<Chain>::iterator j = tc[v].begin(); j != tc[v].end(); j++) {
      int s = j->u, t = j->v;
      if (dep[s] - dep[anc] >= K)
        ans += tc[u].size();
      else {
        int x = getkfa(t, dep[s] + dep[t] - 2 * dep[anc] - K);
        ans += query(root[u], 1, n, dfn[x], dfn[x] + size[x] - 1);
      }
    }
    for (vector<Chain>::iterator j = tc[v].begin(); j != tc[v].end(); j++)
      tc[u].push_back(*j);
    root[u] = merge(root[u], root[v]);
  }
}
void solve2() {
  for (int u = 1; u <= n; u++) {
    if (!c[u].size()) continue;
    seg_node = 0;
    int o = build(c[u]);
    for (vector<Chain>::iterator i = c[u].begin(); i != c[u].end(); i++) {
      if (dep[i->u] - dep[u] >= K)
        ans += tc[i->u].size();
      else {
        int t = getkfa(i->v, dep[i->u] + dep[i->v] - 2 * dep[u] - K);
        ans += query(root[i->u], 1, n, dfn[t], dfn[t] + size[t] - 1);
      }
      update(root[i->u], 1, n, dfn[i->v]);
      tc[i->u].push_back(*i);
    }
    dfs3(o, u);
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &K);
  for (int i = 1, u, v; i < n; i++)
    scanf("%d%d", &u, &v), e[u].push_back(v), e[v].push_back(u);
  dfs1(1, 0), dfs2(1, 1);
  for (int i = 1, u, v; i <= m; i++) {
    scanf("%d%d", &u, &v);
    if (dfn[u] > dfn[v]) swap(u, v);
    c[lca(u, v)].push_back((Chain){u, v});
  }
  solve1(1, 0);
  solve2();
  cout << ans << endl;
}
