#include <bits/stdc++.h>
using namespace std;
int blocksize;
int msmo7;
struct query {
  int start, en, idxofquery, blockidx, mincolor;
  query() {}
  query(int l, int r, int i, int adeh) {
    start = l;
    en = r;
    idxofquery = i;
    blockidx = l / blocksize;
    mincolor = adeh;
  }
  bool operator<(const query& q) const {
    if (start / blocksize != q.start / blocksize)
      return start / blocksize < q.start / blocksize;
    else
      return en < q.en;
  }
};
query queries[100005];
vector<int> arr[100005];
int subtree[100005];
int idxinorder[100005];
int treearray[100005];
int color[100005];
int ansforquery;
int answers[100005];
int bit[100010];
int freq[100005];
const int maxn = 1e5 + 5;
void update(int idx, int val) {
  for (; idx <= maxn; idx += (idx & -idx)) bit[idx] += val;
}
int getsum(int idx) {
  int sum = 0;
  for (; idx; idx -= (idx & -idx)) sum += bit[idx];
  return sum;
}
int nid = 0;
void dfs(int s, int parent) {
  subtree[s] = 1;
  treearray[nid++] = s;
  idxinorder[s] = nid - 1;
  for (int i = 0; i < arr[s].size(); ++i) {
    int to = arr[s][i];
    if (to != parent) {
      dfs(to, s);
      subtree[s] += subtree[to];
    }
  }
}
void add(int valueofpos) {
  update(maxn - freq[color[valueofpos]]++, -1);
  update(maxn - freq[color[valueofpos]], 1);
}
void rem(int valueofpos) {
  update(maxn - freq[color[valueofpos]]--, -1);
  update(maxn - freq[color[valueofpos]], 1);
}
int main() {
  int n, m;
  scanf("%d", &n);
  scanf("%d", &m);
  for (int i = 1; i <= n; ++i) scanf("%d", &color[i]);
  int u, v;
  for (int i = 1; i < n; ++i) {
    scanf("%d", &u);
    scanf("%d", &v);
    arr[u].push_back(v);
    arr[v].push_back(u);
  }
  dfs(1, -1);
  blocksize = sqrt(n);
  int k;
  for (int i = 0; i < m; ++i) {
    scanf("%d", &v);
    scanf("%d", &k);
    queries[i].start = idxinorder[v];
    queries[i].en = queries[i].start + subtree[v] - 1;
    queries[i].idxofquery = i;
    queries[i].mincolor = k;
  }
  sort(queries, queries + m);
  int curl = 0;
  int curr = -1;
  for (int i = 0; i < m; ++i) {
    query& qu = queries[i];
    while (curl > qu.start) add(treearray[--curl]);
    while (curr < qu.en) add(treearray[++curr]);
    while (curl < qu.start) rem(treearray[curl++]);
    while (curr > qu.en) rem(treearray[curr--]);
    answers[qu.idxofquery] = getsum(maxn - qu.mincolor);
  }
  for (int i = 0; i < m; ++i) printf("%d\n", answers[i]);
  return 0;
}
