#include <bits/stdc++.h>
using namespace std;
int N, M, D;
const int NMax = 100005;
vector<int> G[NMax];
int Arb[4 * NMax], Lazy[4 * NMax];
int Point[NMax], Left[NMax], Right[NMax];
bool V[NMax];
int Level[NMax], cnt;
const int INF = -10000000;
int Max[NMax], Max2[NMax];
void Read() {
  scanf("%d%d%d", &N, &M, &D);
  for (int i = 1; i <= M; i++) {
    scanf("%d", &Point[i]);
    V[Point[i]] = 1;
  }
  for (int i = 1; i < N; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    G[x].push_back(y);
    G[y].push_back(x);
  }
}
void DFS(int node, int father) {
  Left[node] = ++cnt;
  Level[node] = Level[father] + 1;
  for (int i = 0; i < G[node].size(); i++) {
    int neighb = G[node][i];
    if (neighb == father) continue;
    DFS(neighb, node);
  }
  Right[node] = cnt;
}
void Update(int K, int L, int R, int x, int y, int val) {
  if (Lazy[K] != INF) {
    Arb[K] = max(Arb[K], Lazy[K]);
    if (L != R) {
      Lazy[K * 2] = max(Lazy[2 * K], Lazy[K]);
      Lazy[K * 2 + 1] = max(Lazy[K], Lazy[2 * K + 1]);
    }
    Lazy[K] = INF;
  }
  if (L > R || L > y || R < x) return;
  if (L >= x && R <= y) {
    Arb[K] = max(Arb[K], val);
    if (L != R) {
      Lazy[K * 2] = max(Lazy[K * 2], val);
      Lazy[K * 2 + 1] = max(Lazy[K * 2 + 1], val);
    }
    return;
  }
  Update(K * 2, L, (L + R) / 2, x, y, val);
  Update(K * 2 + 1, (L + R) / 2 + 1, R, x, y, val);
  Arb[K] = max(Arb[K * 2], Arb[K * 2 + 1]);
}
int Query(int K, int L, int R, int x, int y) {
  if (Lazy[K] != INF) {
    Arb[K] = max(Arb[K], Lazy[K]);
    if (L != R) {
      Lazy[K * 2] = max(Lazy[2 * K], Lazy[K]);
      Lazy[K * 2 + 1] = max(Lazy[K], Lazy[2 * K + 1]);
    }
    Lazy[K] = INF;
  }
  if (L > R || L > y || R < x) return INF;
  if (L >= x && R <= y) return Arb[K];
  int a = Query(K * 2, L, (L + R) / 2, x, y);
  int b = Query(K * 2 + 1, (L + R) / 2 + 1, R, x, y);
  return max(a, b);
}
void Upd(int node, int val) {
  if (Max[node] < val) {
    Max2[node] = Max[node];
    Max[node] = val;
  } else if (Max2[node] < val)
    Max2[node] = val;
}
void DFS2(int node, int father) {
  for (int i = 0; i < G[node].size(); i++) {
    int neighb = G[node][i];
    if (neighb == father) continue;
    DFS2(neighb, node);
    Upd(node, Max[neighb]);
  }
  if (V[node] == 1) Upd(node, Level[node]);
  for (int i = 0; i < G[node].size(); i++) {
    int neighb = G[node][i];
    if (neighb == father) continue;
    if (Max[node] == Max[neighb]) {
      Update(1, 1, N, Left[neighb], Right[neighb],
             Max2[node] - 2 * Level[node]);
    } else {
      Update(1, 1, N, Left[neighb], Right[neighb], Max[node] - 2 * Level[node]);
    }
  }
  Update(1, 1, N, Left[node], Left[node], Max[node] - 2 * Level[node]);
}
void Solve() {
  int cnt = 0;
  for (int i = 1; i <= N; i++) {
    int x = Query(1, 1, N, Left[i], Left[i]);
    if (x + Level[i] > D) ++cnt;
  }
  printf("%d\n", N - cnt);
}
int main() {
  Read();
  for (int i = 1; i <= 4 * N; i++) Arb[i] = Lazy[i] = INF;
  for (int i = 1; i <= N; i++) Max[i] = Max2[i] = INF;
  DFS(1, 0);
  DFS2(1, 0);
  Solve();
  return 0;
}
