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>
using namespace std;
inline int read() {
  int x = 0;
  bool f = 0;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) f = (ch == '-');
  for (; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
  return f ? -x : x;
}
const int maxn = 3e5 + 7;
int n, m, k;
long long ans;
int head[maxn], nx[maxn], to[maxn], ec = 1;
inline void add(int a, int b) {
  nx[++ec] = head[a];
  head[a] = ec;
  to[ec] = b;
}
int f[maxn], d[maxn];
int sz[maxn], son[maxn], top[maxn];
int dfn[maxn], dfr[maxn], dfnx;
int F[maxn][20];
inline int getanc(int x, int k) {
  for (int i = 19; ~i; --i)
    if (k & (1 << i)) x = F[x][i];
  return x;
}
int st[20][maxn], hb[maxn], fir[maxn], eu;
void dfs1(int x) {
  sz[x] = 1;
  d[x] = d[f[x]] + 1;
  st[0][++eu] = x;
  fir[x] = eu;
  for (int i = head[x]; i; i = nx[i]) {
    int t = to[i];
    if (t == f[x]) continue;
    f[t] = x;
    dfs1(t);
    sz[x] += sz[t];
    if (sz[t] > sz[son[x]]) son[x] = t;
    st[0][++eu] = x;
  }
}
void dfs2(int x, int tp) {
  top[x] = tp;
  dfn[x] = ++dfnx;
  if (son[x]) dfs2(son[x], tp);
  for (int i = head[x]; i; i = nx[i]) {
    int t = to[i];
    if (t == f[x] || t == son[x]) continue;
    dfs2(t, t);
  }
  dfr[x] = dfnx;
}
inline int cmp(int a, int b) { return d[a] < d[b] ? a : b; }
inline int lca(int a, int b) {
  a = fir[a];
  b = fir[b];
  if (a > b) swap(a, b);
  int w = hb[b - a + 1];
  return cmp(st[w][a], st[w][b - (1 << w) + 1]);
}
vector<int> con[maxn];
int s[maxn], t[maxn], ord[maxn];
inline bool myjudge(int a, int b) { return d[a] > d[b]; }
inline bool myjudge2(int a, int b) { return dfn[s[a]] < dfn[s[b]]; }
inline bool myjudge3(int a, int b) { return dfn[a] < dfn[b]; }
struct BIT {
  int b[maxn], sta[maxn], top;
  inline void add(int p, int v) {
    for (; p <= n; p += (p & -p)) {
      if (!b[p]) sta[++top] = p;
      b[p] += v;
    }
  }
  inline int que(int p, int v = 0) {
    for (; p; p -= (p & -p)) v += b[p];
    return v;
  }
  inline void clear() {
    while (top) b[sta[top--]] = 0;
  }
} bt;
inline int que_df(int x, int y) {
  int ret = 0;
  while (top[x] ^ top[y]) {
    if (d[top[x]] < d[top[y]]) swap(x, y);
    ret += bt.que(dfn[x]) - bt.que(dfn[top[x]] - 1);
    x = f[top[x]];
  }
  if (dfn[x] > dfn[y]) swap(x, y);
  return ret + bt.que(dfn[y]) - bt.que(dfn[x] - 1);
}
int bin[maxn];
int sta[maxn], tp;
int S[maxn], Sz[maxn], Son[maxn], T;
int SSS[maxn], TTT;
int Head[maxn], To[maxn], Nx[maxn], Ec = 1;
inline void Add(int a, int b) {
  Nx[++Ec] = Head[a];
  Head[a] = Ec;
  To[Ec] = b;
}
multiset<int> stt[maxn];
void predfs(int x) {
  Sz[x] = stt[x].size();
  for (int i = Head[x]; i; i = Nx[i]) {
    int t = To[i];
    predfs(t);
    Sz[x] += Sz[t];
    if (Sz[t] > Sz[Son[x]]) Son[x] = t;
  }
}
void dfs(int x) {
  int rt = S[1];
  for (int i = Head[x]; i; i = Nx[i])
    if (To[i] != Son[x]) dfs(To[i]), bt.clear();
  if (Son[x]) dfs(Son[x]);
  if (stt[x].size() > Sz[Son[x]]) {
    if (Son[x]) dfs(Son[x]), bt.clear();
    int cnt = 0;
    for (multiset<int>::iterator it = stt[x].begin(); it != stt[x].end();
         ++it) {
      int y = *it;
      if (d[x] - d[rt] >= k)
        ans += cnt;
      else {
        int ds = k - d[x] + d[rt];
        if (d[y] - d[rt] >= ds) {
          int anc = getanc(y, d[y] - d[rt] - ds);
          ans += bt.que(dfr[anc]) - bt.que(dfn[anc] - 1);
        }
      }
      bt.add(dfn[y], 1);
      ++cnt;
    }
  } else {
    swap(stt[x], stt[Son[x]]);
  }
  for (int i = Head[x]; i; i = Nx[i]) {
    int t = To[i];
    for (multiset<int>::iterator it = stt[t].begin(); it != stt[t].end();
         ++it) {
      int y = *it;
      if (d[x] - d[rt] >= k)
        ans += stt[x].size();
      else {
        int ds = k - (d[x] - d[rt]);
        if (d[y] - d[rt] >= ds) {
          int anc = getanc(y, d[y] - d[rt] - ds);
          ans += bt.que(dfr[anc]) - bt.que(dfn[anc] - 1);
        }
      }
      bt.add(dfn[y], 1);
      stt[x].insert(y);
    }
  }
}
int main() {
  n = read();
  m = read();
  k = read();
  for (int i = 1; i < n; ++i) {
    int u = read(), v = read();
    add(u, v);
    add(v, u);
  }
  dfs1(1);
  dfs2(1, 1);
  hb[0] = -1;
  for (int i = 1; i <= eu; ++i) hb[i] = hb[i >> 1] + 1;
  for (int u = 1; u < 20; ++u) {
    for (int i = 1; i + (1 << u) - 1 <= eu; ++i)
      st[u][i] = cmp(st[u - 1][i], st[u - 1][i + (1 << (u - 1))]);
  }
  for (int i = 1; i <= n; ++i) F[i][0] = f[i];
  for (int u = 1; u < 20; ++u) {
    for (int i = 1; i <= n; ++i) F[i][u] = F[F[i][u - 1]][u - 1];
  }
  for (int i = 1; i <= m; ++i) {
    s[i] = read();
    t[i] = read();
    if (dfn[s[i]] > dfn[t[i]]) swap(s[i], t[i]);
    con[lca(s[i], t[i])].push_back(i);
  }
  for (int i = 1; i <= n; ++i) ord[i] = i;
  sort(ord + 1, ord + 1 + n, myjudge);
  for (int i = 1; i <= n; ++i)
    if (con[ord[i]].size()) {
      int x = ord[i];
      for (int j = 0; j < con[x].size(); ++j)
        ans += que_df(s[con[x][j]], t[con[x][j]]);
      for (int j = 0; j < con[x].size(); ++j) {
        int id = con[x][j], ss = s[id], tt = t[id], lc = lca(ss, tt);
        if (d[ss] - d[lc] >= k) bt.add(dfn[getanc(ss, d[ss] - d[lc] - k)], 1);
        if (d[tt] - d[lc] >= k) bt.add(dfn[getanc(tt, d[tt] - d[lc] - k)], 1);
      }
    }
  for (int i = 1; i <= n; ++i)
    if (con[i].size() > 1) {
      sort(con[i].begin(), con[i].end(), myjudge2);
      for (int j = 0; j < con[i].size(); ++j) {
        int x = con[i][j];
        if (d[s[x]] - d[i] >= k) ans += bin[getanc(s[x], d[s[x]] - d[i] - 1)];
        if (d[t[x]] - d[i] >= k) ++bin[getanc(t[x], d[t[x]] - d[i] - 1)];
      }
    }
  for (int i = 1; i <= n; ++i)
    if (con[i].size() > 1) {
      bt.clear();
      tp = 0;
      for (int j = 0; j < con[i].size(); ++j)
        sta[++tp] = s[con[i][j]], ++Sz[s[con[i][j]]],
        stt[s[con[i][j]]].insert(t[con[i][j]]);
      sort(sta + 1, sta + 1 + tp, myjudge3);
      T = 0;
      if (sta[1] != i) S[++T] = i;
      for (int j = 1; j <= tp; ++j)
        if (sta[j] != sta[j - 1]) {
          int x = sta[j];
          while (1) {
            if (x == S[T]) {
              --T;
              break;
            }
            int lc = lca(x, S[T]);
            if (lc == S[T]) break;
            if (d[lc] <= d[S[T - 1]])
              Add(S[T - 1], S[T]), --T;
            else
              Add(lc, S[T--]), S[++T] = SSS[++TTT] = lc;
          }
          S[++T] = SSS[++TTT] = x;
        }
      while (T > 1) Add(S[T - 1], S[T]), --T;
      predfs(i);
      dfs(i);
      while (TTT)
        Head[SSS[TTT]] = Sz[SSS[TTT]] = 0, stt[SSS[TTT]].clear(), --TTT;
      Ec = 1;
      Head[i] = 0;
    }
  printf("%lld\n", ans);
  return 0;
}
