#include<bits/stdc++.h>
#include<cmath>
#include<vector>
#include<cassert>
#include<numeric>
namespace ProconLib{

    template<class graph_t>
    class LCA{
        private:        
        static int safeLog2(int N){return std::ceil(std::log2(N+1))+1;}
        void dfs(int v,int pre,const graph_t& g);

        protected:
        int N;
        int logN;
        std::vector<std::vector<int>> par;
        std::vector<int> dep;

        public:
        LCA(std::vector<int> root,const graph_t &g);
        LCA(int root,const graph_t &g):LCA(std::vector<int>(1,root),g){};
        int query(int a,int b);
        int depth(int v){return dep[v];}
    };

    template<class graph_t>
    void LCA<graph_t>::dfs(int v,int pre,const graph_t& g){
        par[0][v]=pre;
        for(auto e:g[v]){
            if(e.to==pre) continue;
            par[0][e.to]=v;
            dep[e.to]=dep[v]+1;
            dfs(e.to,v,g);
        }
    }

    template<class graph_t>
    LCA<graph_t>::LCA(std::vector<int> roots,const graph_t &g): N(g.size()),
                                        logN(safeLog2(N)),
                                        par(logN,std::vector<int>(N)),
                                        dep(N,0)
    {
        std::iota(par[0].begin(),par[0].end(),0);
        for(auto root:roots){
            dep[root]=0;
            dfs(root,root,g);
        }
        for(int i=0;i+1<logN;i++){
            for(int j=0;j<N;j++){
                par[i+1][j]=par[i][par[i][j]];
            }
        }
    }


    template<class graph_t>
    int LCA<graph_t>::query(int a,int b){
        if(dep[a]<dep[b]) std::swap(a,b);
        int u=dep[a]-dep[b];
        for(int i=logN-1;i>=0;i--){
            if((u>>i)&1) a=par[i][a];
        }
        assert(dep[a]==dep[b]);
        if(a==b) return a;
        for(int i=logN-1;i>=0;i--){
            if(par[i][a]!=par[i][b]){
                a=par[i][a];
                b=par[i][b];
            }
        }
        assert(a!=b);
        a=par[0][a],b=par[0][b];
        if(a!=b) return -1; // if (g is a forest) and (a and b is disconnected).
        return a;
    }
    
}
using namespace std;
using namespace ProconLib;

using ll=long long;
const int WIDTH=1LL<<30;
struct Node{
    int dat;
    Node* lch;
    Node* rch;
    Node(int dat):dat(dat),lch(nullptr),rch(nullptr){}
    Node(Node* node):dat(node->dat),lch(node->lch),rch(node->rch){}
    Node* add(int l,int r,int v){
        if(r-l==1){
            assert(l==v);
            return new Node(dat+1);
        }
        else{
            int mid=(l+r)/2;
            Node* res=new Node(this);
            (res->dat)++;
            if(v<mid){
                if(res->lch==nullptr) res->lch=new Node(0);
                res->lch=res->lch->add(l,mid,v);
            }
            else{
                if(res->rch==nullptr) res->rch=new Node(0);
                res->rch=res->rch->add(mid,r,v);
            }
            return res;
        }
    }
};

int search(int l,int r,Node* unode,Node* vnode,Node* pnode,int s,int v){
    if(r-l==1){
        return l;
    }
    int mid=(l+r)/2;
    int lsum=0;
    if(unode!=nullptr && unode->lch!=nullptr) lsum+=unode->lch->dat;
    if(vnode!=nullptr && vnode->lch!=nullptr) lsum+=vnode->lch->dat;
    if(pnode!=nullptr && pnode->lch!=nullptr) lsum-=2*(pnode->lch->dat);
    if(l<=v&& v<mid) lsum++;
    if(s<=lsum){
        auto x=unode!=nullptr ? unode->lch : nullptr;
        auto y=vnode!=nullptr ? vnode->lch : nullptr;
        auto z=pnode!=nullptr ? pnode->lch : nullptr;
        return search(l,mid,x,y,z,s,v);
    }
    else{
        auto x=unode!=nullptr ? unode->rch : nullptr;
        auto y=vnode!=nullptr ? vnode->rch : nullptr;
        auto z=pnode!=nullptr ? pnode->rch : nullptr;
        return search(mid,r,x,y,z,s-lsum,v);
    }
}
struct Edge{
    int to;
};
using Graph=vector<vector<Edge>>;
int main(){
    int N,Q;
    cin>>N>>Q;
    vector<int> x(N);
    for(int i=0;i<N;i++) cin>>x[i];
    Graph g(N);
    for(int i=0;i<N-1;i++){
        int a,b;
        cin>>a>>b;
        a--,b--;
        g[a].push_back(Edge{b});
        g[b].push_back(Edge{a});
    }

    vector<Node*> nodes(N,nullptr);
    LCA<Graph> lca(0,g);
    Node* root=new Node(0);
    queue<int> que;
    queue<Node*> que2;
    que.push(0);
    que2.push(root);
    while(!que.empty()){
        int v=que.front(); que.pop();
        auto pnode=que2.front(); que2.pop();
        nodes[v]=pnode->add(0,WIDTH,x[v]);
        for(auto &e:g[v]){
            if(nodes[e.to]!=nullptr) continue;
            que.push(e.to);
            que2.push(nodes[v]);
        }
    }

    while(Q--){
        int v,w,l;
        cin>>v>>w>>l;
        v--,w--;
        int p=lca.query(v,w);
        cout<<search(0,WIDTH,nodes[v],nodes[w],nodes[p],l,x[p])<<endl;
    }
    return 0;
}



Measured memory_bytes: 186688