#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,1,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
typedef long long ll;
inline ll read() {
ll x=0,f=1;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c==‘-‘) f=-1;
for(;isdigit(c);c=Getchar()) x=x*10+c-‘0‘;
return x*f;
}
const int maxn=20010;
const int maxm=200010;
struct Set {
ll A[60];
void insert(ll val) {
dwn(i,59,0) if(val>>i&1) {
if(!A[i]) {A[i]=val;break;}
val^=A[i];
}
}
ll query() {
ll res=0;
dwn(i,59,0) res=max(res,res^A[i]);
return res;
}
}A[maxn];
int n,m,first[maxn],next[maxn<<1],to[maxn<<1],e;
ll val[maxn],ans[maxm];
void AddEdge(int u,int v) {
to[++e]=v;next[e]=first[u];first[u]=e;
to[++e]=u;next[e]=first[v];first[v]=e;
}
int qx[maxm],qy[maxm],Q[maxm];
int vis[maxn],F[maxn],s[maxn],root,size;
void getroot(int x,int fa) {
int maxs=0;s[x]=1;
ren if(to[i]!=fa&&!vis[to[i]]) getroot(to[i],x),s[x]+=s[to[i]],maxs=max(maxs,s[to[i]]);
F[x]=max(maxs,size-s[x]);
if(F[root]>F[x]) root=x;
}
int bel[maxn],cur;
void dfs(int x,int fa) {
A[x]=A[fa];A[x].insert(val[x]);bel[x]=cur;
ren if(to[i]!=fa&&!vis[to[i]]) dfs(to[i],x);
}
int cmp(int x,int y) {return bel[qx[x]]<bel[qx[y]];}
int ql[maxn],qr[maxn];
void solve(int x,int f,int h) {
if(f>h) return;
vis[x]=1;bel[x]=0;A[x]=A[0];A[x].insert(val[x]);
ren if(!vis[to[i]]) cur++,dfs(to[i],x);
int N=f-1;
rep(i,f,h) if(bel[qx[Q[i]]]!=bel[qy[Q[i]]]||(qx[Q[i]]==x)) {
Set tmp;tmp=A[qx[Q[i]]];
dwn(j,59,0) if(A[qy[Q[i]]].A[j]) tmp.insert(A[qy[Q[i]]].A[j]);
ans[Q[i]]=tmp.query();
} else Q[++N]=Q[i];h=N;
if(f>h) return;
sort(Q+f,Q+h+1,cmp);
ren if(!vis[to[i]]) {
while(f<=h&&bel[qx[Q[f]]]<bel[to[i]]) f++;ql[to[i]]=f;
while(f<=h&&bel[qx[Q[f]]]<=bel[to[i]]) f++;qr[to[i]]=--f;
}
ren if(!vis[to[i]]) {
F[0]=size=s[to[i]];getroot(to[i],root=0);
solve(root,ql[to[i]],qr[to[i]]);
}
}
int main() {
n=read();m=read();
rep(i,1,n) val[i]=read();
rep(i,2,n) AddEdge(read(),read());
rep(i,1,m) Q[i]=i,qx[i]=read(),qy[i]=read();
F[0]=size=n;getroot(1,root=0);solve(root,1,m);
rep(i,1,m) printf("%lld\n",ans[i]);
return 0;
}