#include "bits/stdc++.h"

using namespace std;

using type = int;
static type id() { return 0; }
static type op(const type &l, const type &r) { return l + r; }

constexpr int MAX_N = 200010 * 20;

struct Node {
  Node *lch, *rch;
  type val;
  Node(Node *l, Node *r, int _v) {
    lch = l;
    rch = r;
    val = _v;
  }
  Node(Node *l, Node *r) {
    lch = l;
    rch = r;
    val = op(lch->val, rch->val);
  }
  Node() {}
};

Node pool[MAX_N];
Node *root[100010];
Node *nil;
int sid = 0;

Node *my_new(Node *lch, Node *rch, type val) {
  return &(pool[sid++] = Node(lch, rch, val));
}

Node *my_new(Node *lch, Node *rch) { return &(pool[sid++] = Node(lch, rch)); }

// update(x, pos, val, l, r) := ノードx で [l, r) に必要なノードを作成する
// return : 自身のノードのポインタ
Node *update(Node *node, int pos, type val, int l, int r) {
  if (r - l == 1) {
    return my_new(nil, nil, val);
  }
  int m = (l + r) / 2;
  if (pos < m) {
    return my_new(update(node->lch, pos, val, l, m), node->rch);
  }
  return my_new(node->lch, update(node->rch, pos, val, m, r));
}

type query(Node *node, int a, int b, int l, int r) {
  if (node == nil) return id();
  if (b <= l || r <= a) return id();
  if (a <= l && r <= b) return node->val;
  int m = (l + r) / 2;
  return op(query(node->lch, a, b, l, m), query(node->rch, a, b, m, r));
}

template <typename T>
void coordinateCompression(std::vector<T> &a) {
  int N = a.size();
  std::vector<T> xs = a;
  sort(xs.begin(), xs.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  for (int i = 0; i < N; i++) {
    a[i] = lower_bound(xs.begin(), xs.end(), a[i]) - xs.begin();
  }
}

constexpr int MAX_V = 100010;
using Graph = vector<vector<int>>;

struct LCA {
  static const int LOGN = 20;
  array<vector<int>, LOGN + 1> par;
  vector<int> dep;
  void dfs(int v, int pre, Graph &g) {
    for (auto &e : g[v]) {
      if (e == pre) continue;
      par[0][e] = v;
      dep[e] = dep[v] + 1;
      dfs(e, v, g);
    }
  }

  LCA(Graph &g, int root) : dep(g.size()) {
    int n = g.size();
    for (int i = 0; i <= LOGN; i++) par[i].assign(n, -1);
    dep[root] = 0;
    par[0][root] = root;
    dfs(root, -1, g);
    for (int i = 0; i < LOGN; i++) {
      for (int j = 1; j < n; j++) {
        par[i + 1][j] = par[i][par[i][j]];
      }
    }
  }

  int query(int u, int v) {
    if (dep[u] < dep[v]) swap(u, v);
    int d = dep[u] - dep[v];
    for (int i = LOGN; i >= 0; i--) {
      if ((d >> i) & 1) {
        u = par[i][u];
        d -= (1 << i);
      }
    }
    if (u == v) return u;
    for (int i = LOGN; i >= 0; i--) {
      if (par[i][u] != par[i][v]) u = par[i][u], v = par[i][v];
    }
    return par[0][u];
  }
};

vector<int> x(MAX_V);

// 元の値 <-> segtree 上の index
map<int, int> toIndex, fromIndex;
vector<int> pp(MAX_V);

int n, q;

void rec(int cur, int pre, const Graph &g) {
  pp[cur] = pre;
  int val = query(root[pre], toIndex[x[cur]], toIndex[x[cur]] + 1, 0, n + 1);
  root[cur] = update(root[pre], toIndex[x[cur]], val + 1, 0, n + 1);
  for (auto nxt : g[cur]) {
    if (nxt == pre) continue;
    rec(nxt, cur, g);
  }
}

int main() {
  nil = my_new(0, 0, id());
  nil->lch = nil->rch = nil;
  root[0] = nil;

  cin >> n >> q;
  for (int i = 1; i <= n; i++) {
    cin >> x[i];
  }
  {
    auto tmp = x;
    coordinateCompression(tmp);
    for (int i = 1; i <= n; i++) {
      toIndex[x[i]] = tmp[i];
      fromIndex[tmp[i]] = x[i];
    }
  }
  // cerr << "x ok" << endl;
  Graph g(n + 1);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  // cerr << "g ok" << endl;
  rec(1, 0, g);
  // cerr << "rec ok" << endl;
  LCA lca(g, 1);
  // cerr << "lca ok" << endl;
  while (q--) {
    int v, w, l;
    cin >> v >> w >> l;
    // cerr << v << " " << w << " " << l << endl;
    int p = lca.query(v, w);
    // cerr << p << endl;
    int lb = n + 1, ub = 0;
    while (lb - ub > 1) {
      int mid = (lb + ub) / 2;
      int cnt = query(root[v], 0, mid + 1, 0, n + 1) +
                query(root[w], 0, mid + 1, 0, n + 1) -
                query(root[p], 0, mid + 1, 0, n + 1) -
                query(root[pp[p]], 0, mid + 1, 0, n + 1);
      if (cnt >= l)
        lb = mid;
      else
        ub = mid;
    }
    cout << fromIndex[lb] << endl;
  }
}



Measured memory_bytes: 77660