#include <bits/stdc++.h>
#define int long long
using namespace std;
namespace IO
{
char buff[1<<21],*p1=buff,*p2=buff;
char getch(){return p1==p2&&(p2=((p1=buff)+fread(buff,1,1<<21,stdin)),p1==p2)?EOF:*p1++;}
template<typename T>
void read(T &x){char ch=getch();int fl=1;x=0;while(ch>'9'||ch<'0'){if(ch=='-')fl=-1;ch=getch();}while(ch<='9'&&ch>='0'){x=x*10+ch-48;ch=getch();}x*=fl;}
template<typename T,typename ...Args>
void read(T &x,Args& ...args){read(x);read(args...);}
char obuf[1<<21],*p3=obuf;
void putch(char ch) {if(p3-obuf<(1<<21))*p3++=ch;else fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=ch;}
char ch[100];
template<typename T>
void write(T x) {if(!x)return putch('0');if(x<0)putch('-'),x*=-1;int top=0;while(x)ch[++top]=x%10+48,x/=10;while(top)putch(ch[top]),top--;}
template<typename T,typename ...Args>
void write(T x,Args ...args) {write(x);write(args...);}
void put(string s){for(int i=0;i<s.size();i++)putch(s[i]);}
void flush(){fwrite(obuf,p3-obuf,1,stdout);}
}
using namespace IO;
int n,q;
int a[20005];
struct node{int nex,to;} edge[20005<<1];
int head[20005],tot;
inline void add(int x,int y){edge[++tot]=(node){head[x],y};head[x]=tot;}
struct Elia
{
int p[64];
inline bool insert(int x)
{
for (int i = 60; ~i; i--)
if (x&(1<<i))
{
if (!p[i]){p[i]=x;return true;}
else x ^= p[i];
}
return false;
}
inline int query(int res=0){for(int i=60;~i;i--)res=(res^p[i])>res?(res^p[i]):res;return res;}
};
inline Elia merge(Elia a,Elia b){for(int i=60;~i;i--)a.insert(b.p[i]);return a;}
namespace Asuka
{
int f[20005],dep[20005],siz[20005],son[20005],top[20005];
int rk[20005],dfn[20005];
void dfs1(int x,int fa)
{
f[x] = fa; dep[x] = dep[fa]+1;
siz[x] = 1;
for (int i = head[x]; i; i = edge[i].nex)
{
int v = edge[i].to;
if (v == fa) continue;
dfs1(v,x);
siz[x] += siz[v];
if (siz[v] > siz[son[x]])
son[x] = v;
}
}
void dfs2(int x,int tp)
{
dfn[++tot] = x; rk[x] = tot;
top[x] = tp;
if (son[x]) dfs2(son[x],tp);
for (int i = head[x]; i; i = edge[i].nex)
{
int v = edge[i].to;
if (v == f[x] || v == son[x])
continue;
dfs2(v,v);
}
}
void init(){tot=0;dfs1(1,0);dfs2(1,1);}
}
using namespace Asuka;
namespace Emiya
{
Elia pixiv[20005][18];
int lg[20005];
void init()
{
lg[0] = -1;
for (int i = 1; i <= n; i++)
lg[i] = lg[i>>1]+1,pixiv[i][0].insert(a[rk[i]]);
for (int j = 1; j <= lg[n]; j++)
for (int i = 1; i+(1<<j)-1 <= n; i++)
pixiv[i][j] = merge(pixiv[i][j-1],pixiv[i+(1<<(j-1))][j-1]);
}
inline Elia Merge(int l,int r){int len=lg[r-l+1];return merge(pixiv[l][len],pixiv[r-(1<<len)+1][len]);}
}
inline int search(int x,int y)
{
Elia res;
for (int i = 0; i <= 60; i++) res.p[i] = 0;
while (top[x] != top[y])
{
if (dep[top[x]] < dep[top[y]])
x^=y,y^=x,x^=y;
res = merge(res,Emiya::Merge(dfn[top[x]],dfn[x]));
x = f[top[x]];
}
if (dfn[x] > dfn[y]) x^=y,y^=x,x^=y;
return merge(res,Emiya::Merge(dfn[x],dfn[y])).query();
}
signed main()
{
read(n,q);
for (int i = 1; i <= n; i++)
read(a[i]);
for (int i = 1,u,v; i < n; i++)
read(u,v),add(u,v),add(v,u);
Asuka::init(); Emiya::init();
int x,y;
while (q--)
{
read(x,y);
if (x == y){write(max(a[x],0ll));putch('\n');continue;}
write(search(x,y)); putch('\n');
}
flush();
return 0;
}