#include <bits/stdc++.h>
using namespace std;
 
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl "\n"
#define int long long
 
const int N = 111115;
const int LG = log2(N) + 1;
 
int n, q, ct = 0, num = 0;
int a[N], root[N], level[N];
int st[21*N], lc[21*N], rc[21*N];
int tim=0;
int parent[LG][N];
map<int, int> comp, rcomp;
vector<int> g[N];
 
void dfs0(int k, int par, int lvl)
{
	parent[0][k] = par;
	level[k] = lvl;
	for(auto it:g[k])
	{
		if(it==par)
			continue;
		dfs0(it, k, lvl+1);
	}
}
 
void precompute()
{
	for(int i=1;i<LG;i++)
		for(int j=1;j<=n;j++)
			if(parent[i-1][j])
				parent[i][j]=parent[i-1][parent[i-1][j]];
}
 
int LCA(int u, int v)
{
	if(level[u]<level[v])
		swap(u,v);
	int diff=level[u]-level[v];
	for(int i=LG-1;i>=0;i--)
	{
		if((1<<i) & diff)
		{
			u=parent[i][u];
		}
	}
	if(u==v)
		return u;
	for(int i=LG-1;i>=0;i--)
	{
		if(parent[i][u] && parent[i][u]!=parent[i][v])
		{
			u=parent[i][u];
			v=parent[i][v];
		}
	}
	return parent[0][u];
}
 
 
int build(int L, int R)
{
	int node = ++ct;
	if(L==R)
		return node;
	int M = (L+R)/2;
	lc[node] = build(L, M);
	rc[node] = build(M+1, R);
	return node;
}
 
int update(int onode, int L, int R, int pos)
{
	int node = ++ct;
	if(L==R)
	{
		st[node] = st[onode] + 1;
		return node;
	}
	int M = (L+R)/2;
	lc[node] = lc[onode];
	rc[node] = rc[onode];
	if(pos <= M)
		lc[node] = update(lc[onode], L, M, pos);
	else
		rc[node] = update(rc[onode], M+1, R, pos);
	st[node] = st[lc[node]] + st[rc[node]];
	return node;
}
 
int query(int nodeu, int nodev, int nodelca, int nodelcapar, int L, int R, int pos)
{
	if(L==R)
		return L;
	int M = (L+R)/2;
	int leftval = st[lc[nodeu]] + st[lc[nodev]] - st[lc[nodelca]] - st[lc[nodelcapar]];
	int rightval = st[rc[nodeu]] + st[rc[nodev]] - st[rc[nodelca]] - st[rc[nodelcapar]];
	if(leftval>=pos)
		return query(lc[nodeu], lc[nodev], lc[nodelca], lc[nodelcapar], L, M, pos);
	else
		return query(rc[nodeu], rc[nodev], rc[nodelca], rc[nodelcapar], M+1, R, pos-leftval);
}
 
void dfs(int u, int par)
{
	int onode = root[par];
	root[u] = update(onode, 1, num, a[u]);
	for(auto &it:g[u])
	{
		if(it==par)
			continue;
		dfs(it, u);
	}
}
 
int32_t main()
{
	IOS;
	cin>>n>>q;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		comp[a[i]];
	}
	for(auto &it:comp)
	{
		it.second = ++num;
		rcomp[num] = it.first;
	}
	for(int i=1;i<=n;i++)
		a[i] = comp[a[i]];
	for(int i=1;i<=n-1;i++)
	{
		int u, v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	root[0] = build(1, num);
	dfs0(1, 0, 1);
	precompute();
	dfs(1, 0);
	while(q--)
	{
		int u, v, k;
		cin>>u>>v>>k;
		int lca = LCA(u, v);
		int parlca = parent[0][lca];
		int value = query(root[u], root[v], root[lca], root[parlca], 1, num, k);
		int ans = rcomp[value];
		cout<<ans<<endl;
	}
	return 0;
}