// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2270

#include <iostream>
#include <vector>
#include <cstdio>
#include <sstream>
#include <map>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
#include <functional>
#include <set>
#include <ctime>
#include <random>
#include <chrono>
#include <cassert>
using namespace std;

namespace {
  using Integer = long long; //__int128;
  template<class T> istream& operator >> (istream& is, vector<T>& vec){for(T& val: vec) is >> val; return is;}
  template<class T> istream& operator ,  (istream& is, T& val){ return is >> val;}
  template<class T> ostream& operator << (ostream& os, const vector<T>& vec){for(int i=0; i<vec.size(); i++) os << vec[i] << (i==vec.size()-1?"":" "); return os;}
  template<class T> ostream& operator ,  (ostream& os, const T& val){ return os << " " << val;}

  template<class H> void print(const H& head){ cout << head; }
  template<class H, class ... T> void print(const H& head, const T& ... tail){ cout << head << " "; print(tail...); }
  template<class ... T> void println(const T& ... values){ print(values...); cout << endl; }

  template<class H> void eprint(const H& head){ cerr << head; }
  template<class H, class ... T> void eprint(const H& head, const T& ... tail){ cerr << head << " "; eprint(tail...); }
  template<class ... T> void eprintln(const T& ... values){ eprint(values...); cerr << endl; }

  class range{
    long long start_, end_, step_;
   public:
    struct range_iterator{
      long long val, step_;
      range_iterator(long long v, long long step) : val(v), step_(step) {}
      long long operator * (){return val;}
      void operator ++ (){val += step_;}
      bool operator != (range_iterator& x){return step_ > 0 ? val < x.val : val > x.val;}
    };
    range(long long len) : start_(0), end_(len), step_(1) {}
    range(long long start, long long end) : start_(start), end_(end), step_(1) {}
    range(long long start, long long end, long long step) : start_(start), end_(end), step_(step) {}
    range_iterator begin(){ return range_iterator(start_, step_); }
    range_iterator   end(){ return range_iterator(  end_, step_); }
  };

  string operator "" _s (const char* str, size_t size){ return move(string(str)); }
  constexpr Integer my_pow(Integer x, Integer k, Integer z=1){return k==0 ? z : k==1 ? z*x : (k&1) ? my_pow(x*x,k>>1,z*x) : my_pow(x*x,k>>1,z);}
  constexpr Integer my_pow_mod(Integer x, Integer k, Integer M, Integer z=1){return k==0 ? z%M : k==1 ? z*x%M : (k&1) ? my_pow_mod(x*x%M,k>>1,M,z*x%M) : my_pow_mod(x*x%M,k>>1,M,z);}
  constexpr unsigned long long operator "" _ten (unsigned long long value){ return my_pow(10,value); }

  inline int k_bit(Integer x, int k){return (x>>k)&1;} //0-indexed

  mt19937 mt(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count());

  template<class T> string join(const vector<T>& v, const string& sep){
    stringstream ss; for(int i=0; i<v.size(); i++){ if(i>0) ss << sep; ss << v[i]; } return ss.str();
  }

  string operator * (string s, int k){ string ret; while(k){ if(k&1) ret += s; s += s; k >>= 1; } return ret; }

}



inline int pop_count(unsigned long long x){
  x = (x & 0x5555555555555555UL) + (x >>  1 & 0x5555555555555555UL);
  x = (x & 0x3333333333333333UL) + (x >>  2 & 0x3333333333333333UL);
  x = (x & 0x0f0f0f0f0f0f0f0fUL) + (x >>  4 & 0x0f0f0f0f0f0f0f0fUL);
  x = (x & 0x00ff00ff00ff00ffUL) + (x >>  8 & 0x00ff00ff00ff00ffUL);
  x = (x & 0x0000ffff0000ffffUL) + (x >> 16 & 0x0000ffff0000ffffUL);
  x = (x & 0x00000000ffffffffUL) + (x >> 32 & 0x00000000ffffffffUL);
  return x;
}
class BitVector{
 public:
  vector<long long> TR;   // compressed 01 bit array
  vector<int> TL;   // large table contains count of 1-bits
  vector<int> TS;   // small table contains count of 1-bits

  size_t bit_L = 9;
  size_t bit_S = 6;

  size_t size_L = 1<<9;
  size_t size_S = 1<<6;

  int lg_size;

  int count_one  = 0;
  int count_zero = 0;

  BitVector(vector<int>& v){
    TL.resize( (v.size() + size_L - 1) >> bit_L , 0);
    TS.resize( TL.size() * (size_L / size_S) , 0);
    TR.resize( TL.size() * (size_L / size_S)  , 0);

    for(int i=0; i<v.size(); i++){
      TR[i >> bit_S] |= (long long)(v[i]) << (i&0b111111);
      if((i >> bit_S) + 1 < TS.size()) TS[(i >> bit_S) + 1] += v[i];
      if((i >> bit_L) + 1 < TL.size()) TL[(i >> bit_L) + 1] += v[i];

      (v[i] ? count_one : count_zero) += 1;
    }
    for(int i=1; i<TL.size(); i++){
      TL[i] += TL[i-1];
    }
    for(int i=1; i<TS.size(); i++){
      if(i % (size_L / size_S)) TS[i] += TS[i-1];
      else TS[i] = 0;
    }
    lg_size = 0;
    while( 1<<(lg_size+1) < (TL.size()-1)) lg_size++;
  }

  int at(int pos){
    assert(0 <= pos && pos < count_one + count_zero);
    return (TR[ pos >> bit_S ] >> (pos & 0x11111)) & 1;
  }

  //count of q in [0, ub)
  int rank(int q, int ub){
    int res = 0;

    res += TL[ ub>>bit_L ];
    res += TS[ ub>>bit_S ];
    
    unsigned long long mask = (1LL << ( ub & (size_S-1) )) - 1;
    res += pop_count(TR[ (ub>>bit_S) ] & mask);

    if(q == 0) res = ub - res;
    return res;
  }

  //the position + 1 of the t+1-th occurrence of q
  // rank(q, select(q, t)) = t
  int select(int q, int t){
    if( (q ? count_one : count_zero) <= t) return -1;

    t++;
    int idx_L = binary_search_L(q, t);

    int idx_S = binary_search_S(q, t, idx_L);

    int idx_R = binary_search_R(q, t, idx_S);

    int ret = idx_S * size_S + idx_R;
    return ret;
  }

 private:

  inline int binary_search_L(int q, int& t){
    int tmp = 0;
    for(int k=lg_size, sm=0; k>=0; k--){
      if(sm == 0 && (((TL.size()-1)>>k)&1)==0) continue;
      int cnt = TL[tmp + (1<<k)];
      if(!q) cnt = (tmp+(1<<k)) * size_L - cnt;
      if(cnt < t) tmp += 1<<k;
      else sm = 1;
    }
    int cnt = TL[tmp];
    if(!q) cnt = (tmp) * size_L - cnt;
    t -= cnt;
    return tmp;
  }

  inline int binary_search_S(int q, int& t, int& idx_L){
    {
      int ret = idx_L * size_L / size_S;
      int tmp = 0;
      for(int k=2; k>=0; k--){
        int cnt = TS[ret + tmp + (1<<k)];
        if(!q) cnt = (tmp+(1<<k)) * size_S - cnt;
        if(cnt < t){
          tmp += (1<<k);
        }
      }
      int cnt = TS[ret + tmp];
      if(!q) cnt = tmp * size_S - cnt;
      t -= cnt;

      return ret + tmp;
    }
  }

  inline int binary_search_R(int q, int& t, int idx_S){
    long long a = TR[ idx_S ];
    if(!q) a = ~a;
    long long b = (a & 0x5555555555555555UL) + (a >>  1 & 0x5555555555555555UL);
    long long c = (b & 0x3333333333333333UL) + (b >>  2 & 0x3333333333333333UL);
    long long d = (c & 0x0f0f0f0f0f0f0f0fUL) + (c >>  4 & 0x0f0f0f0f0f0f0f0fUL);
    long long e = (d & 0x00ff00ff00ff00ffUL) + (d >>  8 & 0x00ff00ff00ff00ffUL);
    long long f = (e & 0x0000ffff0000ffffUL) + (e >> 16 & 0x0000ffff0000ffffUL);

    int k = 0;

    if( (f & 0xffffffff) < t ){
      t -= (f & 0xffffffff);
      k += 32;
    }
    e = (e>>k) & 0xffff;

    if( (e & 0xffff) < t){
      t -= (e & 0xffff);
      k += 16;
    }
    d = (d>>k) & 0xff;

    if( (d & 0xff) < t){
      t -= (d & 0xff);
      k += 8;
    }
    c = (c>>k) & 0xf;

    if( (c & 0xf) < t){
      t -= (c & 0xf);
      k += 4;
    }
    b = (b>>k) & 0x3;

    if( (b & 0x3) < t){
      t -= (b & 0x3);
      k += 2;
    }
    a = (a>>k) & 0x1;


    if( (a & 0x1) < t){
      t -= (a & 0x1);
      k += 1;
    }

    return k;
  }
};


// T = unsigned int / unsigned long long
// B = bitvector container type
template<class T, class B>
class WaveletMatrix{
 public:
  vector<B> m;
  vector<int> L_size;
  T lg;
  T mx;
  const int len;
 public:
  WaveletMatrix(vector<T>& v) : len(v.size()){
    mx = *max_element(v.begin(), v.end());
    lg = 0;
    while((T(1)<<lg+1) <= mx) lg++;

    m.reserve(lg+1);
    L_size.resize(lg+1);

    deque<int> l,r;

    l.resize(len);
    iota(l.begin(), l.end(), 0);

    for(int k=0; k<=lg; k++){
      deque<int> l_, r_;
      vector<int> bits(len);

      L_size[k] = l.size();

      for(int i=0; i<l.size(); i++){
        bits[i] = (v[ l[i] ] >> (lg-k))&1;
        if( (v[ l[i] ] >> (lg-k))&1 ){
          r_.push_back( l[i] );
        }else{
          l_.push_back( l[i] );
        }
      }

      for(int i=0; i<r.size(); i++){
        bits[l.size() + i] = (v[ r[i] ] >> (lg-k))&1;
        if( (v[ r[i] ] >> (lg-k))&1 ){
          r_.push_back( r[i] );
        }else{
          l_.push_back( r[i] );
        }
      }

      swap(l, l_);
      swap(r, r_);
      m.emplace_back(bits);
      /*
      for(int i=0; i<len; i++){
        cerr << bits[i];
      }cerr << endl;
      */
    }
  }

};

void Euler_tour(vector<vector<int>>& G, int pos, int last, vector<int>& res){
  res.push_back(pos);
  for(int nx : G[pos]){
    if(nx == last) continue;
    Euler_tour(G, nx, pos, res);
  }
  res.push_back(pos);
}

//HL????§£ ?§????O(|v|), ??????O(|v|)
class HeavyLightDecomposition{
 public:
  struct heavy_set{
    vector<int> element;
    int depth;
    int parent_vertex;
    heavy_set(int v, int d, int par) : element(1,v), depth(d), parent_vertex(par){}
  };

  vector<vector<int>>& G;
  vector<heavy_set> S;
  vector<int> subtree_size;
  vector<int> set_index;
  vector<int> ele_index;

 private:
  int get_subtree_size(int pos, int par){
    int sz = 1;
    for(int ch : G[pos]){
      if(ch == par) continue;
      sz += get_subtree_size(ch, pos);
    }
    return subtree_size[pos] = sz;
  }

  void make_path(int pos, int par, int set_id){
    set_index[pos] = set_id;
    ele_index[pos] = S[set_id].element.size()-1;

    int largest_child = -1;
    int value = 0;

    for(int ch : G[pos]){
      if(ch == par) continue;
      if(value < subtree_size[ch]){
        value = subtree_size[ch];
        largest_child = ch;
      }
    }

    for(int ch : G[pos]){
      if(ch == par) continue;
      if(largest_child == ch){
        S[set_id].element.push_back(ch);
        make_path(ch, pos, set_id);
      }else{
        S.emplace_back( ch, S[set_id].depth+1, pos );
        make_path(ch, pos, S.size()-1);
      }
    }
  }

  void init(int root){
    subtree_size.resize(G.size(), 0);
    get_subtree_size(root,root);

    set_index.resize(G.size(), 0);
    ele_index.resize(G.size(), 0);

    S.emplace_back( root,0,root );

    make_path( root, root, 0 );

    subtree_size.clear();
  }

 public:
  HeavyLightDecomposition(vector<vector<int>>& G_, int root = 0) : G(G_){
    init(root);
  }

  //set_index, element_index
  //S[set_index].element[element_index] == v
  pair<int,int> get_position(int v){
    return {set_index[v], ele_index[v]};
  }
};

//Lowest Common Ancestor with HL-decomposition tree
//O(log n) / query
int LCA(HeavyLightDecomposition& T, int u, int v){
  auto pu = T.get_position(u);
  auto pv = T.get_position(v);
  if(pu.first == pv.first){
    return pu.second < pv.second ? u : v;
  }

  if(T.S[pu.first].depth > T.S[pv.first].depth){
    swap(pu, pv);
    swap(u,v);
  }

  while(T.S[pu.first].depth != T.S[pv.first].depth){
    v = T.S[pv.first].parent_vertex;
    pv = T.get_position( v );
  }

  while(pu.first != pv.first){
    u = T.S[pu.first].parent_vertex;
    v = T.S[pv.first].parent_vertex;
    pu = T.get_position(u);
    pv = T.get_position(v);
    if(T.S[pv.first].depth == 0) break;
    if(T.S[pv.first].depth == 0) break;
  }

  if(pu.first == pv.first){
    return pu.second < pv.second ? u : v;
  }else{
    abort();
  }
  return -1;
}


template<class T>
vector<T> compress(vector<T> a, vector<T>& b){
  b = a;
  sort(b.begin(), b.end());
  b.erase( unique(b.begin(), b.end()), b.end());
  for(int i=0; i<a.size(); i++){
    a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin();
  }
  return a;
}

int main(){
  int n,q;
  scanf("%d%d", &n, &q);
  vector<int> v(n);
  for(auto&& x: v) scanf("%d", &x);
  vector<vector<int>> G(n);
  for(int i=0; i<n-1; ++i){
    int a,b;
    scanf("%d%d", &a, &b);
    a--; b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }

  v.push_back(0);

  vector<int> E;
  Euler_tour(G, 0, 0, E);
  vector<int> dic;
  auto v_c = compress(v, dic);

  int mx = *max_element(v_c.begin(), v_c.end());

  vector<int> in(n, -1);
  vector<int> x,y;
  for(auto i : E){
    if(in[i] != -1){
      x.push_back(mx*2);
      y.push_back(v_c[i]);
    }else{
      in[i] = x.size();
      x.push_back(v_c[i]);
      y.push_back(mx*2);
    }
  }

  WaveletMatrix<int, BitVector> w_x(x);
  WaveletMatrix<int, BitVector> w_y(y);

  HeavyLightDecomposition T(G);

  while(q--){
    int a,b,c;
    scanf("%d%d%d", &a, &b, &c);
    a--; b--; c--;

    int p = LCA(T, a,b);

    if(in[a] > in[b]) swap(a,b);

    int k = 0;
    vector<int> lb = {in[p],   in[p],   in[p]+1, in[p]+1};
    vector<int> ub = {in[a]+1, in[a]+1, in[b]+1, in[b]+1};
    int res = 0;
    while(1){
      vector<int> l(4), r(4);
      for(int i=0; i<2; ++i){
        l[2*i]   = w_x.m[k].rank(0, lb[i<<1]);
        r[2*i]   = w_x.m[k].rank(0, ub[i<<1]);

        l[2*i+1] = w_y.m[k].rank(0, lb[(i<<1)+1]);
        r[2*i+1] = w_y.m[k].rank(0, ub[(i<<1)+1]);
      }

      int cnt = 0;
      cnt += (r[0] - l[0]) - (r[1] - l[1]);
      cnt += (r[2] - l[2]) - (r[3] - l[3]);
      assert(cnt>=0);

      if(k==w_x.lg){
        res = c < cnt ? res : res + 1;
        break;
      }

      if(c < cnt){
        lb = {l[0], l[1], l[2], l[3]};
        ub = {r[0], r[1], r[2], r[3]};
      }else{
        lb = {w_x.L_size[k+1] + lb[0]-l[0], w_y.L_size[k+1] + lb[1]-l[1], w_x.L_size[k+1] + lb[2]-l[2], w_y.L_size[k+1] + lb[3]-l[3]};
        ub = {w_x.L_size[k+1] + ub[0]-r[0], w_y.L_size[k+1] + ub[1]-r[1], w_x.L_size[k+1] + ub[2]-r[2], w_y.L_size[k+1] + ub[3]-r[3]};
        res += 1<<w_x.lg-k;
        c -= cnt;
      }
      k++;
    }
    
    printf("%d\n", dic[min(res, (int)dic.size()-1)]);
  }
  return 0;
}

Measured memory_bytes: 32100