#include<bits/stdc++.h>
using namespace std;
int col[1000005], ans[1000005];
const int N = 2e5 + 5;
vector<int> v[100005];
vector<pair<int, int> > ask[100005];
int cnt[1000005];
bool vis[1000005];
struct node{
int dep, size, son;
}Node[1000005];
struct point{
int l, r, sum;
}seg[4000005];
int heavy, tot, root, type, n, m;
void dfs(int x, int fa){
Node[x].dep = Node[fa].dep + 1, Node[x].size = 1;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(to == fa) continue;
dfs(to, x); Node[x].size += Node[to].size;
if(Node[Node[x].son].size < Node[to].size) Node[x].son = to;
}
}
void pushup(int cur) {
seg[cur].sum = seg[seg[cur].l].sum + seg[seg[cur].r].sum;
}
void insert(int &cur, int l, int r, int x, int val) {
if(!cur) cur = ++tot;
if(l == r) { seg[cur].sum += val; return; }
int mid = (l + r) >> 1;
if(x <= mid) insert(seg[cur].l, l, mid, x, val);
else insert(seg[cur].r, mid + 1, r, x, val);
pushup(cur);
}
int Ask(int cur, int l, int r, int L, int R){
if(!cur) return 0;
if(l >= L and r <= R) return seg[cur].sum;
int mid = (l + r) >> 1, ans = 0;
if(L <= mid) ans += Ask(seg[cur].l, l, mid, L, R);
if(R > mid) ans += Ask(seg[cur].r, mid + 1, r, L, R);
return ans;
}
void update(int x, int fa, int val){
cnt[col[x]] += val; //cout << Node[x].dep << "\n";
insert(root, 1, N, cnt[col[x]] - val, -1);
insert(root, 1, N, cnt[col[x]], 1);
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(to == heavy or to == fa) continue;
update(to, x, val);
}
}
void get_ans(int x){
// cout << x << ": ";
//for(int i = 1; i <= n; i++) cout << cnt[Node[i].dep] << " ";
//puts("");
for(int i = 0; i < ask[x].size(); i++) {
pair<int, int> to = ask[x][i];
ans[to.first] = Ask(root, 1, N, to.second, N);
}
}
void dfs2(int x, int fa, int flag){
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(to == fa or to == Node[x].son) continue;
dfs2(to, x, 0);
}
if(Node[x].son) dfs2(Node[x].son, x, 1), heavy = Node[x].son;
// for(int i = 1; i <= n; i++) cout << cnt[Node[i].dep] << " ";
update(x, fa, 1);
get_ans(x);
heavy = 0;
if(!flag) update(x, fa, -1);
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> col[i];
if(vis[col[i]] == 0) type++;
vis[col[i]]++;
}
for(int i = 1; i <= n - 1; i++) {
int x, y; cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
for(int i = 1; i <= m; i++) {
int x, y; cin >> x >> y;
ask[x].push_back(make_pair(i, y));
}
dfs(1, 0);
insert(root, 1, N, 0, type);
dfs2(1, 0, 0);
for(int i = 1; i <= m; i++) cout << ans[i] << "\n";
}
思路是dsu on tree再用权值线段树求大于等于k的颜色