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>
template <class T>
inline void read(T &x) {
  x = 0;
  register char c = getchar();
  register bool f = 0;
  while (!isdigit(c)) f ^= c == '-', c = getchar();
  while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
  if (f) x = -x;
}
const int N = 1.5e5 + 10;
int n, m, k, rt, all, vis[N], mxp[N], siz[N];
long long ans;
std::vector<int> G[N], L[N], nod[N];
struct Data {
  int src, dep;
} dat[N];
inline long long C2(int n) { return (long long)n * (n - 1) / 2; }
void getroot(int u, int fa) {
  siz[u] = 1 + L[u].size(), mxp[u] = 0;
  for (int v : G[u])
    if (!vis[v] && v != fa) {
      getroot(v, u);
      siz[u] += siz[v];
      mxp[u] = std::max(mxp[u], siz[v]);
    }
  mxp[u] = std::max(mxp[u], all - siz[u]);
  if (mxp[u] < mxp[rt]) rt = u;
}
void getdata(int u, int fa, int src, int dep) {
  nod[src].push_back(u);
  dat[u] = {src, dep};
  for (int v : G[u])
    if (!vis[v] && v != fa) {
      getdata(v, u, src, dep + 1);
    }
}
int filter(const std::vector<int> &f, int lim) {
  int cnt = 0;
  for (int x : f) cnt += dat[x].dep >= lim;
  return cnt;
}
std::vector<int> calc(int u, int fa) {
  std::vector<int> cur;
  for (int x : L[u])
    if (dat[u].src != dat[x].src) {
      printf("u=%d x=%d\n", u, x);
      cur.push_back(x);
    }
  long long tem = 0;
  for (int v : G[u])
    if (!vis[v] && v != fa) {
      std::vector<int> rhs = calc(v, u);
      tem -= C2(filter(rhs, k - dat[u].dep));
      cur.insert(cur.end(), rhs.begin(), rhs.end());
    }
  tem += C2(filter(cur, k - dat[u].dep));
  if (tem) printf("(calc) tem[%d]=%lld\n", u, tem);
  ans += tem;
  return cur;
}
void solve(int u) {
  printf("solve %d\n", u);
  vis[u] = 1;
  dat[u] = {0, 0};
  for (int v : G[u])
    if (!vis[v]) {
      nod[v].clear();
      getdata(v, u, v, 1);
    }
  std::vector<int> cur = L[u];
  long long tem = 0;
  for (int v : G[u])
    if (!vis[v]) {
      std::vector<int> rhs = calc(v, u);
      tem -= C2(filter(rhs, k));
      cur.insert(cur.end(), rhs.begin(), rhs.end());
      if (rhs.size()) {
        for (int x : rhs) printf("%d ", x);
        printf("\n");
      }
      if (tem) printf("(solve) tem[%d]=%lld\n", u, tem);
    }
  tem += C2(filter(cur, k));
  if (cur.size()) {
    for (int x : cur) printf("%d ", x);
    printf("\n");
  }
  if (tem) printf("(solve) tem[%d]=%lld\n", u, tem);
  ans += tem;
  for (int v : G[u])
    if (!vis[v]) {
      all = nod[v].size();
      for (int x : nod[v]) {
        std::vector<int> tmp;
        L[x].swap(tmp);
        for (int y : tmp)
          if (dat[x].src == dat[y].src) L[x].push_back(y), ++all;
      }
      mxp[rt = 0] = all;
      getroot(v, 0), solve(rt);
    }
}
int main() {
  read(n), read(m), read(k);
  for (int u, v, i = 1; i < n; i++) {
    read(u), read(v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  for (int u, v, i = 1; i <= m; i++) {
    read(u), read(v);
    L[u].push_back(v);
    L[v].push_back(u);
  }
  mxp[rt = 0] = all = n + (m << 1);
  getroot(1, 0), solve(rt);
  printf("%lld\n", ans >> 1);
}
