#include <bits/stdc++.h>
using namespace std;
pair<int, int> dtm[100005];
bool vis[100005];
int dep[100005], sp[100005], tim, tree[4 * 100005 + 5], arr[100005], m, d,
    lazy[4 * 100005 + 5], cnt;
vector<int> v[100005];
map<int, int> mp, mp2;
map<int, int>::iterator it;
void dfs(int node, int dd) {
  vis[node] = true;
  dep[node] = dd;
  dtm[node].first = tim++;
  for (int i = 0; i < (v[node].size()); i++) {
    if (!vis[v[node][i]]) {
      dfs(v[node][i], dd + 1);
    }
  }
  dtm[node].second = tim++;
}
void build(int lft, int rght, int node) {
  if (lft == rght) {
    tree[node] = arr[lft - 1];
    return;
  }
  int mid = (lft + rght) / 2;
  build(lft, mid, 2 * node);
  build(mid + 1, rght, 2 * node + 1);
  tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
void unlazy(int lnode, int rnode, int node) {
  if (!lazy[node]) return;
  tree[node] += lazy[node];
  if (lnode != rnode) {
    lazy[2 * node] += lazy[node];
    lazy[2 * node + 1] += lazy[node];
  }
  lazy[node] = 0;
}
int query(int lft, int rght, int lnode, int rnode, int node) {
  unlazy(lnode, rnode, node);
  if (lft == lnode && rght == rnode) return tree[node];
  int mid = (lnode + rnode) / 2;
  if (mid >= rght)
    return query(lft, rght, lnode, mid, 2 * node);
  else if (mid + 1 <= lft)
    return query(lft, rght, mid + 1, rnode, 2 * node + 1);
  return max(query(lft, mid, lnode, mid, 2 * node),
             query(mid + 1, rght, mid + 1, rnode, 2 * node + 1));
}
void update(int lft, int rght, int lnode, int rnode, int val, int node) {
  if (lft > rght) return;
  unlazy(lnode, rnode, node);
  if (lft == lnode && rght == rnode) {
    lazy[node] = val;
    return;
  }
  int mid = (lnode + rnode) / 2;
  if (mid >= rght)
    update(lft, rght, lnode, mid, val, 2 * node);
  else if (mid + 1 <= lft)
    update(lft, rght, mid + 1, rnode, val, 2 * node + 1);
  else {
    update(lft, mid, lnode, mid, val, 2 * node);
    update(mid + 1, rght, mid + 1, rnode, val, 2 * node + 1);
  }
  unlazy(lnode, mid, 2 * node);
  unlazy(mid + 1, rnode, 2 * node + 1);
  tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
void dfs2(int node) {
  int mxd = query(1, m, 1, m, 1);
  if (mxd <= d) cnt++;
  vis[node] = true;
  int l, r, nd;
  for (int i = 0; i < (v[node].size()); i++) {
    if (vis[v[node][i]]) continue;
    nd = v[node][i];
    it = mp.lower_bound(dtm[nd].first);
    if (it == mp.end())
      l = m + 1;
    else
      l = it->second;
    it = mp.upper_bound(dtm[nd].second);
    if (it != mp.begin()) {
      it--;
      r = it->second;
    } else {
      r = 0;
    }
    if (r < l || l > m || r < 1) {
      update(1, m, 1, m, 1, 1);
      dfs2(nd);
      update(1, m, 1, m, -1, 1);
    } else {
      update(1, l - 1, 1, m, 1, 1);
      update(r + 1, m, 1, m, 1, 1);
      update(l, r, 1, m, -1, 1);
      dfs2(nd);
      update(1, l - 1, 1, m, -1, 1);
      update(r + 1, m, 1, m, -1, 1);
      update(l, r, 1, m, 1, 1);
    }
  }
}
int main() {
  int n, i, a, b;
  scanf("%d%d%d", &n, &m, &d);
  for ((i) = 0; (i) < (m); (i)++) {
    scanf("%d", &sp[i]);
    sp[i]--;
  }
  for ((i) = 0; (i) < (n - 1); (i)++) {
    scanf("%d%d", &a, &b);
    v[a - 1].push_back(b - 1);
    v[b - 1].push_back(a - 1);
  }
  dfs(0, 0);
  for ((i) = 0; (i) < (n); (i)++) {
    mp2[dtm[i].first] = i;
  }
  for ((i) = 0; (i) < (m); (i)++) {
    mp[dtm[sp[i]].first] = 0;
  }
  for (it = mp.begin(), i = 1; it != mp.end(); it++, i++) {
    it->second = i;
    arr[i - 1] = dep[mp2[it->first]];
  }
  build(1, m, 1);
  memset(vis, 0, sizeof(vis));
  dfs2(0);
  cout << cnt << endl;
  return 0;
}
