#include <bits/stdc++.h>
using namespace std;
namespace IO {
const int Rlen = 1 << 22 | 1;
inline char gc() {
  static char buf[Rlen], *p1, *p2;
  (p1 == p2) && (p2 = (p1 = buf) + fread(buf, 1, Rlen, stdin));
  return p1 == p2 ? EOF : *p1++;
}
int read() {
  int x = 0;
  char c = gc();
  bool f = false;
  while (!isdigit(c)) f = c == '-', c = gc();
  while (isdigit(c)) x = (((x << 2) + x) << 1) + (c ^ 48), c = gc();
  return f ? -x : x;
}
}  // namespace IO
using namespace IO;
const int N = 6e5 + 50;
int n, m, k, lg[N];
vector<int> G[N];
int fa[N][20], dep[N], in[N], out[N], sgn, ps[N];
long long Ans;
void pre_dfs(int u, int f) {
  for (int i = 1; i <= lg[dep[u]]; i++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
  ps[in[u] = ++sgn] = u;
  for (int v : G[u])
    if (v ^ f) fa[v][0] = u, dep[v] = dep[u] + 1, pre_dfs(v, u);
  out[u] = sgn;
}
namespace BIT {
int c[N];
void add(int x, int v) {
  for (; x <= n; x += x & -x) c[x] += v;
}
int ask(int x) {
  int as = 0;
  for (; x; x -= x & -x) as += c[x];
  return as;
}
int qry(int l, int r) { return ask(r) - ask(l - 1); }
}  // namespace BIT
int jmp(int x, int d) {
  for (int i = lg[d]; ~i; i--)
    if (d >> i & 1) x = fa[x][i];
  return x;
}
int LCA(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  for (int i = lg[dep[x] - dep[y]]; ~i; i--)
    if (dep[fa[x][i]] >= dep[y]) x = fa[x][i];
  if (x == y) return x;
  for (int i = lg[dep[x]]; ~i; i--)
    if (fa[x][i] ^ fa[y][i]) x = fa[x][i], y = fa[y][i];
  return fa[x][0];
}
bool sub(int u, int v) { return in[u] <= in[v] && in[v] <= out[u]; }
namespace FSY {
vector<pair<int, int> > S[N];
void love(int u, int f) {
  for (auto c : S[u]) {
    if (dep[c.first] - dep[u] >= k) {
      int t = jmp(c.first, dep[c.first] - dep[u] - k);
      Ans += BIT::qry(in[t], out[t]);
    }
    if (dep[c.second] - dep[u] >= k) {
      int t = jmp(c.second, dep[c.second] - dep[u] - k);
      Ans += BIT::qry(in[t], out[t]);
    }
  }
  for (auto c : S[u]) BIT::add(in[c.first], 1), BIT::add(in[c.second], 1);
  for (int v : G[u])
    if (v ^ f) love(v, u);
  for (auto c : S[u]) BIT::add(in[c.first], -1), BIT::add(in[c.second], -1);
}
}  // namespace FSY
namespace SGT {
const int N = ::N * 20;
int nd, sz[N], lc[N], rc[N];
void clr() { nd = 0; }
int nwnd() {
  int x = ++nd;
  sz[x] = lc[x] = rc[x] = 0;
  return x;
}
void ins(int &x, int l, int r, int p) {
  if (!x) x = nwnd();
  ++sz[x];
  if (l == r) return;
  (p <= ((l + r) >> 1)) ? ins(lc[x], l, ((l + r) >> 1), p)
                        : ins(rc[x], ((l + r) >> 1) + 1, r, p);
}
void mrg(int &x, int y) {
  if (!x || !y) {
    x |= y;
    return;
  }
  sz[x] += sz[y];
  mrg(lc[x], lc[y]);
  mrg(rc[x], rc[y]);
}
int qry(int x, int l, int r, int L, int R) {
  if (!x) return 0;
  if (L <= l && r <= R) return sz[x];
  int as = 0;
  if (L <= ((l + r) >> 1)) as += qry(lc[x], l, ((l + r) >> 1), L, R);
  if (R > ((l + r) >> 1)) as += qry(rc[x], ((l + r) >> 1) + 1, r, L, R);
  return as;
}
}  // namespace SGT
namespace Yolanda {
vector<pair<int, int> > S[N];
set<int> A[N];
vector<int> mat[N];
int tmp[N], tr[N];
int lca, rt[N];
long long as;
void mrg(int u, int v) {
  if (u == lca) return;
  int x = u, y = v;
  if (SGT::sz[rt[u]] < SGT::sz[rt[v]]) swap(u, v);
  for (int t : A[v]) {
    if (dep[x] - dep[lca] >= k) {
      int o = tmp[t];
      Ans += SGT::qry(rt[u], 1, n, in[lca], out[lca]);
      if (tr[t] != lca) {
        int a = jmp(tr[t], dep[tr[t]] - dep[lca] - 1);
        Ans -= SGT::qry(rt[u], 1, n, in[a], out[a]);
      }
      if (o != lca) {
        int b = jmp(o, dep[o] - dep[lca] - 1);
        Ans -= SGT::qry(rt[u], 1, n, in[b], out[b]);
      }
    }
    if (x != lca) {
      int res = max(1, k - (dep[x] - dep[lca])), o = tmp[t];
      if (dep[o] - dep[lca] >= res) {
        int a = jmp(o, dep[o] - dep[lca] - res);
        as += SGT::qry(rt[u], 1, n, in[a], out[a]);
      }
    }
  }
  if (A[x].size() < A[y].size()) swap(A[x], A[y]);
  for (int t : A[y]) A[x].insert(t);
  SGT::mrg(rt[x], rt[y]);
}
void work() {
  if (S[lca].size() <= 1) return;
  static int a[N];
  int num = 0;
  int idx = n;
  for (auto c : S[lca]) {
    a[++num] = c.first, a[++num] = c.second;
    ++idx;
    mat[c.first].push_back(idx);
    tmp[idx] = c.second;
    tr[idx] = c.first;
    ++idx;
    mat[c.second].push_back(idx);
    tmp[idx] = c.first;
    tr[idx] = c.second;
  }
  sort(a + 1, a + num + 1,
       [](const int &i, const int &j) { return in[i] < in[j]; });
  for (int i = 1, nx = num; i < nx; i++) a[++num] = LCA(a[i], a[i + 1]);
  sort(a + 1, a + num + 1,
       [](const int &i, const int &j) { return in[i] < in[j]; });
  num = unique(a + 1, a + num + 1) - (a + 1);
  SGT::clr();
  as = 0;
  static int sta[N];
  int top = 0;
  for (int i = 1; i <= num; i++) {
    int u = a[i];
    while (top > 1 && !sub(sta[top], u)) {
      mrg(sta[top - 1], sta[top]);
      --top;
    }
    sta[++top] = u;
    for (int v : mat[u]) {
      SGT::ins(rt[v], 1, n, in[tmp[v]]), A[v].insert(v);
      mrg(u, v);
    }
  }
  while (top > 1) mrg(sta[top - 1], sta[top]), --top;
  Ans += (as >> 1);
  for (int i = 1; i <= num; i++)
    rt[a[i]] = 0, mat[a[i]].clear(), A[a[i]].clear();
  for (int i = n + 1; i <= idx; i++) rt[i] = 0;
}
void forever() {
  for (int i = 1; i <= n; i++) tr[i] = i;
  for (int i = 1; i <= n; i++) lca = i, work();
}
}  // namespace Yolanda
int main() {
  n = read(), m = read(), k = read();
  for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
  for (int i = 1, x, y; i < n; i++)
    x = read(), y = read(), G[x].push_back(y), G[y].push_back(x);
  dep[1] = 1;
  pre_dfs(1, 0);
  for (int i = 1, u, v, l; i <= m; i++) {
    u = read(), v = read(), l = LCA(u, v);
    if (dep[u] + dep[v] - 2 * dep[l] < k) continue;
    FSY::S[l].push_back(pair<int, int>(u, v));
    Yolanda ::S[l].push_back(pair<int, int>(u, v));
  }
  FSY ::love(1, 0);
  Yolanda ::forever();
  cout << Ans;
  return 0;
}
