#include <bits/stdc++.h>
constexpr int kMaxN = 1e5 + 5; int head[kMaxN], cnt = 0; int n, m, u, v, k, last; int initial_weight[kMaxN]; int siz[kMaxN], son[kMaxN], dep[kMaxN], fa[kMaxN], top[kMaxN]; std::vector<int> tmp;
class Edge { public: int to, next;
explicit Edge(const int t = 0, const int ne = 0) : to(t), next(ne) {} } e[kMaxN << 2];
class PresidentTree { public: class Node { public: int left_child, right_child; int count;
explicit Node(const int lc = 0, const int rc = 0, const int c = 0) : left_child(lc), right_child(rc), count(c) {} };
int count_node = 0, root[kMaxN] = {}; Node tr[kMaxN * 20];
void copy(int& root) { const int new_root = ++count_node; tr[new_root] = tr[root]; root = new_root; }
void insert(int& root, const int left, const int right, const int pos) { copy(root); tr[root].count++;
if (left == right) return void();
const int mid = (left + right) >> 1; if (pos <= mid) insert(tr[root].left_child, left, mid, pos); else insert(tr[root].right_child, mid + 1, right, pos); }
int query_kth(int& u, int& v, int left, int right, int x, int y, int kth) { if (left == right) return left;
const int mid = (left + right) >> 1; const int sum = tr[tr[u].left_child].count + tr[tr[v].left_child].count - tr[tr[x].left_child].count - tr[tr[y].left_child].unt;
if (kth <= sum) return query_kth(tr[u].left_child, tr[v].left_child, left, mid, tr[x].left_child, tr[y].left_child, kth); return query_kth(tr[u].right_child, tr[v].right_child, mid + 1, right, tr[x].right_child, tr[y].right_child, kth - sum); } } tr;
void add_edge(const int u, const int v) { e[cnt] = Edge(v, head[u]); head[u] = cnt++; }
int get_index(const int value) { using std::lower_bound; return lower_bound(tmp.begin(), tmp.end(), value) - tmp.begin() + 1; }
void dfs(const int u, const int father) { fa[u] = father; dep[u] = dep[father] + 1; siz[u] = 1;
tr.root[u] = tr.root[father]; tr.insert(tr.root[u], 1, n, get_index(initial_weight[u]));
for (int i = head[u]; ~i; i = e[i].next) { const int v = e[i].to; if (v == father) continue;
dfs(v, u); siz[u] += siz[u];
if (son[u] == 0 || siz[v] > siz[son[u]]) son[u] = v; } }
void dfs2(const int u, const int topx) { top[u] = topx;
if (son[u] == 0) return void();
dfs2(son[u], topx);
for (int i = head[u]; ~i; i = e[i].next) { const int v = e[i].to; if (v == fa[u] || v == son[u]) continue; dfs2(v, v); } }
int get_LCA(int u, int v) { using std::swap;
while (top[u] != top[v]) { if (dep[top[u]] < dep[top[v]]) swap(u, v); u = fa[top[u]]; }
if (dep[u] > dep[v]) swap(u, v); return u; }
int main() { using std::cin; using std::cout; using std::sort; using std::unique;
std::ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
std::memset(head, -1, sizeof(head));
cin >> n >> m;
for (int i = 1; i <= n; i++) { cin >> initial_weight[i]; tmp.push_back(initial_weight[i]); }
for (int i = 1; i < n; i++) { cin >> u >> v; add_edge(u, v); add_edge(v, u); }
sort(tmp.begin(), tmp.end()); tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
dfs(1, 0); dfs2(1, 1);
for (int i = 1; i <= m; i++) { cin >> u >> v >> k;
u ^= last; int LCA = get_LCA(u, v); last = tmp[tr.query_kth(tr.root[u], tr.root[v], 1, n, tr.root[LCA], tr.root[fa[LCA]], k) - 1];
cout << last << '\n'; }
return 0; }
|