#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 30;
int len, cnt = 0, cnt2 = 0, in[maxn], out[maxn], Next[maxn];
int c[maxn], nc[maxn], f[maxn] = {0}, sum[maxn] = {0}, ans[maxn];
struct node {
  int v, next;
} edge[maxn << 1];
struct query {
  int l, r, block, id, k;
  query() {}
  query(int l, int r, int k, int id) : l(l), r(r), k(k), id(id) {
    block = (l - 1) / len + 1;
  }
  bool operator<(const query b) const {
    if (block == b.block) return r < b.r;
    return block < b.block;
  }
} q[maxn];
void add_edge(int u, int v) {
  edge[cnt] = {v, Next[u]};
  Next[u] = cnt++;
  edge[cnt] = {u, Next[v]};
  Next[v] = cnt++;
}
void dfs(int pre, int cur) {
  in[cur] = ++cnt2;
  nc[cnt2] = c[cur];
  for (int i = Next[cur]; i != -1; i = edge[i].next) {
    int v = edge[i].v;
    if (v == pre) continue;
    dfs(cur, v);
  }
  out[cur] = cnt2;
}
int main() {
  int n, m;
  memset(Next, -1, sizeof(Next));
  scanf("%d%d", &n, &m);
  len = sqrt(n * 1.0);
  for (int i = 1; i <= n; ++i) scanf("%d", &c[i]);
  for (int i = 1; i < n; ++i) {
    int s, e;
    scanf("%d%d", &s, &e);
    add_edge(s, e);
  }
  dfs(0, 1);
  for (int i = 1; i <= m; ++i) {
    int s, e;
    scanf("%d%d", &s, &e);
    q[i] = query(in[s], out[s], e, i);
  }
  sort(q + 1, q + 1 + m);
  int L = 1, R = 0;
  for (int i = 1; i <= m; ++i) {
    query &t = q[i];
    while (R < t.r) {
      ++f[nc[++R]];
      ++sum[f[nc[R]]];
    }
    while (L > t.l) {
      ++f[nc[--L]];
      ++sum[f[nc[L]]];
    }
    while (R > t.r) {
      --sum[f[nc[R]]];
      --f[nc[R--]];
    }
    while (L < t.l) {
      --sum[f[nc[L]]];
      --f[nc[L++]];
    }
    ans[t.id] = sum[t.k];
  }
  for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
  return 0;
}
