#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;

typedef int _loop_int;
#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)
#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)
#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)

// ?°??¶???????
struct node{
  int lch,rch;
  int val,version;
};
node *nodes;
int nodehead;
void nodesinit(){
  nodehead = 0;
  nodes = (node*)calloc(2000000,sizeof(node));
}
int mynew(int val,int version){
  nodes[nodehead].val = val;
  nodes[nodehead].version = version;
  nodes[nodehead].lch = nodes[nodehead].rch = -1;
  return nodehead++;
}
#define SIZE 131072
#define VMAX 100002
#define DEFAULT 0
struct myarray{
  int *rootid;
  myarray(){
    rootid = (int*)calloc(VMAX,sizeof(int));
    rootid[0] = mynew(DEFAULT,0);
  }
  int getat(int v,int k){
    int l=0,r=SIZE;
    int curid = rootid[v];
    while(l+1<r){
      int c = (l+r)>>1;
      if(k<c){
        if(nodes[curid].lch==-1)return DEFAULT;
        r = c;
        curid = nodes[curid].lch;
      }else{
        if(nodes[curid].rch==-1)return DEFAULT;
        l = c;
        curid = nodes[curid].rch;
      }
    }
    return nodes[curid].val;
  }
  int setat_rec(int curid,int v,int k,int x,int l,int r,int id){
    if(l+1==r){
      if(nodes[curid].version == v){
        nodes[curid].val = x;
        return curid;
      }else{
        return mynew(x,v);
      }
    }else{
      int c = (l+r)>>1;
      int ret;
      if(k<c){
        int nxt=0;
        if(nodes[curid].lch==-1){
          int lch = mynew(DEFAULT,v);
          nxt = setat_rec(lch,v,k,x,l,c,(id<<1)+1);
        }else{
          nxt = setat_rec(nodes[curid].lch,v,k,x,l,c,(id<<1)+1);
        }
        if(nodes[curid].version == v){
          nodes[curid].lch = nxt;
          ret = curid;
        }else{
          ret = mynew(DEFAULT,v);
          nodes[ret].rch = nodes[curid].rch;
          nodes[ret].lch = nxt;
        }
      }else{
        int nxt = 0;
        if(nodes[curid].rch==-1){
          int rch = mynew(DEFAULT,v);
          nxt = setat_rec(rch,v,k,x,c,r,(id<<1)+2);
        }else{
          nxt = setat_rec(nodes[curid].rch,v,k,x,c,r,(id<<1)+2);
        }
        if(nodes[curid].version == v){
          nodes[curid].rch = nxt;
          ret = curid;
        }else{
          ret = mynew(DEFAULT,v);
          nodes[ret].lch = nodes[curid].lch;
          nodes[ret].rch = nxt;
        }
      }
      nodes[ret].val = (nodes[ret].lch==-1 ? 0 : nodes[nodes[ret].lch].val)
        + (nodes[ret].rch==-1 ? 0 : nodes[nodes[ret].rch].val);
      return ret;
    }
  }
  void setat(int v,int k,int x){
    rootid[v] = setat_rec(rootid[v],v,k,x,0,SIZE,0);
  }
  void copy(int from,int to){
    rootid[to] = mynew(DEFAULT,to);
    nodes[rootid[to]].lch = nodes[rootid[from]].lch;
    nodes[rootid[to]].rch = nodes[rootid[from]].rch;
  }
  int sum(int k,int l,int r,int cur){
    if(cur==-1){
      return 0;
    }else if(r <= k){
      return nodes[cur].val;
    }else if((l+r)>>1 <= k){
      return (nodes[cur].lch==-1?0:nodes[nodes[cur].lch].val) + sum(k,(l+r)>>1,r,nodes[cur].rch);
    }else if(l <= k){
      return sum(k,l,(l+r)>>1,nodes[cur].lch);
    }else{
      return 0;
    }
  }
  int sum(int v,int k){
    return sum(k,0,SIZE,rootid[v]);
  }
};

#define INF 1252583025

int n,q;
int x[125252];
int y[125252];
int rev[125252];

int vs[125252];
int par[125252];
vi g[125252];
int depth[125252];
int anc[125252][20];

int main(){
  nodesinit();
  myarray segs;
  scanf("%d%d",&n,&q);
  REP(i,n)scanf("%d",x+i);
  {
    // ??§??§
    set<int> S;
    REP(i,n)S.insert(x[i]);
    int it = 0;
    map<int,int> M;
    for(int v:S){
      M[v] = it;
      rev[it] = v;
      ++it;
    }
    REP(i,n)y[i]=M[x[i]];
    S.clear();
    M.clear();
  }
  // ??°??????
  REP(i,n-1){
    int a,b;
    scanf("%d%d",&a,&b);
    --a; --b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  {
    REP(i,n) depth[i]=INF;
    REP(i,n)REP(k,20) anc[i][k]=INF;
    depth[0] = 0;
    queue<int> Q;
    Q.push(0);
    int it = 0;
    while(!Q.empty()){
      int pos = Q.front(); Q.pop();
      int d = depth[pos];
      if(d>0){
        segs.copy(vs[anc[pos][0]],it);
      }
      segs.setat(it,y[pos],segs.getat(it,y[pos])+1);
      vs[pos] = it;
      ++it;
      REP(i,g[pos].size()){
        int to = g[pos][i];
        if(depth[to]!=INF)continue;
        depth[to] = d+1;
        Q.push(to);
        // ??????????????°??????
        anc[to][0] = pos;
        int id = 1;
        int cur = pos;
        while(anc[cur][id-1]!=INF){
          int next = anc[cur][id-1];
          anc[to][id] = next;
          cur = next;
          ++id;
        }
      }
    }
  }
  while(q--){
    int s,t,l;
    scanf("%d%d%d",&s,&t,&l);
    --s; --t;
    int lca;
    {
      // LCA?????????
      int a,b;
      a = s;
      b = t;
      if(depth[a]>depth[b])swap(a,b);
      // ????????????????????????
      int diff = depth[b]-depth[a];
      int k = 0;
      while(diff){
        if(diff&1) b = anc[b][k];
        diff>>=1;
        ++k;
      }
      k = 19;
      while(k>=0){
        if(anc[a][k]!=INF && anc[a][k]!=anc[b][k]){
          a = anc[a][k];
          b = anc[b][k];
        }
        --k;
      }
      lca = (a==b) ? a : anc[a][0];
    }
    int va = vs[s];
    int vb = vs[t];
    int vc = vs[lca];
    int vd = anc[lca][0]==INF ? -1 : vs[anc[lca][0]];
    // bin search
    int low=0, high=SIZE;
    while(low+1<high){
      int mid = (low+high)>>1;
      int cnt = 0;
      cnt += segs.sum(va,mid);
      cnt += segs.sum(vb,mid);
      cnt -= segs.sum(vc,mid);
      if(vd!=-1) cnt -= segs.sum(vd,mid);
      if(cnt >= l){
        high = mid;
      }else{
        low = mid;
      }
    }
    printf("%d\n",rev[low]);
  }
  return 0;
}

Measured memory_bytes: 54024