#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)
using namespace std;
typedef long long LL;
typedef vector<int> Vertex;
typedef vector<Vertex> Graph;

void debug(const char* format, ...) {
    va_list args;
    va_start(args, format);

#ifdef DEBUG
    vfprintf(stderr, format, args);
#endif

    va_end(args);
}

struct Node{
    int val;
    int cnt;
    int size;
    Node* lc;
    Node* rc;
    Node(int val, int cnt, Node* lc, Node* rc) :
        val(val), cnt(cnt), lc(lc), rc(rc)
    {
        update();
    }
    void update() {
        size = cnt;
        if(lc) size += lc->size;
        if(rc) size += rc->size;
    }
};

int lsize(Node* r) {
    return r->lc ? r->lc->size : 0;
}
int count(Node* r) {
    return r ? r->cnt : 0;
}

int rsize(Node* r) {
    return r->rc ? r->rc->size : 0;
}

Node* init(const vector<int>& v, int l, int r) {
    if(r - l == 0) {
        return NULL;
    } else if(r - l == 1) {
        return new Node(v[l], 0, NULL, NULL);
    } else {
        int m = (l + r) / 2;
        Node* lc = init(v, l, m);
        Node* rc = init(v, m+1, r);
        return new Node(v[m], 0, lc, rc);
    }
}

Node* add(Node* r, int val) {
    if(val < r->val) {
        Node* nlc = add(r->lc, val);
        Node* nr = new Node(r->val, r->cnt, nlc, r->rc);
        return nr;
    } else if(val > r->val) {
        Node* nrc = add(r->rc, val);
        Node* nr = new Node(r->val, r->cnt, r->lc, nrc);
        return nr;
    } else {
        debug("add 1 to r->cnt = %d of r->val = %d\n", r->cnt, r->val);
        Node* nr = new Node(r->val, r->cnt + 1, r->lc, r->rc);
        return nr;
    }
}

const int MAX = 100011;
int label[MAX];
int parent[MAX];
Node* trees[MAX];
Graph G;

void dfs(int u, int p, Node* pre) {
    parent[u] = p;
    trees[u] = add(pre, label[u]);
    auto next = trees[u];

    for(int v : G[u]) if(v != p) {
        dfs(v, u, next);
    }
}

int search(int k, Node* a, Node* b, Node* c, Node* d) {
    int left = lsize(a) + lsize(b) - lsize(c) - lsize(d);
    int mid = count(a) + count(b) - count(c) - count(d);
    debug("k = %d val = %d left = %d mid = %d\n", k, a->val, left, mid);
    if(left >= k) {
        return search(k, a->lc, b->lc, c->lc, d->lc);
    } else if(left + mid >= k) {
        return a->val;
    } else {
        return search(k-left-mid, a->rc, b->rc, c->rc, d->rc);
    }
}
struct LCA{
    int log_v;
    vector<int> depth;
    vector<vector<int>> par;

    void dfs(const Graph& G, int v, int p, int d){
        depth[v] = d;
        par[v][0] = p;
        for(int next : G[v]) if(next != p) {
            dfs(G, next, v, d + 1);
        }
    }

    LCA(const Graph& G, int root) {
        int n = G.size();

        for(log_v = 0; (1 << log_v) < n; log_v++) { }

        depth.resize(n);
        par.assign(n, vector<int>(log_v + 1));

        dfs(G, root, root, 0);

        for(int k = 0; k + 1 <= log_v; k++){
            for(int v = 0; v < n; v++){
                par[v][k + 1] = par[ par[v][k] ][k];
            }
        }
    }

    int query(int u, int v){
        if(depth[u] > depth[v]) swap(u, v);
        for(int k = 0; k <= log_v; k++){
            if((depth[v] - depth[u]) >> k & 1){
                v = par[v][k];
            }
        }
       
        if(u == v) return u;

        for(int k = log_v; k >= 0; k--){
            if(par[u][k] != par[v][k]){
                u = par[u][k];
                v = par[v][k];
            }
        }

        return par[u][0];
    }
};

int main(){
    int N, Q;
    cin >> N >> Q;

    debug("graph\n");

    G.resize(N);
    REP(i, N) cin >> label[i];

    REP(i, N - 1) {
        int a, b;
        cin >> a >> b;
        a--; b--;
        debug("%d -> %d\n", a, b);
        G[a].push_back(b);
        G[b].push_back(a);
    }

    vector<int> uv(N);
    REP(i, N) uv[i] = label[i];
    sort(uv.begin(), uv.end());
    uv.erase(unique(uv.begin(), uv.end()), uv.end());
    
    debug("init\n");
    Node* init_root = init(uv, 0, uv.size());
    trees[N] = init_root; // super root
    debug("dfs\n");
    dfs(0, N, init_root);

    debug("lca\n");
    LCA lca(G, 0);

    debug("query\n");
    while(Q--) {
        int v, w, l;
        cin >> v >> w >> l;
        v--; w--;
        debug("query (%d, %d, %d)\n", v, w, l);
        debug("lca.query(%d, %d)\n", v, w);
        int p = lca.query(v, w);
        debug("int sp = parent[%d] = %d\n", p, parent[p]);
        int sp = parent[p];
        debug("query (%d, %d, %d)\n", v, w, l);
        debug("search (%d, %d, %d, %d)\n", v, w, p, sp);
        int res = search(l, trees[v], trees[w], trees[p], trees[sp]);
        cout << res << endl;
    }

    return 0;
}

Measured memory_bytes: 99996