```go
package main
import (
"bufio"
"io"
"os"
"strconv"
)
func main() {
buf, _ := io.ReadAll(os.Stdin)
pos := 0
nextInt := func() int {
for pos < len(buf) && buf[pos] <= ' ' {
pos++
}
if pos >= len(buf) {
return 0
}
res := 0
for pos < len(buf) && buf[pos] > ' ' {
res = res*10 + int(buf[pos]-'0')
pos++
}
return res
}
n := nextInt()
m := nextInt()
if n == 0 {
return
}
color := make([]int, n+1)
for i := 1; i <= n; i++ {
color[i] = nextInt()
}
adj := make([][]int, n+1)
for i := 0; i < n-1; i++ {
u, v := nextInt(), nextInt()
adj[u] = append(adj[u], v)
adj[v] = append(adj[v], u)
}
type Query struct {
k, id int
}
queries := make([][]Query, n+1)
for i := 0; i < m; i++ {
v, k := nextInt(), nextInt()
queries[v] = append(queries[v], Query{k, i})
}
ans := make([]int, m)
size := make([]int, n+1)
heavy := make([]int, n+1)
for i := range heavy {
heavy[i] = -1
}
var dfs1 func(int, int)
dfs1 = func(u, p int) {
size[u] = 1
max_sub := 0
for _, v := range adj[u] {
if v != p {
dfs1(v, u)
size[u] += size[v]
if size[v] > max_sub {
max_sub = size[v]
heavy[u] = v
}
}
}
}
dfs1(1, 0)
freq := make([]int, 100005)
at_least := make([]int, 100005)
var add_subtree func(int, int, int)
add_subtree = func(u, p, val int) {
if val == 1 {
freq[color[u]]++
at_least[freq[color[u]]]++
} else {
at_least[freq[color[u]]]--
freq[color[u]]--
}
for _, v := range adj[u] {
if v != p {
add_subtree(v, u, val)
}
}
}
var dfs2 func(int, int, bool)
dfs2 = func(u, p int, keep bool) {
for _, v := range adj[u] {
if v != p && v != heavy[u] {
dfs2(v, u, false)
}
}
if heavy[u] != -1 {
dfs2(heavy[u], u, true)
}
for _, v := range adj[u] {
if v != p && v != heavy[u] {
add_subtree(v, u, 1)
}
}
freq[color[u]]++
at_least[freq[color[u]]]++
for _, q := range queries[u] {
if q.k <= 100000 {
ans[q.id] = at_least[q.k]
}
}
if !keep {
add_subtree(u, p, -1)
}
}
dfs2(1, 0, false)
out := bufio.NewWriter(os.Stdout)
for _, a := range ans {
out.WriteString(strconv.Itoa(a) + "\n")
}
out.Flush()
}
```