#include <bits/stdc++.h>

using namespace std;

#define int long long
// #define double long double
#define FOR(i, a, b) for(ll i = (a); i < (b); ++i)
#define FORR(i, a, b) for(ll i = (a); i > (b); --i)
#define REP(i, n) for(ll i = 0; i < (n); ++i)
#define REPR(i, n) for(ll i = n; i >= 0; i--)
#define FOREACH(x, a) for(auto &(x) : (a))
#define VECCIN(x)                                                              \
    for(auto &youso_ : (x)) cin >> youso_
#define bitcnt __builtin_popcount
#define SZ(x) ((ll)(x).size())
#define fi first
#define se second
#define All(a) (a).begin(), (a).end()
#define rAll(a) (a).rbegin(), (a).rend()
template <typename T = long long> inline T IN() {
    T x;
    cin >> x;
    return (x);
}
inline void CIN() {}
template <class Head, class... Tail>
inline void CIN(Head &&head, Tail &&... tail) {
    cin >> head;
    CIN(move(tail)...);
}
#define CCIN(...)                                                              \
    char __VA_ARGS__;                                                          \
    CIN(__VA_ARGS__)
#define DCIN(...)                                                              \
    double __VA_ARGS__;                                                        \
    CIN(__VA_ARGS__)
#define LCIN(...)                                                              \
    ll __VA_ARGS__;                                                            \
    CIN(__VA_ARGS__)
#define SCIN(...)                                                              \
    string __VA_ARGS__;                                                        \
    CIN(__VA_ARGS__)
#define Printv(v)                                                              \
    {                                                                          \
        REP(x, v.size()) { cout << v[x] << (x == v.size() - 1 ? "\n" : " "); } \
    }
template <typename T = string> inline void eputs(T s) {
    cout << s << "\n";
    exit(0);
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
    std::fill((T *)array, (T *)(array + N), val);
}
template <typename T> using PQG = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using PQ = priority_queue<T>;

typedef long long ll;
typedef pair<ll, ll> PL;
typedef vector<PL> VPL;
typedef vector<ll> VL;
typedef vector<VL> VVL;
typedef vector<double> VD;

#define uni int;

const int INF = 1e9;
const int MOD = 1e9 + 7;
const ll LINF = 1e18;
const ll dx[] = {1, 0, -1, 0};
const ll dy[] = {0, 1, 0, -1};
#define PI 3.141592653589793238

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);
};

// new
template <typename T> struct BIT {
    int n;
    vector<T> dat;

    BIT(ll n = 0) { initialize(n); }

    void initialize(ll nin) {
        n = nin + 1;
        dat.resize(n + 1);
        fill(All(dat), 0);
    }

    T sum(ll i) {
        T s = 0;
        while(i > 0) {
            s += dat[i];
            i = i & (i - 1);
        }
        return s;
    }

    T sum_between(ll i, ll j) {
        if(i > j) return 0;
        return sum(j) - sum(i - 1);
    }

    void plus(ll i, T x) {
        while(i <= n) {
            dat[i] += x;
            i += i & -i;
        }
    }

    ll lower_bound(T x) {
        ll ret = 0;
        ll k = 1;
        while(2 * k <= n) k <<= 1;
        for(; k > 0; k >>= 1) {
            if(ret + k <= n && dat[ret + k] < x) {
                x -= dat[ret + k];
                ret += k;
            }
        }
        return ret + 1;
    }
};

ll N, Q, val[100000], k[100000], ans[100000];
BIT<ll> bit(100010);

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

void Mo_Tree_Vertex::del(int idx) { bit.plus(val[idx] + 1, -1); }

signed main() {
    cin >> N >> Q;
    VL com;
    REP(i, N) cin >> val[i], com.emplace_back(val[i]);
    sort(All(com));
    com.erase(unique(All(com)), com.end());
    REP(i, N) val[i] = lower_bound(All(com), val[i]) - com.begin();
    Mo_Tree_Vertex mo(N);
    REP(i, N - 1) {
        LCIN(a, b);
        mo.add_edge(--a, --b);
    }
    mo.prepare();
    REP(i, Q) {
        LCIN(a, b);
        cin >> k[i];
        mo.insert(--a, --b);
    }
    mo.build();
    REP(i, Q) {
        ll idx = mo.process();
        ans[idx] = com[bit.lower_bound(k[idx]) - 1];
    }
    REP(i, Q) { cout << ans[i] << "\n"; }
}



Measured memory_bytes: 35100