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>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-const-variable"
using namespace std;
long long sqr(long long x) { return x * x; }
int mysqrt(long long x) {
  int l = 0, r = 1e9 + 1;
  while (r - l > 1) {
    int m = (l + r) / 2;
    if (m * (long long)m <= x)
      l = m;
    else
      r = m;
  }
  return l;
}
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
mt19937_64 rndll(
    chrono::high_resolution_clock::now().time_since_epoch().count());
template <typename T>
T gcd(T a, T b) {
  return a ? gcd(b % a, a) : b;
}
int gcdex(int a, int b, int &x, int &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  int x1, y1;
  int ret = gcdex(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return ret;
}
int Mod = 998244353;
int Bpow(int x, long long y) {
  int ret = 1;
  int w = x;
  while (y) {
    if (y & 1) ret = (ret * (long long)w) % Mod;
    w = (w * (long long)w) % Mod;
    y >>= 1;
  }
  return ret;
}
int Bdiv(int x) {
  int a, b;
  gcdex(x, Mod, a, b);
  if (a < 0) a += Mod;
  return a;
}
int Bdiv(int x, int y) { return (x * (long long)Bpow(y, Mod - 2)) % Mod; }
inline int ad(int x, int y) { return x + y >= Mod ? x + y - Mod : x + y; }
inline int dif(int x, int y) { return x - y < 0 ? x - y + Mod : x - y; }
inline int mul(int x, int y) { return (x * (long long)y) % Mod; }
int inv(int a) {
  int b = Mod, x = 0, y = 1;
  while (a) {
    int t = b / a;
    b -= a * t;
    x -= t * y;
    swap(a, b);
    swap(x, y);
  }
  if (x < 0) x += Mod;
  return x;
}
void setmin(int &x, int y) { x = min(x, y); }
void setmax(int &x, int y) { x = max(x, y); }
void setmin(long long &x, long long y) { x = min(x, y); }
void setmax(long long &x, long long y) { x = max(x, y); }
const long long llinf = 4e18 + 100;
const long double eps = 1e-9;
const int maxn = 15e4 + 100, maxw = 1e6 + 100, inf = 1e9 + 100, sq = 100,
          LG = 18, mod = 1e9 + 933;
vector<int> e[maxn];
int mas[maxn][3];
int n;
int fen[maxn], all, pref[maxn];
int Get(int l, int r) { return pref[r] - (l == 0 ? 0 : pref[l - 1]); }
void inc(int i, int w) {
  all += w;
  for (; i < n; i = (i | (i + 1))) fen[i] += w;
}
int get(int i) {
  int w = 0;
  for (; i >= 0; i = (i & (i + 1)) - 1) w += fen[i];
  return w;
}
int get(int l, int r) { return get(r) - get(l - 1); }
int oget(int l, int r) { return all - get(l, r); }
int tin[maxn], tout[maxn], tnow;
int sz[maxn];
int up[LG][maxn], h[maxn];
bool bad[maxn];
vector<pair<int, int> > que[maxn];
void predfs(int v, int par) {
  tin[v] = tnow++;
  sz[v] = que[v].size();
  for (int i : e[v])
    if (i != par) {
      up[0][i] = v;
      h[i] = h[v] + 1;
      predfs(i, v);
      sz[v] += sz[i];
    }
  tout[v] = tnow - 1;
}
int go(int v, int len) {
  for (int i = LG - 1; i >= 0; i--)
    if ((1 << i) & len) v = up[i][v];
  return v;
}
void add(int v, int par, int w) {
  for (auto i : que[v])
    if (!bad[i.first]) inc(tin[mas[i.first][i.second ^ 1]], w);
  for (int i : e[v])
    if (i != par) add(i, v, w);
}
int getlca(int v, int u) {
  if (h[v] < h[u]) swap(v, u);
  if (tin[u] <= tin[v] && tout[u] >= tin[v]) return u;
  v = go(v, h[v] - h[u]);
  for (int i = LG - 1; i >= 0; i--)
    if (up[i][v] != up[i][u]) v = up[i][v], u = up[i][u];
  return up[0][v];
}
void precalc() {
  predfs(0, -1);
  for (int j = 1; j < LG; j++)
    for (int i = 0; i < n; i++) up[j][i] = up[j - 1][up[j - 1][i]];
}
long long ans;
int K;
set<pair<int, int> > g[maxn];
ostream cnull(NULL);
void dfs(int v, int par) {
  int big = -1;
  for (int i : e[v])
    if (i != par && (big == -1 || sz[big] < sz[i])) big = i;
  cnull << "v big " << v << ' ' << big << '\n';
  for (int i : e[v])
    if (i != par && i != big) {
      dfs(i, v);
      add(i, v, -1);
    }
  if (big != -1) {
    dfs(big, v);
    swap(g[big], g[v]);
  }
  vector<int> rm;
  for (int i : e[v])
    if (i != par && i != big) {
      for (auto j : g[i]) {
        {
          int y = mas[j.first][j.second ^ 1], z = mas[j.first][2];
          if (h[v] - h[z] >= K) {
            int o = go(v, K - 1);
            cnull << "1 " << v << ' ' << i << ' ' << oget(tin[o], tout[o])
                  << '\n';
            ans += oget(tin[o], tout[o]);
          } else {
            int len = h[v] + h[y] - 2 * h[z];
            if (len >= K) {
              int o = go(y, len - K);
              cnull << "2 " << v << ' ' << i << ' ' << get(tin[o], tout[o])
                    << '\n';
              ans += get(tin[o], tout[o]);
            }
          }
        }
        if (g[v].find({j.first, j.second ^ 1}) != g[v].end()) {
          rm.push_back(j.first);
        }
        inc(tin[mas[j.first][j.second ^ 1]], 1);
        g[v].insert(j);
      }
    }
  for (auto j : que[v]) {
    {
      int y = mas[j.first][j.second ^ 1], z = mas[j.first][2];
      if (h[v] - h[z] >= K) {
        int o = go(v, K - 1);
        cnull << v << ' ' << oget(tin[o], tout[o]) << '\n';
        ans += oget(tin[o], tout[o]);
      } else {
        int len = h[v] + h[y] - 2 * h[z];
        if (len >= K) {
          int o = go(y, len - K);
          cnull << v << ' ' << get(tin[o], tout[o]) << '\n';
          ans += get(tin[o], tout[o]);
        }
      }
    }
    if (g[v].find({j.first, j.second ^ 1}) != g[v].end()) {
      rm.push_back(j.first);
    }
    inc(tin[mas[j.first][j.second ^ 1]], 1);
    g[v].insert(j);
  }
  for (int i : rm) {
    bad[i] = 1;
    g[v].erase({i, 0});
    g[v].erase({i, 1});
    inc(tin[mas[i][0]], -1);
    inc(tin[mas[i][1]], -1);
  }
}
vector<int> op[maxn];
void dfs1(int v, int par) {
  int big = -1;
  for (int i : e[v])
    if (i != par && (big == -1 || sz[big] < sz[i])) big = i;
  for (int i : e[v])
    if (i != big && i != par) {
      dfs1(i, v);
      add(i, v, -1);
    }
  if (big != -1) {
    dfs1(big, v);
  }
  for (int i : e[v])
    if (i != big && i != par) {
      add(i, v, 1);
    }
  for (auto i : que[v]) inc(tin[mas[i.first][i.second ^ 1]], 1);
  for (int i : op[v]) {
    int z = mas[i][2];
    auto f = [&](int x) {
      if (h[x] - h[z] >= K) {
        int o = go(x, h[x] - h[z] - K);
        ans += Get(tin[o], tout[o]) - get(tin[o], tout[o]);
        cnull << v << ' ' << Get(tin[o], tout[o]) - get(tin[o], tout[o])
              << '\n';
      }
    };
    f(mas[i][0]);
    f(mas[i][1]);
  }
}
void solve() {
  int m;
  cin >> n >> m >> K;
  for (int i = 1; i < n; i++) {
    int v, u;
    cin >> v >> u;
    v--;
    u--;
    e[v].push_back(u);
    e[u].push_back(v);
  }
  for (int i = 0; i < m; i++) {
    cin >> mas[i][0] >> mas[i][1];
    mas[i][0]--;
    mas[i][1]--;
    que[mas[i][0]].emplace_back(i, 0);
    que[mas[i][1]].emplace_back(i, 1);
  }
  precalc();
  for (int i = 0; i < m; i++) {
    mas[i][2] = getlca(mas[i][0], mas[i][1]);
    op[mas[i][2]].push_back(i);
    pref[tin[mas[i][0]]]++;
    pref[tin[mas[i][1]]]++;
  }
  for (int i = 1; i < n; i++) pref[i] += pref[i - 1];
  dfs(0, -1);
  memset(bad, 0, sizeof(bad));
  dfs1(0, -1);
  cout << ans / 2 << '\n';
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  while (t--) {
    solve();
  }
}
