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>
namespace IO {
inline char gc() {
  static const int Rlen = 1 << 22 | 1;
  static char buf[Rlen], *p1, *p2;
  return (p1 == p2) && (p2 = (p1 = buf) + fread(buf, 1, Rlen, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
template <typename T>
T get_integer() {
  char c;
  bool f = false;
  while (!isdigit(c = gc())) f = c == '-';
  T x = c ^ 48;
  while (isdigit(c = gc())) x = ((x + (x << 2)) << 1) + (c ^ 48);
  return f ? -x : x;
}
inline int gi() { return get_integer<int>(); }
}  // namespace IO
using namespace IO;
using std::cerr;
using std::cout;
using pii = std::pair<int, int>;
const int N = 1.5e5 + 7;
int n, m, k;
long long ans;
std::vector<int> G[N];
std::vector<pii> Q[N];
int fa[N], in[N], out[N];
int sz[N], son[N], top[N];
int d[N], ps[N], dfc;
void dfs1(int u, int p) {
  fa[u] = p, d[u] = d[p] + 1;
  for (int v : G[u])
    if (v != p) {
      dfs1(v, u);
      sz[u] += sz[v];
      if (sz[v] > sz[son[u]]) son[u] = v;
    }
  ++sz[u];
}
void dfs2(int u, int tp) {
  top[u] = tp;
  ps[in[u] = ++dfc] = u;
  if (son[u]) dfs2(son[u], tp);
  for (int v : G[u])
    if (v != fa[u] && v != son[u]) dfs2(v, v);
  out[u] = dfc;
}
int LCA(int u, int v) {
  while (top[u] != top[v])
    d[top[u]] < d[top[v]] ? v = fa[top[v]] : u = fa[top[u]];
  return d[u] < d[v] ? u : v;
}
int jump(int u, int k) {
  while (k > d[u] - d[top[u]]) {
    k -= d[u] - d[top[u]] + 1;
    u = fa[top[u]];
  }
  return ps[in[u] - k];
}
namespace SGT {
const int N = ::N * 40;
int lc[N], rc[N], sm[N], ct;
void ins(int &u, int l, int r, int p) {
  if (!u) u = ++ct;
  ++sm[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);
}
int qy(int u, int l, int r, int ql, int qr) {
  if ((ql <= l && r <= qr) || !u) return sm[u];
  int m = (l + r) >> 1;
  if (qr <= m) return qy(lc[u], l, m, ql, qr);
  if (m < ql) return qy(rc[u], m + 1, r, ql, qr);
  return qy(lc[u], l, m, ql, qr) + qy(rc[u], m + 1, r, ql, qr);
}
void merge(int &u, int v) {
  if (!u || !v) {
    u |= v;
    return;
  }
  merge(lc[u], lc[v]);
  merge(rc[u], rc[v]);
  sm[u] += sm[v];
}
void ins(int &u, int p) { ins(u, 1, n, p); }
int qy(int u, int l, int r) { return qy(u, 1, n, l, r); }
void clear() {
  while (ct) lc[ct] = rc[ct] = sm[ct] = 0, --ct;
}
}  // namespace SGT
namespace BIT {
int tr[N];
void add(int l, int r) {
  for (int register p = l; p <= n; p += p & -p) ++tr[p];
  for (int register p = r + 1; p <= n; p += p & -p) --tr[p];
}
int qy(int p) {
  int r = 0;
  for (; p; p &= p - 1) r += tr[p];
  return r;
}
}  // namespace BIT
int rt[N];
std::vector<int> q[N];
void solve_q(int u, int Rt) {
  rt[u] = 0;
  int od = std::max(0, k - d[u] + d[Rt]);
  for (int v : q[u]) {
    if (d[v] >= od + d[Rt]) {
      int p = jump(v, d[v] - d[Rt] - od);
      ans += SGT::qy(rt[u], in[p], out[p]);
    }
    SGT::ins(rt[u], in[v]);
  }
  for (int w : G[u])
    if (Rt != u || w != son[u]) {
      solve_q(w, Rt);
      if (q[w].size() > q[u].size()) q[u].swap(q[w]), std::swap(rt[u], rt[w]);
      for (int v : q[w]) {
        if (d[v] >= od + d[Rt]) {
          int p = jump(v, d[v] - d[Rt] - od);
          ans += SGT::qy(rt[u], in[p], out[p]);
        }
        q[u].push_back(v);
      }
      q[w].clear();
      SGT::merge(rt[u], rt[w]);
    }
}
void solve(int u) {
  for (int v : G[u]) solve(v);
  for (auto &t : Q[u]) ans += BIT::qy(in[t.second]);
  for (auto &t : Q[u])
    if (d[t.second] >= d[u] + k) {
      int p = jump(t.second, d[t.second] - d[u] - k);
      BIT::add(in[p], out[p]);
    }
  for (auto &t : Q[u]) ans += BIT::qy(in[t.first]);
  for (auto &t : Q[u])
    if (d[t.first] >= d[u] + k) {
      int p = jump(t.first, d[t.first] - d[u] - k);
      BIT::add(in[p], out[p]);
    }
  for (auto &t : Q[u]) q[t.first].push_back(t.second);
  solve_q(u, u);
  q[u].clear();
  SGT::clear();
}
void Main() {
  n = gi(), m = gi(), k = gi();
  for (int register i = 1; i < n; ++i) {
    int u = gi(), v = gi();
    G[u].push_back(v);
    G[v].push_back(u);
  }
  dfs1(1, 0);
  dfs2(1, 1);
  for (int register i = 2; i <= n; ++i)
    G[i].erase(std::find(G[i].begin(), G[i].end(), fa[i]));
  for (int register i = 1; i <= m; ++i) {
    int u = gi(), v = gi();
    if (in[u] > in[v]) std::swap(u, v);
    if (in[v] > out[u]) std::swap(u, v);
    Q[LCA(u, v)].push_back({u, v});
  }
  solve(1);
  cout << ans << "\n";
}
inline void file() {}
signed main() {
  file();
  Main();
  return 0;
}
