#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cctype>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <ctime>
#include <cassert>
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
inline int read_int(){
int t=0;bool sign=false;char c=getchar();
while(!isdigit(c)){sign|=c=='-';c=getchar();}
while(isdigit(c)){t=(t<<1)+(t<<3)+(c&15);c=getchar();}
return sign?-t:t;
}
inline LL read_LL(){
LL t=0;bool sign=false;char c=getchar();
while(!isdigit(c)){sign|=c=='-';c=getchar();}
while(isdigit(c)){t=(t<<1)+(t<<3)+(c&15);c=getchar();}
return sign?-t:t;
}
inline char get_char(){
char c=getchar();
while(c==' '||c=='\n'||c=='\r')c=getchar();
return c;
}
inline void write(LL x){
register char c[21],len=0;
if(!x)return putchar('0'),void();
if(x<0)x=-x,putchar('-');
while(x)c[++len]=x%10,x/=10;
while(len)putchar(c[len--]+48);
}
inline void space(LL x){write(x),putchar(' ');}
inline void enter(LL x){write(x),putchar('\n');}
const int MAXN=1e5+5,MAXM=40;
struct Edge{
int to,next;
}edge[MAXN<<1];
int head[MAXN],edge_cnt;
void Insert(int u,int v){
edge[++edge_cnt]=Edge{v,head[u]};
head[u]=edge_cnt;
}
namespace LCA{
int d[MAXN],sz[MAXN],f[MAXN];
int h_son[MAXN],mson[MAXN],p[MAXN];
void dfs_1(int u,int fa,int depth){
sz[u]=1;f[u]=fa;d[u]=depth;mson[u]=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa)
continue;
dfs_1(v,u,depth+1);
sz[u]+=sz[v];
if(sz[v]>mson[u])
h_son[u]=v,mson[u]=sz[v];
}
}
void dfs_2(int u,int top){
p[u]=top;
if(mson[u])dfs_2(h_son[u],top);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==f[u]||v==h_son[u])
continue;
dfs_2(v,v);
}
}
void init(int root){dfs_1(root,0,0);dfs_2(root,root);}
int query_lca(int u,int v){
while(p[u]!=p[v]){
if(d[p[u]]<d[p[v]])swap(u,v);
u=f[p[u]];
}
return d[u]<d[v]?u:v;
}
};
struct Node{
int ch[2],val;
}node[MAXN*MAXM];
int node_cnt;
int nodecopy(int k){
node[++node_cnt]=node[k];
return node_cnt;
}
void update(int &k,int p,int lef,int rig,int pos){
k=nodecopy(p);
node[k].val++;
if(lef==rig)
return;
int mid=lef+rig>>1;
if(mid<pos)
update(node[k].ch[1],node[p].ch[1],mid+1,rig,pos);
else
update(node[k].ch[0],node[p].ch[0],lef,mid,pos);
}
int query(int k1,int k2,int k3,int k4,int lef,int rig,int rk){
int mid=lef+rig>>1;
if(lef==rig)
return mid;
int lc1=node[k1].ch[0],lc2=node[k2].ch[0],lc3=node[k3].ch[0],lc4=node[k4].ch[0];
int lz=node[lc1].val+node[lc2].val-node[lc3].val-node[lc4].val;
if(rk>lz)
return query(node[k1].ch[1],node[k2].ch[1],node[k3].ch[1],node[k4].ch[1],mid+1,rig,rk-lz);
else
return query(node[k1].ch[0],node[k2].ch[0],node[k3].ch[0],node[k4].ch[0],lef,mid,rk);
}
int a[MAXN],b[MAXN],root[MAXN],n2;
void dfs(int u,int fa){
update(root[u],root[fa],1,n2,a[u]);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa)continue;
dfs(v,u);
}
}
int query2(int u,int v,int k){
int lca=LCA::query_lca(u,v);
return query(root[u],root[v],root[lca],root[LCA::f[lca]],1,n2,k);
}
int main()
{
int n=read_int(),m=read_int();
_rep(i,1,n)a[i]=b[i]=read_int();
sort(b+1,b+n+1);
n2=unique(b+1,b+n+1)-b;
_rep(i,1,n)a[i]=lower_bound(b+1,b+n2,a[i])-b;
_for(i,1,n){
int u=read_int(),v=read_int();
Insert(u,v);Insert(v,u);
}
LCA::init(1);
dfs(1,0);
int last=0;
while(m--){
int u=read_int()^last,v=read_int();
enter(last=b[query2(u,v,read_int())]);
}
return 0;
}