RT,1-7WA,8TLE,9-10RE
#include<bits/stdc++.h>
using namespace std;
const int MAX=4e4+100;
const int N=5e2+1;
struct edge{
int to,net;
}ed[MAX<<1],edCT[MAX<<1];
int hed[MAX],cnt;
int hedCT[MAX],cntCT;
int val[MAX];
void add(int x,int y){
ed[++cnt].net=hed[x];
hed[x]=cnt;
ed[cnt].to=y;
}
void addCT(int x,int y){
edCT[++cntCT].net=hedCT[x];
hedCT[x]=cntCT;
edCT[cntCT].to=y;
}
struct Top_Cluster{
//BP:界点 CL:簇 CLP:簇路径 CT:收缩树
int fa[MAX],B,id[MAX],all;
int faCT[MAX],dep[MAX],depCT[MAX],belong[MAX];
int CLP_near[MAX],BP_up[MAX],BP_down[MAX];
vector<int>BP,downP[MAX];
bitset<MAX>app[N];
int tmp_CL[MAX],tmp_cnt;
void add_CL(int u,int d) { // u:up v:down
if(!d) d=tmp_CL[tmp_cnt];
BP.emplace_back(d);
CLP_near[u]=u;
addCT(u,d);addCT(d,u);
for(int p=d;p!=u;p=fa[p]) CLP_near[p]=p;
for(int i=1;i<=tmp_cnt;i++){
int p=tmp_CL[i],ne;
BP_up[p]=u;BP_down[p]=d;
downP[d].emplace_back(p);
for(ne=p;!CLP_near[ne];ne=fa[ne]);
CLP_near[p]=CLP_near[ne];
}
tmp_cnt=0;
}
int stk[MAX],top,top_node[MAX];
int waiting[MAX],BP_rec[MAX];
void CL_part(int u,int mf){
fa[u]=mf;
dep[u]=dep[mf]+1;
stk[++top]=u;
top_node[u]=top;
if(u!=1) waiting[u]=1;
int BN_cnt=0;
for(int i=hed[u];i;i=ed[i].net){
int v=ed[i].to;
if(v==mf) continue;
CL_part(v,u);
waiting[u]+=waiting[v];
BP_rec[u]=(BP_rec[v]?BN_cnt++,BP_rec[v]:BP_rec[u]);
}
if(waiting[u]>B||BN_cnt>1||!mf){
waiting[u]=0;BP_rec[u]=u;
int cnt=0,tmp_down=0,j=top_node[u]+1;
for(int i=hed[u];i;i=ed[i].net){
int v=ed[i].to;
if(v==mf) continue;
if(cnt+waiting[v]>B||(tmp_down&&BP_rec[v])){
for(;j<top_node[v];j++) tmp_CL[++tmp_cnt]=stk[j];
add_CL(u,tmp_down);cnt=0;
tmp_down=0;
}
cnt+=waiting[v];
tmp_down=BP_rec[v]?BP_rec[v]:tmp_down;
}
for(;j<=top;j++) tmp_CL[++tmp_cnt]=stk[j];
add_CL(u,tmp_down);
top=top_node[u];
}
}
void dfs(int now,int mf){
faCT[now]=mf;
depCT[now]=depCT[mf]+1;
id[now]=++all;
for(int i=hedCT[now];i;i=edCT[i].net){
int to=edCT[i].to;
if(to==mf) continue;
dfs(to,now);
app[id[to]][val[now]]=1;
for(int p=to;p!=now;p=fa[p])
app[id[to]][val[p]]=1;
// cout<<to<<" "<<app[id[to]].count()<<"\n";
}
}
bitset<MAX> get(int x,int y){
bitset<MAX>res;
if(dep[x]<dep[y]) swap(x,y);
while(dep[x]>dep[y]){
res[val[x]]=1;
x=fa[x];
}
res[val[y]]=1;
res[val[x]]=1;
if(x==y) return res;
while(x!=y) {
x=fa[x];y=fa[y];
res[val[x]]=1;
res[val[y]]=1;
}
return res;
}
int query(int x,int y){
bitset<MAX>res;
int u=BP_down[x],v=BP_down[y];
if(u==v) return get(x,y).count();
if(depCT[u]<depCT[v]) swap(u,v),swap(x,y);
res|=get(faCT[u],x);u=faCT[u];
while(depCT[u]>depCT[v]) res|=app[id[u]],u=faCT[u];
if(u!=v){
res|=get(faCT[v],y)|app[id[u]];
v=faCT[v];u=faCT[u];
while(u!=v){
res|=app[id[u]]|app[id[v]];
u=faCT[u],v=faCT[v];
}
return res.count();
}
return (res|get(u,y)).count();
}
}TC;
int n,m;
int tot,g[MAX];
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) {
cin>>val[i];
g[++tot]=val[i];
}
for(int i=1;i<n;i++) {
int x,y;
cin>>x>>y;
add(x,y);add(y,x);
}
sort(g+1,g+tot+1);
tot=unique(g+1,g+tot+1)-g-1;
for(int i=1;i<=n;i++){
val[i]=lower_bound(g+1,g+tot+1,val[i])-g;
}
TC.B=sqrt(n);
TC.BP.emplace_back(1);TC.CL_part(1,0);
TC.dfs(1,0);
// for(auto rt1:TC.BP) cout<<rt1<<" ";cout<<"\n";
// cout<<TC.all<<"\n";
int lastans=0;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
u=u^lastans;
cout<<(lastans=TC.query(u,v))<<"\n";
}
return 0;
}