#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;   }