#include <bits/stdc++.h>
using namespace std;
using ll = long long;

// TODO

// Mo(N, JUST Q, double k)
// WARN : write "int id = mo.next();"
// 1: addEdge
// 2: prebuild
// 3: insert
// 4: build
// 5: next...
/// --- MoTreeVertex Library {{{ ///

struct MoTreeVertex {
  const int n, logn, m;
  const int width;
  vector< vector< int > > par;
  vector< int > dep;
  vector< int > in, vs;
  vector< vector< int > > g;
  vector< int8_t > flag;
  vector< int > le, ri, lcas, order;
  int nl = 0, nr = 0;
  int log(int x) {
    int h = 1;
    while((1 << h) < x) h++;
    return h;
  }
  MoTreeVertex(int n, int q, double k = 1)
      : n(n),
        logn(log(n)),
        m(2 * n - 1),
        width(int(k *m / sqrt(q) + 1.0)),
        par(logn, vector< int >(n, -1)),
        dep(n),
        in(n),
        g(n),
        flag(n),
        le(q),
        ri(q),
        lcas(q),
        order(q) {
    vs.reserve(m);
  }
  inline void addEdge(int u, int v) {
    g[u].emplace_back(v);
    g[v].emplace_back(u);
  }
  inline void prebuild() {
    dfs(0, -1, 0);
    for(int k = 1; k < logn; k++)
      for(int i = 0; i < n; i++) {
        int p = par[k - 1][i];
        if(p == -1) continue;
        par[k][i] = par[k - 1][p];
      }
  }
  void dfs(int i, int p, int d) {
    dep[i] = d;
    par[0][i] = p;
    in[i] = vs.size();
    vs.emplace_back(i);
    for(int j : g[i])
      if(j != p) {
        dfs(j, i, d + 1);
        vs.emplace_back(j);
      }
  }
  inline int lca(int u, int v) {
    if(dep[u] > dep[v]) swap(u, v);
    for(int k = logn - 1; k >= 0; k--) {
      int nv = par[k][v];
      if(nv != -1 && dep[nv] >= dep[u]) v = nv;
    }
    if(u == v) return u;
    for(int k = logn - 1; k >= 0; k--) {
      int nu = par[k][u], nv = par[k][v];
      if(nu != nv) u = nu, v = nv;
    }
    return par[0][u];
  }
  inline void insert(int u, int v) {
    if(in[u] > in[v]) swap(u, v);
    static int i = 0;
    le[i] = in[u] + 1;
    ri[i] = in[v] + 1;
    lcas[i] = lca(u, v);
    order[i] = i;
    i++;
  }
  inline void build() {
    sort(begin(order), end(order), [&](int a, int b) {
      const int ab = le[a] / width, bb = le[b] / width;
      return ab != bb ? ab < bb : ab & 1 ? ri[a] < ri[b] : ri[b] < ri[a];
    });
  }
  inline int next() {
    static int i = 0;
#ifdef DEBUG
    assert(i < (int) order.size());
#endif
    if(i > 0) rem(lcas[order[i - 1]]);
    const int id = order[i++];
    while(nl > le[id]) flip(vs[--nl]);
    while(nr < ri[id]) flip(vs[nr++]);
    while(nl < le[id]) flip(vs[nl++]);
    while(nr > ri[id]) flip(vs[--nr]);
    add(lcas[id]);
    return id;
  }
  inline void flip(int i) {
    if(flag[i] ^= 1)
      add(i);
    else
      rem(i);
  }
  inline void add(int i);
  inline void rem(int i);
};

/// }}}--- ///

// NOTE : there's get and sum method.
/// --- BIT Library {{{ ///

template < class T = ll >
struct BIT {
  int n, m;
  T identity;
  vector< T > data;
  BIT() : n(0) {}
  BIT(int n, T identity = T()) : n(n), identity(identity), data(n, identity) {
    m = 1;
    while(m < n) m <<= 1;
  }
  void add(int i, T x) {
    i++;
    while(i <= n) {
      data[i - 1] = data[i - 1] + x;
      i += i & -i;
    }
  }
  T sum(int i) {
    if(i < 0) return identity;
    if(i >= n) i = n - 1;
    i++;
    T s = identity;
    while(i > 0) {
      s = s + data[i - 1];
      i -= i & -i;
    }
    return s;
  }
  T get(int i) { return sum(i) - inverse(sum(i - 1)); }
  T range(int a, int b) { return sum(b) - inverse(sum(a - 1)); }
  int lower_bound(T w) {
    int i = 0;
    for(int k = m; k > 0; k >>= 1) {
      if(i + k <= n && data[i + k - 1] < w) w -= data[(i += k) - 1];
    }
    return i;
  }
};

/// }}}--- ///

const int N = 1e5;
BIT<> bit(N + 1);
int v[N];

inline void MoTreeVertex::add(int i) { bit.add(v[i], 1); }

inline void MoTreeVertex::rem(int i) { bit.add(v[i], -1); }

#define uniq(v) \
  (sort(begin(v), end(v)), (v).erase(unique(begin(v), end(v)), end(v)))
#define compress(mp, b)                            \
  map< typename decltype(b)::value_type, int > mp; \
  {                                                \
    int i = 0;                                     \
    for(auto &e : (b)) mp[e] = i++;                \
  }

int main() {
  std::ios::sync_with_stdio(false), std::cin.tie(0);
  int n, q;
  cin >> n >> q;
  vector< int > x(n);
  for(auto &e : x) cin >> e;
  auto y = x;
  uniq(y);
  compress(mp, y);
  for(int i = 0; i < n; i++) v[i] = mp[x[i]];
  MoTreeVertex mo(n, q, 2);
  for(int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    mo.addEdge(a, b);
  }
  mo.prebuild();
  vector< int > k(q);
  for(int i = 0; i < q; i++) {
    int a, b;
    cin >> a >> b >> k[i];
    a--;
    b--;
    mo.insert(a, b);
  }
  mo.build();
  vector< int > ans(q);
  for(int i = 0; i < q; i++) {
    int id = mo.next();
    ans[id] = y[bit.lower_bound(k[id])];
  }
  for(int i = 0; i < q; i++) cout << ans[i] << endl;
  return 0;
}



Measured memory_bytes: 27556