#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1, c = getchar();
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 1) + (x << 3) + (c ^ 48);
    c = getchar();
  }
  return f == 1 ? x : -x;
}
const int N = 2e5 + 4;
int n, Q, k, dfn[N];
long long ans, ans2;
namespace vars {
int tim, siz[N], fa[N], dep[N], son[N], top[N], idx[N];
}
namespace sz {
using namespace vars;
int t[N];
inline void clear() { memset(t, 0, sizeof(t)); }
inline void add(int x, int v) {
  for (; x <= n; x += x & -x) t[x] += v;
}
inline int ask(int x) {
  int ret = 0;
  for (; x; x -= x & -x) ret += t[x];
  return ret;
}
inline void additv(int x, int v) {
  add(dfn[x], v);
  add(dfn[x] + siz[x], -v);
}
inline int askitv(int x) { return ask(dfn[x] + siz[x] - 1) - ask(dfn[x] - 1); }
}  // namespace sz
namespace slpf {
inline int jpk(int x, int y, int lca);
}
namespace vt {
vector<int> e[N], vec[N];
int rt, siz[N], son[N];
void dfs_5(int x) {
  siz[x] = vec[x].size();
  son[x] = 0;
  for (auto v : e[x]) {
    dfs_5(v);
    siz[x] += siz[v];
    if (siz[v] > siz[son[x]]) son[x] = v;
  }
}
inline void calc_7(int x, int fl, int anc) {
  int qwq;
  for (auto v : vec[x]) {
    qwq = slpf::jpk(anc, v, rt);
    if (qwq != -1) ans += fl * sz::askitv(qwq);
  }
}
void dfs_7(int x, int fl, int anc) {
  calc_7(x, fl, anc);
  for (auto v : e[x]) dfs_7(v, fl, anc);
}
inline void calc_8(int x, int fl) {
  for (auto v : vec[x]) {
    sz::add(dfn[v], fl);
  }
}
void dfs_8(int x, int fl) {
  calc_8(x, fl);
  for (auto v : e[x]) dfs_8(v, fl);
}
void dfs_6(int x, int fl) {
  for (auto v : e[x])
    if (v != son[x]) dfs_6(v, 0);
  calc_7(x, -1, x);
  for (auto v : e[x])
    if (v != son[x]) dfs_7(v, -1, x);
  if (son[x]) dfs_6(son[x], 1);
  if (x == rt) {
    if (son[x]) dfs_8(son[x], -1);
    return;
  }
  int qwq;
  for (auto v : vec[x]) {
    qwq = slpf::jpk(x, v, rt);
    if (qwq != -1) ans += sz::askitv(qwq);
    sz::add(dfn[v], 1);
  }
  for (auto v : e[x])
    if (v != son[x]) {
      dfs_7(v, 1, x);
      dfs_8(v, 1);
    }
  if (!fl) dfs_8(x, -1);
}
void dfs_9(int x) {
  for (auto v : e[x]) dfs_9(v);
  e[x].clear();
  vec[x].clear();
}
inline void solve() {
  dfs_5(rt);
  dfs_6(rt, 0);
  dfs_9(rt);
}
}  // namespace vt
namespace slpf {
using namespace vars;
vector<int> e[N];
vector<pair<int, int> > vec[N];
void dfs_1(int x) {
  siz[x] = 1;
  for (auto v : e[x])
    if (v != fa[x]) {
      fa[v] = x;
      dep[v] = dep[x] + 1;
      dfs_1(v);
      siz[x] += siz[v];
      if (siz[v] > siz[son[x]]) son[x] = v;
    }
}
void dfs_2(int x, int tp) {
  top[x] = tp;
  idx[dfn[x] = ++tim] = x;
  if (son[x]) dfs_2(son[x], tp);
  for (auto v : e[x])
    if (v != fa[x] && v != son[x]) dfs_2(v, v);
}
inline int jump(int x, int k) {
  if (k < 0) return -1;
  if (k >= dep[x]) return 1;
  while (dep[x] - dep[top[x]] < k) {
    k -= dep[x] - dep[top[x]] + 1;
    x = fa[top[x]];
  }
  return idx[dfn[x] - k];
}
inline int jpk(int x, int y, int lca) {
  if (dep[x] - dep[lca] >= k) return jump(y, dep[y] - dep[lca] - 1);
  return jump(y, dep[x] + dep[y] - dep[lca] * 2 - k);
}
inline int getlca(int x, int y) {
  while (top[x] != top[y]) {
    if (dep[top[x]] > dep[top[y]])
      x = fa[top[x]];
    else
      y = fa[top[y]];
  }
  return dep[x] < dep[y] ? x : y;
}
struct QWQ {
  int u, v, au, av;
  QWQ() {}
  QWQ(int x, int y, int z, int w) : u(x), v(y), au(z), av(w) {}
} qwq[N];
inline bool comp_qwq(const QWQ &a, const QWQ &b) {
  return a.au < b.au || (a.au == b.au && a.av < b.av);
}
void dfs_3(int x) {
  for (auto v : vec[x]) ans -= sz::ask(dfn[v.first]) + sz::ask(dfn[v.second]);
  for (auto v : e[x])
    if (v != fa[x]) dfs_3(v);
  int cqwq = 0;
  for (auto v : vec[x]) {
    ++cqwq;
    qwq[cqwq] =
        QWQ(v.first, v.second,
            v.first == x ? -cqwq : jump(v.first, dep[v.first] - dep[x] - 1),
            jump(v.second, dep[v.second] - dep[x] - 1));
  }
  sort(qwq + 1, qwq + cqwq + 1, comp_qwq);
  for (int i = 1, las = 0; i <= cqwq; i++) {
    ans += sz::ask(dfn[qwq[i].u]) + sz::ask(dfn[qwq[i].v]);
    if (i == cqwq || qwq[i].au != qwq[i + 1].au || qwq[i].av != qwq[i + 1].av) {
      for (int j = i; j > las; j--) {
        if (dep[qwq[j].u] - dep[x] >= k)
          sz::additv(jump(qwq[j].u, dep[qwq[j].u] - dep[x] - k), 1);
        if (dep[qwq[j].v] - dep[x] >= k)
          sz::additv(jump(qwq[j].v, dep[qwq[j].v] - dep[x] - k), 1);
      }
      las = i;
    }
  }
}
int tp, st[N], b[N];
inline void insert(int x) {
  if (tp < 2) {
    st[++tp] = x;
    return;
  }
  int lca = getlca(st[tp], x);
  if (lca == st[tp]) {
    st[++tp] = x;
    return;
  }
  while (tp > 1 && dfn[st[tp - 1]] >= dfn[lca]) {
    vt::e[st[tp - 1]].push_back(st[tp]);
    tp--;
  }
  if (st[tp] != lca) {
    vt::e[lca].push_back(st[tp]);
    st[tp] = lca;
  }
  st[++tp] = x;
}
inline bool comp_dfn(int x, int y) { return dfn[x] < dfn[y]; }
inline void rebuild() {
  sort(b + 1, b + b[0] + 1, comp_dfn);
  b[0] = unique(b + 1, b + b[0] + 1) - b - 1;
  tp = 0;
  for (int i = 1; i <= b[0]; i++) insert(b[i]);
  while (tp > 1) {
    vt::e[st[tp - 1]].push_back(st[tp]);
    tp--;
  }
}
void dfs_4(int x) {
  for (auto v : e[x])
    if (v != fa[x]) dfs_4(v);
  if (vec[x].empty()) return;
  b[b[0] = 1] = x;
  for (auto v : vec[x])
    if (v.first != x) {
      b[++b[0]] = v.first;
      vt::vec[v.first].push_back(v.second);
    }
  rebuild();
  vt::rt = x;
  vt::solve();
}
}  // namespace slpf
int main() {
  n = read();
  Q = read();
  k = read();
  for (int i = 1, u, v; i < n; i++) {
    u = read();
    v = read();
    slpf::e[u].push_back(v);
    slpf::e[v].push_back(u);
  }
  slpf::dfs_1(1);
  slpf::dfs_2(1, 1);
  for (int u, v, lca; Q--;) {
    u = read();
    v = read();
    if (dfn[u] > dfn[v]) u ^= v ^= u ^= v;
    lca = slpf::getlca(u, v);
    slpf::vec[lca].push_back(make_pair(u, v));
  }
  slpf::dfs_3(1);
  sz::clear();
  slpf::dfs_4(1);
  cout << ans << "\n";
  return (0 - 0);
}
