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;
const int N = 1.5e5 + 10;
int gi() {
  int x = 0, o = 1;
  char ch = getchar();
  while (!isdigit(ch) && ch != '-') ch = getchar();
  if (ch == '-') o = -1, ch = getchar();
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  return x * o;
}
int n, m, k, dfn[N], low[N], tim, fa[N], anc[N][20], dep[N], s[N], t[N];
long long ans;
vector<int> E[N], vec[N];
void dfs(int u, int ff) {
  fa[u] = anc[u][0] = ff;
  dep[u] = dep[ff] + 1;
  dfn[u] = ++tim;
  for (int i = 1; i <= 17; i++) anc[u][i] = anc[anc[u][i - 1]][i - 1];
  for (auto v : E[u])
    if (v != ff) dfs(v, u);
  low[u] = tim;
}
int lca(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  int c = dep[u] - dep[v];
  for (int i = 17; ~i; i--)
    if (c >> i & 1) u = anc[u][i];
  if (u == v) return u;
  for (int i = 17; ~i; i--)
    if (anc[u][i] != anc[v][i]) u = anc[u][i], v = anc[v][i];
  return fa[u];
}
int jump(int u, int k) {
  for (int i = 17; ~i; i--)
    if (k >> i & 1) u = anc[u][i];
  return u;
}
int move(int u, int v, int k) {
  int p = lca(u, v), dist = dep[u] + dep[v] - 2 * dep[p];
  if (dist < k) return -1;
  if (dep[u] - dep[p] >= k) return jump(u, k);
  return jump(v, dist - k);
}
namespace fenw {
int c[N];
vector<pair<int, int> > opts;
void modify(int p, int v, bool fl = 1) {
  if (fl) opts.push_back(make_pair(p, v));
  while (p <= n) c[p] += v, p += p & -p;
}
int query(int p) {
  int ret = 0;
  while (p) ret += c[p], p -= p & -p;
  return ret;
}
void clear() {
  for (auto t : opts) modify(t.first, -t.second, 0);
  opts.clear();
}
}  // namespace fenw
namespace S1 {
int id[N];
bool cmp(int x, int y) { return dep[x] > dep[y]; }
void solve() {
  for (int i = 1; i <= n; i++) id[i] = i;
  sort(id + 1, id + n + 1, cmp);
  for (int cur = 1; cur <= n; cur++) {
    int u = id[cur];
    for (auto i : vec[u]) {
      ans += fenw::query(dfn[s[i]]);
      ans += fenw::query(dfn[t[i]]);
    }
    for (auto i : vec[u]) {
      int tmp = move(u, s[i], k);
      if (tmp != -1) fenw::modify(dfn[tmp], 1), fenw::modify(low[tmp] + 1, -1);
      tmp = move(u, t[i], k);
      if (tmp != -1) fenw::modify(dfn[tmp], 1), fenw::modify(low[tmp] + 1, -1);
    }
  }
  fenw::clear();
}
}  // namespace S1
namespace seg {
int sum[N * 50], ls[N * 50], rs[N * 50], tt;
void insert(int p, int &x, int l = 1, int r = n) {
  ++tt;
  ls[tt] = ls[x];
  rs[tt] = rs[x];
  sum[tt] = sum[x] + 1;
  x = tt;
  if (l == r) return;
  int mid = (l + r) >> 1;
  p <= mid ? insert(p, ls[x], l, mid) : insert(p, rs[x], mid + 1, r);
}
int query(int L, int R, int x, int l = 1, int r = n) {
  if (!x) return 0;
  if (L <= l && r <= R) return sum[x];
  int mid = (l + r) >> 1, ret = 0;
  if (L <= mid) ret += query(L, R, ls[x], l, mid);
  if (R > mid) ret += query(L, R, rs[x], mid + 1, r);
  return ret;
}
int merge(int x, int y) {
  if (!x || !y) return x | y;
  ls[x] = merge(ls[x], ls[y]);
  rs[x] = merge(rs[x], rs[y]);
  sum[x] += sum[y];
  return x;
}
void clear() {
  for (int i = 1; i <= tt; i++) sum[i] = ls[i] = rs[i] = 0;
  tt = 0;
}
}  // namespace seg
namespace vir {
int rt[N], p;
vector<int> E[N], need_clr, vec[N], all[N];
bool cmp(int x, int y) { return dfn[x] < dfn[y]; }
void build(vector<int> nodes) {
  sort(nodes.begin(), nodes.end(), cmp);
  for (int i = int(nodes.size()) - 2; ~i; i--)
    nodes.push_back(lca(nodes[i], nodes[i + 1]));
  sort(nodes.begin(), nodes.end(), cmp);
  nodes.erase(unique(nodes.begin(), nodes.end()), nodes.end());
  need_clr = nodes;
  static int st[N];
  int tp = 0;
  p = nodes[0];
  for (auto u : nodes) {
    while (tp && low[st[tp]] < dfn[u]) --tp;
    if (tp) E[st[tp]].push_back(u);
    st[++tp] = u;
  }
}
void add(int x, int id) { vec[x].push_back(id); }
void dfs(int u) {
  for (auto i : vec[u]) {
    int b = move(u, t[i], max(k, dep[u] - dep[p] + 1));
    if (b != -1 && u != p) ans += seg::query(dfn[b], low[b], rt[u]);
    seg::insert(dfn[t[i]], rt[u]);
    all[u].push_back(i);
  }
  for (auto v : E[u]) {
    dfs(v);
    if (int(all[u].size()) > int(all[v].size())) {
      for (auto i : all[v]) {
        int b = move(u, t[i], max(k, dep[u] - dep[p] + 1));
        if (b != -1 && u != p) ans += seg::query(dfn[b], low[b], rt[u]);
      }
      for (auto i : all[v]) all[u].push_back(i);
    } else {
      for (auto i : all[u]) {
        int b = move(u, t[i], max(k, dep[u] - dep[p] + 1));
        if (b != -1 && u != p) ans += seg::query(dfn[b], low[b], rt[v]);
      }
      for (auto i : all[u]) all[v].push_back(i);
      swap(all[u], all[v]);
    }
    rt[u] = seg::merge(rt[u], rt[v]);
  }
}
void clear() {
  for (auto u : need_clr) {
    rt[u] = 0;
    E[u].clear();
    vec[u].clear();
    all[u].clear();
  }
}
}  // namespace vir
namespace S2 {
int cur;
pair<int, int> get(int i) {
  if (s[i] == cur) return make_pair(dfn[cur], dfn[t[i]]);
  return make_pair(dfn[move(cur, s[i], 1)], dfn[move(cur, t[i], 1)]);
}
bool cmp(int x, int y) { return get(x) < get(y); }
void solve() {
  for (int u = 1; u <= n; u++) {
    cur = u;
    sort(vec[u].begin(), vec[u].end(), cmp);
    for (int l = 0, r; l < int(vec[u].size()); l = r) {
      r = l + 1;
      if (s[vec[u][l]] != u) {
        while (r < int(vec[u].size()) && get(vec[u][l]) == get(vec[u][r])) ++r;
      }
      for (int o = l; o < r; o++) {
        int i = vec[u][o];
        ans += fenw::query(dfn[s[i]]);
        ans += fenw::query(dfn[t[i]]);
      }
      for (int o = l; o < r; o++) {
        int i = vec[u][o], tmp = move(u, s[i], k);
        if (tmp != -1)
          fenw::modify(dfn[tmp], 1), fenw::modify(low[tmp] + 1, -1);
        tmp = move(u, t[i], k);
        if (tmp != -1)
          fenw::modify(dfn[tmp], 1), fenw::modify(low[tmp] + 1, -1);
      }
    }
    fenw::clear();
    vector<int> all = {u};
    for (auto i : vec[u])
      if (s[i] != u) all.push_back(s[i]), all.push_back(t[i]);
    vir::build(all);
    for (auto i : vec[u])
      if (s[i] != u) vir::add(s[i], i);
    vir::dfs(u);
    vir::clear();
    seg::clear();
  }
}
}  // namespace S2
int main() {
  cin >> n >> m >> k;
  for (int i = 1, u, v; i < n; i++)
    u = gi(), v = gi(), E[u].push_back(v), E[v].push_back(u);
  dfs(1, 0);
  for (int i = 1; i <= m; i++) {
    s[i] = gi(), t[i] = gi();
    if (dfn[s[i]] > dfn[t[i]]) swap(s[i], t[i]);
    vec[lca(s[i], t[i])].push_back(i);
  }
  S1::solve();
  S2::solve();
  cout << ans;
  return 0;
}
