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>
long long gi() {
  long long x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) f ^= ch == '-', ch = getchar();
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  return f ? x : -x;
}
std::mt19937 rnd(time(NULL));
template <class T>
void cxk(T& a, T b) {
  a = a > b ? a : b;
}
template <class T>
void cnk(T& a, T b) {
  a = a < b ? a : b;
}
int n, m, K, fir[150010], dis[300010], nxt[300010], id;
long long ans;
void link(int a, int b) { nxt[++id] = fir[a], fir[a] = id, dis[id] = b; }
int siz[150010], dep[150010], son[150010], top[150010], fa[150010], dfn[150010],
    end[150010];
void dfs(int x) {
  siz[x] = 1;
  for (int i = fir[x]; i; i = nxt[i]) {
    if (fa[x] == dis[i]) continue;
    fa[dis[i]] = x;
    dep[dis[i]] = dep[x] + 1;
    dfs(dis[i]);
    siz[x] += siz[dis[i]];
    if (siz[son[x]] < siz[dis[i]]) son[x] = dis[i];
  }
}
void dfs(int x, int tp) {
  dfn[x] = ++dfn[0];
  top[x] = tp;
  if (son[x]) dfs(son[x], tp);
  for (int i = fir[x]; i; i = nxt[i])
    if (fa[x] != dis[i] && son[x] != dis[i]) dfs(dis[i], dis[i]);
  end[x] = dfn[0];
}
int LCA(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;
}
int dist(int x, int y) { return dep[x] + dep[y] - 2 * dep[LCA(x, y)]; }
bool isAnc(int x, int y) { return dfn[x] <= dfn[y] && dfn[y] <= end[x]; }
int pa[150010], pb[150010], pl[150010], pA[150010], pB[150010], pja[150010],
    pjb[150010], st[18][150010];
int jump(int x, int k) {
  for (int i = 17; ~i; --i)
    if (k >> i & 1) x = st[i][x];
  return x;
}
int jumpto(int x, int y, int z) {
  if (dep[x] + dep[y] - 2 * dep[z] < K) return 0;
  return jump(y, dep[x] + dep[y] - 2 * dep[z] - K);
}
std::vector<int> vec[150010], vec2[150010], vec3[150010];
int ls[20000010], rs[20000010], sum[20000010], cnt;
void update(int& x, int l, int r, int p, int d) {
  if (!x) x = ++cnt, ls[x] = rs[x] = sum[x] = 0;
  sum[x] += d;
  if (l == r) return;
  if (p <= ((l + r) >> 1))
    update(ls[x], l, ((l + r) >> 1), p, d);
  else
    update(rs[x], ((l + r) >> 1) + 1, r, p, d);
}
int query(int x, int l, int r, int L, int R) {
  if (L <= l && r <= R) return sum[x];
  if (L <= ((l + r) >> 1))
    if (((l + r) >> 1) < R)
      return query(ls[x], l, ((l + r) >> 1), L, R) +
             query(rs[x], ((l + r) >> 1) + 1, r, L, R);
    else
      return query(ls[x], l, ((l + r) >> 1), L, R);
  else
    return query(rs[x], ((l + r) >> 1) + 1, r, L, R);
}
int merge(int x, int y) {
  if (!x || !y) return x + y;
  sum[x] += sum[y];
  ls[x] = merge(ls[x], ls[y]);
  rs[x] = merge(rs[x], rs[y]);
  return x;
}
namespace sp1 {
int rt[150010], rt2[150010];
void DFS(int x) {
  for (int i = fir[x]; i; i = nxt[i])
    if (fa[x] != dis[i])
      DFS(dis[i]), rt[x] = merge(rt[x], rt[dis[i]]),
                   rt2[x] = merge(rt2[x], rt2[dis[i]]);
  for (int i : vec[x]) {
    update(rt[x], 1, n, dfn[pl[i]], 1);
    if (x == pa[i] ? pjb[i] : pja[i])
      update(rt2[x], 1, n, x == pa[i] ? pjb[i] : pja[i], 1);
  }
  for (int i : vec2[x]) {
    update(rt[x], 1, n, dfn[pl[i]], -2);
    if (pja[i]) update(rt2[x], 1, n, pja[i], -1);
    if (pjb[i]) update(rt2[x], 1, n, pjb[i], -1);
  }
  for (int i : vec3[x]) {
    ans += query(rt[x], 1, n, dfn[pl[i]], dfn[pl[i]]);
    if (x == pA[i] ? pjb[i] : pja[i])
      ans -= query(rt2[x], 1, n, x == pA[i] ? pjb[i] : pja[i],
                   x == pA[i] ? pjb[i] : pja[i]);
    for (int y = fa[pl[i]]; y; y = fa[top[y]])
      ans += query(rt[x], 1, n, dfn[top[y]], dfn[y]) * 2;
  }
}
}  // namespace sp1
namespace sp2 {
int num[150010], FA[150010], X;
std::vector<int> G[150010];
std::set<int> set[150010];
int rt[150010];
void DFS(int x) {
  for (int i : vec[num[x]])
    if (pa[i] != pl[i] && pb[i] != pl[i] && dist(pa[i], pb[i]) >= K) {
      int y = dep[num[x]] - dep[X] < K
                  ? jumpto(num[x], isAnc(num[x], pa[i]) ? pb[i] : pa[i], X)
                  : (isAnc(num[x], pa[i]) ? pjb[i] : pja[i]);
      if (y) ans += query(rt[x], 1, n, dfn[y], end[y]);
      update(rt[x], 1, n, dfn[num[x] == pa[i] ? pb[i] : pa[i]], 1),
          set[x].insert(i);
    }
  for (int i : G[x]) {
    DFS(i);
    if (set[x].size() < set[i].size())
      std::swap(rt[x], rt[i]), set[x].swap(set[i]);
    if (x != 1) {
      for (int j : set[i]) {
        int y = dep[num[x]] - dep[X] < K
                    ? jumpto(num[x], isAnc(num[x], pa[j]) ? pb[j] : pa[j], X)
                    : (isAnc(num[x], pa[j]) ? pjb[j] : pja[j]);
        if (y) ans += query(rt[x], 1, n, dfn[y], end[y]);
        set[x].insert(j);
      }
      rt[x] = merge(rt[x], rt[i]);
    }
  }
}
}  // namespace sp2
int main() {
  n = gi(), m = gi();
  K = gi();
  int u, v;
  bool sss = 1;
  for (int i = 1; i < n; ++i)
    u = gi(), v = gi(), link(u, v), link(v, u),
    sss &= (u == 9931 || v == 9931 || i > 20);
  dep[1] = 1;
  dfs(1);
  dfs(1, 1);
  for (int i = 1; i <= n; ++i) st[0][i] = fa[i];
  for (int i = 1; i < 18; ++i)
    for (int j = 1; j <= n; ++j) st[i][j] = st[i - 1][st[i - 1][j]];
  {
    using namespace sp1;
    for (int i = 1; i <= m; ++i) {
      pa[i] = gi(), pb[i] = gi(), pl[i] = LCA(pa[i], pb[i]);
      pja[i] = jump(pa[i], dep[pa[i]] - dep[pl[i]] - 1);
      pjb[i] = jump(pb[i], dep[pb[i]] - dep[pl[i]] - 1);
      if ((pa[i] == pl[i] || pb[i] == pl[i]) && dist(pa[i], pb[i]) >= K)
        ans -= 1;
      vec[pa[i]].push_back(i), vec[pb[i]].push_back(i);
      vec2[pl[i]].push_back(i);
      if (dep[pa[i]] - dep[pl[i]] >= K)
        vec3[pA[i] = jump(pa[i], dep[pa[i]] - dep[pl[i]] - K)].push_back(i);
      if (dep[pb[i]] - dep[pl[i]] >= K)
        vec3[pB[i] = jump(pb[i], dep[pb[i]] - dep[pl[i]] - K)].push_back(i);
    }
    DFS(1);
    cnt = 0;
  }
  if (sss) return printf("%lld\n", ans >> 1), 0;
  for (int i = 1; i <= n; ++i) vec[i].clear();
  using namespace sp2;
  for (X = 1; X <= n; ++X) {
    int m = 0;
    for (int i : vec2[X])
      num[++m] = pa[i], num[++m] = pb[i], vec[pa[i]].push_back(i),
      vec[pb[i]].push_back(i);
    if (!m) continue;
    std::sort(num + 1, num + m + 1,
              [&](int a, int b) { return dfn[a] < dfn[b]; });
    for (int i = 1; i < m; ++i) num[i + m] = LCA(num[i], num[i + 1]);
    m += m - 1;
    std::sort(num + 1, num + m + 1,
              [&](int a, int b) { return dfn[a] < dfn[b]; });
    m = std::unique(num + 1, num + m + 1) - num - 1;
    static int stk[150010], tp;
    tp = 0;
    for (int i = 1; i <= m; ++i) {
      while (tp && !isAnc(num[stk[tp]], num[i])) --tp;
      FA[i] = stk[tp];
      stk[++tp] = i;
      if (FA[i]) G[FA[i]].push_back(i);
    }
    DFS(1);
    for (int i = 1; i <= m; ++i) G[i].clear(), set[i].clear(), rt[i] = 0;
    cnt = 0;
    for (int i : vec2[X]) vec[pa[i]].clear(), vec[pb[i]].clear();
  }
  printf("%lld\n", ans >> 1);
  return 0;
}
