using namespace std;
const int INF=0x3f3f3f3f;
const int inf=0x3f3f3f3f;
const long long LINF=0x3f3f3f3f3f3f3f3f;
#define pb(i) push_back(i)
#define fup(a,b,c,d) for(int a=(b);a<=(c);a+=(d))
using vi = vector<int>;
using vvi = vector<vector<int>>;
using mi = map<int,int>;
using namespace std;
bitset<40010>bit[305][305];
bitset<40010>B;
struct Link_Cut_Tree{
struct node{
int fa,ch[2],size=1,virtual_size,color,sum,lazy,val;
};vector<node>tree;
Link_Cut_Tree(){}
~Link_Cut_Tree(){}
Link_Cut_Tree(int n){
tree=vector<node>(n+10);
}
bool ident(int x,int f){
return tree[f].ch[1]==x;
};
bool isroot(int x){
return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;
};
void reverse(int x){
tree[x].lazy^=1;
swap(tree[x].ch[0],tree[x].ch[1]);
};
void pushup(int x){
tree[x].sum=tree[x].val;
if(tree[x].ch[0])tree[x].sum|=tree[tree[x].ch[0]].sum;
if(tree[x].ch[1])tree[x].sum|=tree[tree[x].ch[1]].sum;
};
void pushdown(int x){
if(tree[x].lazy){
if(tree[x].ch[0]){
reverse(tree[x].ch[0]);
}
if(tree[x].ch[1]){
reverse(tree[x].ch[1]);
}
tree[x].lazy^=1;
}
};
void pushall(int x){
if(!isroot(x)){
pushall(tree[x].fa);
}
pushdown(x);
};
void connect(int x,int f,int k){
tree[f].ch[k]=x;
tree[x].fa=f;
};
void rotate(int x){
int f=tree[x].fa,ff=tree[f].fa,fk=ident(x,f),ffk=ident(f,ff);
connect(tree[x].ch[fk^1],f,fk);
tree[x].fa=ff;
if(!isroot(f)){
tree[ff].ch[ffk]=x;
}
connect(f,x,fk^1);
pushup(f);
pushup(x);
};
void splay(int x){
pushall(x);
while(!isroot(x)){
int f=tree[x].fa,ff=tree[f].fa;
if(!isroot(f)){
ident(x,f)^ident(f,ff)?rotate(x):rotate(f);
}
rotate(x);
}
};
void access(int x){
for(int y=0;x;x=tree[y=x].fa){
splay(x);
tree[x].ch[1]=y;
pushup(x);
}
};
void changeroot(int x){
access(x);
splay(x);
reverse(x);
};
int findroot(int x){
access(x);
splay(x);
int root=x;
while(tree[root].ch[0]){
pushdown(root);
root=tree[root].ch[0];
}
splay(root);
return root;
};
void link(int x,int y){
changeroot(x);
changeroot(y);
if(findroot(y)==x)return;
tree[x].fa=y;
};
bool split(int x,int y){
if(findroot(x)!=findroot(y))return false;
changeroot(x);
access(y);
splay(y);
return true;
}
void changeval(int x,int val){
changeroot(x);
tree[x].val=val;
tree[x].sum=val;
};
int getans(int x,int y){
int cnt=0;
B.reset();
auto dfs=[&](auto self,int u)->void{
if(!u)return;
B.set(tree[u].color);
self(self,tree[u].ch[0]);
self(self,tree[u].ch[1]);
};
auto get=[&](auto self,int u)->int{
if(tree[u].ch[1]&&tree[tree[u].ch[1]].sum)return self(self,tree[u].ch[1]);
if(tree[u].val)return u;
return self(self,tree[u].ch[0]);
};
split(x,y);
if(tree[y].sum){
int X=get(get,y);
split(X,y);
dfs(dfs,y);
split(y,x);
int Y=get(get,x);
split(Y,x);
dfs(dfs,x);
B|=bit[tree[X].val][tree[Y].val];
}else dfs(dfs,y);
splay(x);
return (int)B.count();
};
};
void solve(){
mt19937_64 Rand(random_device{}());
int n,q;cin>>n>>q;
vi val(n+10);
mi id;
fup(i,1,n,1)cin>>val[i];
fup(i,1,n,1)id[val[i]]++;
int idex=0;
for(auto &[x,y]:id)y=++idex;
fup(i,1,n,1)val[i]=id[val[i]];
Link_Cut_Tree lct(n+10);
fup(i,1,n,1)lct.tree[i].color=val[i];
vvi adj(n+10);
fup(i,2,n,1){
int u,v;cin>>u>>v;
lct.link(u,v);
adj[u].pb(v);
adj[v].pb(u);
}
int M=min(n,(int)sqrt(n+1)+1);
vi flag(n+10);
iota(flag.begin(),flag.end(),0);
shuffle(flag.begin()+1,flag.begin()+1+n,Rand);
fup(i,1,M,1){
lct.tree[flag[i]].val=i;
lct.tree[flag[i]].sum=i;
}
vi cnt(n+10);
fup(i,1,n,1){
if(lct.tree[i].val){
auto init=[&](auto self,int u,int f)->void{
cnt[lct.tree[u].color]++;
B.set(lct.tree[u].color);
if(lct.tree[u].val){
bit[lct.tree[u].val][lct.tree[i].val]=B;
bit[lct.tree[i].val][lct.tree[u].val]=B;
}
for(auto &v:adj[u]){
if(v==f)continue;
self(self,v,u);
}
if(!--cnt[lct.tree[u].color])B.reset(lct.tree[u].color);
};
init(init,i,0);
}
}
int lastans=0;
while(q--){
int x,y;cin>>x>>y;
x^=lastans;
cout<<(lastans=lct.getans(x,y))<<'\n';
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
while(T--){
solve();
}
}
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int inf=0x3f3f3f3f;
const long long LINF=0x3f3f3f3f3f3f3f3f;
#define pb(i) push_back(i)
#define fup(a,b,c,d) for(int a=(b);a<=(c);a+=(d))
using vi = vector<int>;
using vvi = vector<vector<int>>;
using mi = map<int,int>;
using namespace std;
bitset<40010>bit[305][305];
bitset<40010>B;
struct Link_Cut_Tree{
struct node{
int fa,ch[2],size=1,virtual_size,color,sum,lazy,val;
};vector<node>tree;
Link_Cut_Tree(){}
~Link_Cut_Tree(){}
Link_Cut_Tree(int n){
tree=vector<node>(n+10);
}
bool ident(int x,int f){
return tree[f].ch[1]==x;
};
bool isroot(int x){
return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;
};
void reverse(int x){
tree[x].lazy^=1;
swap(tree[x].ch[0],tree[x].ch[1]);
};
void pushup(int x){
tree[x].sum=tree[x].val;
if(tree[x].ch[0])tree[x].sum|=tree[tree[x].ch[0]].sum;
if(tree[x].ch[1])tree[x].sum|=tree[tree[x].ch[1]].sum;
};
void pushdown(int x){
if(tree[x].lazy){
if(tree[x].ch[0]){
reverse(tree[x].ch[0]);
}
if(tree[x].ch[1]){
reverse(tree[x].ch[1]);
}
tree[x].lazy^=1;
}
};
void pushall(int x){
if(!isroot(x)){
pushall(tree[x].fa);
}
pushdown(x);
};
void connect(int x,int f,int k){
tree[f].ch[k]=x;
tree[x].fa=f;
};
void rotate(int x){
int f=tree[x].fa,ff=tree[f].fa,fk=ident(x,f),ffk=ident(f,ff);
connect(tree[x].ch[fk^1],f,fk);
tree[x].fa=ff;
if(!isroot(f)){
tree[ff].ch[ffk]=x;
}
connect(f,x,fk^1);
pushup(f);
pushup(x);
};
void splay(int x){
pushall(x);
while(!isroot(x)){
int f=tree[x].fa,ff=tree[f].fa;
if(!isroot(f)){
ident(x,f)^ident(f,ff)?rotate(x):rotate(f);
}
rotate(x);
}
};
void access(int x){
for(int y=0;x;x=tree[y=x].fa){
splay(x);
tree[x].ch[1]=y;
pushup(x);
}
};
void changeroot(int x){
access(x);
splay(x);
reverse(x);
};
int findroot(int x){
access(x);
splay(x);
int root=x;
while(tree[root].ch[0]){
pushdown(root);
root=tree[root].ch[0];
}
splay(root);
return root;
};
void link(int x,int y){
changeroot(x);
changeroot(y);
if(findroot(y)==x)return;
tree[x].fa=y;
};
bool split(int x,int y){
if(findroot(x)!=findroot(y))return false;
changeroot(x);
access(y);
splay(y);
return true;
}
void changeval(int x,int val){
changeroot(x);
tree[x].val=val;
tree[x].sum=val;
};
int getans(int x,int y){
int cnt=0;
B.reset();
auto dfs=[&](auto self,int u)->void{
if(!u)return;
B.set(tree[u].color);
self(self,tree[u].ch[0]);
self(self,tree[u].ch[1]);
};
auto get=[&](auto self,int u)->int{
if(tree[u].ch[1]&&tree[tree[u].ch[1]].sum)return self(self,tree[u].ch[1]);
if(tree[u].val)return u;
return self(self,tree[u].ch[0]);
};
split(x,y);
if(tree[y].sum){
int X=get(get,y);
split(X,y);
dfs(dfs,y);
split(y,x);
int Y=get(get,x);
split(Y,x);
dfs(dfs,x);
B|=bit[tree[X].val][tree[Y].val];
}else dfs(dfs,y);
splay(x);
return (int)B.count();
};
};
void solve(){
mt19937_64 Rand(random_device{}());
int n,q;cin>>n>>q;
vi val(n+10);
mi id;
fup(i,1,n,1)cin>>val[i];
fup(i,1,n,1)id[val[i]]++;
int idex=0;
for(auto &[x,y]:id)y=++idex;
fup(i,1,n,1)val[i]=id[val[i]];
Link_Cut_Tree lct(n+10);
fup(i,1,n,1)lct.tree[i].color=val[i];
vvi adj(n+10);
fup(i,2,n,1){
int u,v;cin>>u>>v;
lct.link(u,v);
adj[u].pb(v);
adj[v].pb(u);
}
int M=min(n,(int)sqrt(n+1)+1);
vi flag(n+10);
iota(flag.begin(),flag.end(),0);
shuffle(flag.begin()+1,flag.begin()+1+n,Rand);
fup(i,1,M,1){
lct.tree[flag[i]].val=i;
lct.tree[flag[i]].sum=i;
}
vi cnt(n+10);
fup(i,1,n,1){
if(lct.tree[i].val){
auto init=[&](auto self,int u,int f)->void{
cnt[lct.tree[u].color]++;
B.set(lct.tree[u].color);
if(lct.tree[u].val){
bit[lct.tree[u].val][lct.tree[i].val]=B;
bit[lct.tree[i].val][lct.tree[u].val]=B;
}
for(auto &v:adj[u]){
if(v==f)continue;
self(self,v,u);
}
if(!--cnt[lct.tree[u].color])B.reset(lct.tree[u].color);
};
init(init,i,0);
}
}
int lastans=0;
while(q--){
int x,y;cin>>x>>y;
x^=lastans;
cout<<(lastans=lct.getans(x,y))<<'\n';
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
while(T--){
solve();
}
}