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

struct Mo_Tree_Vertex
{
  vector< vector< int > > g, parent;
  vector< int > vs, in;

  vector< int > left, right, order, lca, dep;
  vector< bool > v;
  int width;
  int nl, nr, ptr;

  Mo_Tree_Vertex(int n) : width((int) sqrt(2 * n - 1)), nl(0), nr(0), ptr(0), g(n), in(n), dep(n), v(n)
  {
    const auto lg = (int) (log2(n) + 1);
    parent.resize(lg, vector< int >(n));
    vs.reserve(2 * n - 1);
  }

  void add_edge(int x, int y)
  {
    g[x].push_back(y);
    g[y].push_back(x);
  }

  void dfs(int idx, int depth, int par)
  {
    in[idx] = (int) vs.size();
    dep[idx] = depth;
    parent[0][idx] = par;
    vs.push_back(idx);
    for(auto &to : g[idx]) {
      if(to == par) continue;
      dfs(to, depth + 1, idx);
      vs.push_back(to); // 本来のEuler-tourはidxだが, 今回は深い方の頂点をとりたいのでto
    }
  }

  int getlca(int u, int v)
  {
    if(dep[u] > dep[v]) swap(u, v);
    for(int k = 0; k < parent.size(); k++) {
      if(((dep[v] - dep[u]) >> k) & 1) {
        v = parent[k][v];
      }
    }
    if(u == v) return (u);
    for(int k = (int) parent.size() - 1; k >= 0; k--) {
      if(parent[k][u] != parent[k][v]) {
        u = parent[k][u];
        v = parent[k][v];
      }
    }
    return (parent[0][u]);
  }

  void insert(int x, int y)
  {
    if(in[x] > in[y]) swap(x, y);
    left.push_back(in[x] + 1);
    right.push_back(in[y] + 1);
    lca.push_back(getlca(x, y));
  }

  void prepare()
  {
    dfs(0, 0, -1);
    for(int k = 0; k + 1 < parent.size(); k++) {
      for(int i = 0; i < parent[k].size(); i++) {
        if(parent[k][i] == -1) parent[k + 1][i] = -1;
        else parent[k + 1][i] = parent[k][parent[k][i]];
      }
    }
  }

  void build()
  {
    order.resize(left.size());
    iota(begin(order), end(order), 0);
    sort(begin(order), end(order), [&](int a, int b)
    {
      if(left[a] / width != left[b] / width) return left[a] < left[b];
      return right[a] < right[b];
    });
  }

  int process()
  {
    if(ptr == order.size()) return (-1);
    if(ptr > 0) distribute(lca[order[ptr - 1]]); // 前のクエリで追加したLCAを削除
    const auto id = order[ptr];
    while(nl > left[id]) distribute(vs[--nl]);
    while(nr < right[id]) distribute(vs[nr++]);
    while(nl < left[id]) distribute(vs[nl++]);
    while(nr > right[id]) distribute(vs[--nr]);
    distribute(lca[id]); // LCA の頂点を例外として追加する
    return (order[ptr++]);
  }

  /* 偶数回目の訪問時は削除, 奇数回目の訪問時は追加を呼び出す */
  inline void distribute(int vertex)
  {
    v[vertex].flip();
    if(v[vertex]) add(vertex);
    else del(vertex);
  }

  void add(int idx);

  void del(int idx);
};

typedef long long int64;

template< class T >
struct BinaryIndexedTree
{
  vector< T > data;

  BinaryIndexedTree(int sz)
  {
    data.assign(++sz, 0);
  }

  T sum(int k)
  {
    T ret = 0;
    for(++k; k > 0; k -= k & -k) ret += data[k];
    return (ret);
  }

  void add(int k, T x)
  {
    for(++k; k < data.size(); k += k & -k) data[k] += x;
  }
};

template< class T >
struct AdditionalBIT : BinaryIndexedTree< T >
{
  int curr;

  AdditionalBIT(int sz) : BinaryIndexedTree< T >(sz)
  {
    curr = 1;
    while(curr <= sz) curr <<= 1;
  }

  int lower_bound(T w)
  {
    if(w <= 0) return (0);
    int i = 0;
    for(int k = curr; k > 0; k >>= 1) {
      if(i + k < BinaryIndexedTree< T >::data.size() && BinaryIndexedTree< T >::data[i + k] < w) {
        w -= BinaryIndexedTree< T >::data[i + k];
        i += k;
      }
    }
    return (i);
  }
};

int N, Q, X[100000];
int A[100000], B[100000], K[100000];
int64 ans[100000];
AdditionalBIT< int > bit(100000);

void Mo_Tree_Vertex::add(int idx)
{
  bit.add(X[idx], 1);
}

void Mo_Tree_Vertex::del(int idx)
{
  bit.add(X[idx], -1);
}

int main()
{
  scanf("%d %d", &N, &Q);
  vector< int > vs(N);
  for(int i = 0; i < N; i++) scanf("%d", &X[i]), vs[i] = X[i];
  sort(begin(vs), end(vs));
  vs.erase(unique(begin(vs), end(vs)), end(vs));
  for(int i = 0; i < N; i++) {
    X[i] = lower_bound(begin(vs), end(vs), X[i]) - begin(vs);
  }
  Mo_Tree_Vertex mo(N);
  for(int i = 1; i < N; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    mo.add_edge(--a, --b);
  }
  mo.prepare();
  for(int i = 0; i < Q; i++) {
    scanf("%d %d %d", &A[i], &B[i], &K[i]);
    mo.insert(--A[i], --B[i]);
  }
  mo.build();
  for(int i = 0; i < Q; i++) {
    int idx = mo.process();
    ans[idx] = vs[bit.lower_bound(K[idx])];
  }
  for(int i = 0; i < Q; i++) {
    printf("%lld\n", ans[i]);
  }
}


Measured memory_bytes: 23708