#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,tot,lca[N][30],deep[N],c[N],rt[N];
long long a[N],b[N],trk[N];
vector<int> to[N];
struct Segment_Tree{
int cnt,ls[N*30],rs[N*30],val[N*30];
void build(int &pos,int l,int r)
{
pos=++cnt;
if(l==r) return;
int mid=(l+r)>>1;
build(ls[pos],l,mid),build(rs[pos],mid+1,r);
}
void insert(int &pos,int prev,int l,int r,int x)
{
pos=++cnt;
val[pos]=val[prev]+1,rs[pos]=rs[prev],ls[pos]=ls[prev];
if(l==r) return ;
int mid=(l+r)>>1;
if(x<=mid) insert(ls[pos],ls[prev],l,mid,x);
else insert(rs[pos],rs[prev],mid+1,r,x);
}
void dfs(int pos,int fa)
{
insert(rt[pos],rt[fa],1,tot,c[pos]);
lca[pos][0]=fa;
deep[pos]=deep[fa]+1;
for(int i=log2(n)+1;i>=1;i--) lca[pos][i]=lca[lca[pos][i-1]][i-1];
for(int i=0;i<to[pos].size();i++)
{
int v=to[pos][i];
if(v==fa) continue;
dfs(v,pos);
}
}
int find(int x,int y)
{
if(deep[x]<deep[y]) swap(x,y);
for(int i=log2(n)+1;i>=0;i--)
if(deep[lca[x][i]]>=deep[y]) x=lca[x][i];
if(x==y) return x;
for(int i=log2(n)+1;i>=0;i--)
if(lca[x][i]!=lca[y][i]) x=lca[x][i],y=lca[y][i];
return lca[x][0];
}
int query(int pos1,int pos2,int prev1,int prev2,int l,int r,int k)
{
if(l==r) return l;
int mid=(l+r)>>1;
int wl=val[ls[pos1]]+val[ls[pos2]]-val[ls[prev1]]-val[ls[prev2]];
if(k<=wl) return query(ls[pos1],ls[pos2],ls[prev1],ls[prev2],l,mid,k);
else return query(rs[pos1],rs[pos2],rs[prev1],rs[prev2],mid+1,r,k-wl);
}
}T;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+n+1);
tot=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)
{
c[i]=lower_bound(b+1,b+1+tot,a[i])-b;
trk[c[i]]=a[i];
}
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
to[u].push_back(v);
to[v].push_back(u);
}
T.build(rt[0],1,tot);
T.dfs(1,0);
int last=0;
while(m--)
{
int x,y,g,w;
cin>>x>>y>>w;
x=(x^last);
g=T.find(x,y);
last=T.query(rt[x],rt[y],rt[g],rt[lca[g][0]],1,tot,w);
cout<<trk[last]<<"\n";
last=trk[last];
}
return 0;
}