```go
package main
import (
"bufio"
"os"
"strconv"
)
func main() {
// Configure fast I/O
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
nextInt := func() int {
scanner.Scan()
val, _ := strconv.Atoi(scanner.Text())
return val
}
n := nextInt()
m := nextInt()
d := nextInt()
isAffected := make([]bool, n+1)
for i := 0; i < m; i++ {
isAffected[nextInt()] = true
}
adj := make([][]int, n+1)
for i := 0; i < n-1; i++ {
u := nextInt()
v := nextInt()
adj[u] = append(adj[u], v)
adj[v] = append(adj[v], u)
}
// down[u] stores the maximum distance to an affected node in the subtree of u
down := make([]int, n+1)
// up[u] stores the maximum distance to an affected node outside the subtree of u
up := make([]int, n+1)
for i := 0; i <= n; i++ {
down[i] = -1
up[i] = -1
}
// First DFS to compute down[] values (post-order)
var dfs1 func(int, int)
dfs1 = func(u, p int) {
if isAffected[u] {
down[u] = 0
}
for _, v := range adj[u] {
if v == p {
continue
}
dfs1(v, u)
if down[v] != -1 {
if down[v]+1 > down[u] {
down[u] = down[v] + 1
}
}
}
}
// Second DFS to compute up[] values (pre-order)
var dfs2 func(int, int)
dfs2 = func(u, p int) {
// Calculate two largest distances from u downwards (including self or children)
m1, m2 := -1, -1
// Consider u itself
if isAffected[u] {
m1 = 0
}
// Consider children
for _, v := range adj[u] {
if v == p {
continue
}
val := -1
if down[v] != -1 {
val = down[v] + 1
}
if val > m1 {
m2 = m1
m1 = val
} else if val > m2 {
m2 = val
}
}
// Propagate to children
for _, v := range adj[u] {
if v == p {
continue
}
// Find longest path starting from u excluding the branch to v
longest := m1
valV := -1
if down[v] != -1 {
valV = down[v] + 1
}
if valV == m1 {
longest = m2
}
// Calculate up[v]
best := -1
// Path going up through parent of u
if up[u] != -1 {
best = up[u] + 1
}
// Path going from u to other children or u itself
if longest != -1 {
if longest+1 > best {
best = longest + 1
}
}
up[v] = best
dfs2(v, u)
}
}
dfs1(1, 0)
dfs2(1, 0)
count := 0
for i := 1; i <= n; i++ {
maxDist := down[i]
if up[i] > maxDist {
maxDist = up[i]
}
// maxDist is the distance to the farthest affected node from i
if maxDist != -1 && maxDist <= d {
count++
}
}
os.Stdout.WriteString(strconv.Itoa(count) + "\n")
}
```