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 {
const int IN_LEN = 1 << 18 | 1;
static char buf[IN_LEN], *s, *t;
inline int Getchar(void) {
  return s == t && (t = (s = buf) + fread(buf, 1, IN_LEN, stdin)),
         s == t ? -1 : *s++;
}
template <class T>
inline void read(T& x) {
  static int c, f;
  c = Getchar(), x = f = 0;
  while (c < '0' || c > '9') {
    if (c == '-') f = 1;
    c = Getchar();
  }
  while (c <= '9' && c >= '0') x = x * 10 + c - 48, c = Getchar();
  x = f ? -x : x;
}
}  // namespace IO
using IO::read;
using namespace std;
const int N = 2e5 + 5;
const int LG = 20;
int son[N << 6][2], Val[N << 6], nidx, rt[N];
void ins(int l, int r, int& u, int pos) {
  if (!u) u = ++nidx;
  ++Val[u];
  if (l == r) return;
  int mid = (l + r) >> 1;
  if (mid >= pos)
    ins(l, mid, son[u][0], pos);
  else
    ins(mid + 1, r, son[u][1], pos);
}
int qry(int l, int r, int u, int L, int R) {
  if (!u) return 0;
  if (l >= L && r <= R) return Val[u];
  int mid = (l + r) >> 1, res = 0;
  if (mid >= L) res += qry(l, mid, son[u][0], L, R);
  if (mid < R) res += qry(mid + 1, r, son[u][1], L, R);
  return res;
}
int merge(int u, int v) {
  if (!u || !v) return u + v;
  Val[u] += Val[v];
  son[u][0] = merge(son[u][0], son[v][0]);
  son[u][1] = merge(son[u][1], son[v][1]);
  return u;
}
vector<int> G[N];
vector<pair<int, int> > ch[N];
int dep[N], f[LG][N], n, m, k, dfn[N], dfc, siz[N];
set<int> st[N];
namespace BIT {
int tree[N];
void add(int i, int v) {
  while (i <= n) tree[i] += v, i += (i & (-i));
}
int sum(int i) {
  int res = 0;
  while (i) res += tree[i], i -= (i & (-i));
  return res;
}
int qry(int x) { return sum(x); }
void mdf(int l, int r, int v) {
  add(l, v);
  add(r + 1, -v);
}
}  // namespace BIT
void pre(int u, int fa) {
  dep[u] = dep[fa] + 1, dfn[u] = ++dfc, f[0][u] = fa, siz[u] = 1;
  for (const int& v : G[u])
    if (v != fa) pre(v, u), siz[u] += siz[v];
}
void init(void) {
  pre(1, 0);
  for (int k = 1; k < LG; ++k)
    for (int u = 1; u <= n; ++u) f[k][u] = f[k - 1][f[k - 1][u]];
}
int LCA(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  for (int i = LG - 1; ~i; --i)
    if ((1 << i) <= dep[u] - dep[v]) u = f[i][u];
  if (u == v) return u;
  for (int i = LG - 1; ~i; --i)
    if (f[i][u] != f[i][v]) u = f[i][u], v = f[i][v];
  return f[0][u];
}
int kthfa(int u, int k) {
  for (int i = 0; (1 << i) <= k; ++i)
    if ((k >> i) & 1) u = f[i][u];
  return u;
}
int dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[LCA(u, v)]; }
int kstep(int u, int v, int k) {
  if (dist(u, v) < k) return 0;
  int lca = LCA(u, v);
  if (dep[u] - dep[lca] >= k) return kthfa(u, k);
  k -= dep[u] - dep[lca];
  return kthfa(v, dep[v] - dep[lca] - k);
}
bool cmp(int a, int b) { return dfn[a] < dfn[b]; }
long long ans;
int S[N], tp, dat[N], tot;
vector<int> val[N];
vector<int> NG[N];
pair<int, int> w[N];
void ndfs(int u) {
  rt[u] = 0, st[u].clear();
  for (const int& v : NG[u]) {
    ndfs(v);
    if (st[u].size() < st[v].size()) swap(st[u], st[v]), swap(rt[u], rt[v]);
    for (const int& id : st[v]) {
      pair<int, int> path = w[id];
      int L = path.first, R = path.second, lca, mid;
      lca = LCA(L, R);
      mid = kstep(u, R, k);
      if (mid) {
        if (LCA(mid, L) != lca)
          ans += st[u].size();
        else
          ans += qry(1, n, rt[u], dfn[mid], dfn[mid] + siz[mid] - 1);
      }
    }
    for (const int& id : st[v]) st[u].insert(id);
    st[v].clear();
    rt[u] = merge(rt[u], rt[v]);
  }
  for (const int& v : val[u]) {
    pair<int, int> path = w[v];
    int L = path.first, R = path.second, lca, mid;
    lca = LCA(L, R);
    mid = kstep(u, R, k);
    if (mid) {
      if (LCA(mid, L) != lca)
        ans += st[u].size();
      else
        ans += qry(1, n, rt[u], dfn[mid], dfn[mid] + siz[mid] - 1);
    }
    st[u].insert(v);
    ins(1, n, rt[u], dfn[R]);
  }
}
void clr(int u) {
  st[u].clear(), val[u].clear(), rt[u] = 0;
  for (const int& v : NG[u]) clr(v);
  NG[u].clear();
}
void dfs(int u, int fa) {
  for (const int& v : G[u])
    if (v != fa) dfs(v, u);
  for (const pair<int, int>& v : ch[u]) ans += BIT::qry(dfn[v.second]);
  for (const pair<int, int>& v : ch[u])
    if (dep[v.second] - dep[u] >= k) {
      int tmp = kthfa(v.second, dep[v.second] - dep[u] - k);
      BIT::mdf(dfn[tmp], dfn[tmp] + siz[tmp] - 1, 1);
    }
  for (const pair<int, int>& v : ch[u]) ans += BIT::qry(dfn[v.first]);
  for (const pair<int, int>& v : ch[u])
    if (dep[v.first] - k >= dep[u]) {
      int tmp = kthfa(v.first, dep[v.first] - dep[u] - k);
      BIT::mdf(dfn[tmp], dfn[tmp] + siz[tmp] - 1, 1);
    }
  if (ch[u].size() <= 1) return;
  tot = 0;
  for (const pair<int, int>& v : ch[u]) {
    dat[++tot] = v.first;
    w[tot] = v;
    val[v.first].push_back(tot);
  }
  dat[++tot] = u;
  sort(dat + 1, dat + 1 + tot, cmp);
  int tmp_tot = tot;
  tot = 0;
  for (int i = 1; i <= tmp_tot; ++i)
    if (dat[i] != dat[i - 1]) dat[++tot] = dat[i];
  S[tp = 1] = dat[1];
  for (int i = 2; i <= tot; ++i) {
    int x = dat[i], y = LCA(dat[i], S[tp]);
    while (tp > 1 && dfn[S[tp - 1]] >= dfn[y])
      NG[S[tp - 1]].push_back(S[tp]), --tp;
    if (S[tp] != y) NG[y].push_back(S[tp]), S[tp] = y;
    S[++tp] = x;
  }
  while (tp > 1) NG[S[tp - 1]].push_back(S[tp]), --tp;
  ndfs(u);
  clr(u);
}
int main(void) {
  read(n), read(m), read(k);
  for (int i = 1, u, v; i < n; ++i) {
    read(u), read(v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  init();
  for (int i = 1, u, v, lca; i <= m; ++i) {
    read(u), read(v);
    lca = LCA(u, v);
    if (dfn[u] > dfn[v]) swap(u, v);
    ch[lca].push_back(pair<int, int>(u, v));
  }
  dfs(1, 0);
  cout << ans;
  return 0;
}
