#include <bits/stdc++.h>
#define rep(i, l, r) for(int i = l; i <= r; i++)
#define rep2(i, l, r) for(int i = l; i >= r; i--)
#define fi first
#define se second
#define bit(i, x) (x >> i & 1)
const int N = 3e5 + 3;
using namespace std;
int n, m, a[N];
vector<int> G[N];
int parr[N];
int sz[N], big[N], depth[N];
int in[N], top[N], cnt;
struct node{
    node *child[2];
    int num;
    node() {
        child[0] = child[1] = nullptr;
        num = 0;
    }
};
void add(int u, node *cur) {
    assert(cur != nullptr);
    rep2(i, 16, 0) {
        int x = bit(i, u);
        if (cur -> child[x] != nullptr) {
            node *old = cur -> child[x];
            cur -> child[x] = new node;
            cur = cur -> child[x];
            cur -> child[0] = old -> child[0];
            cur -> child[1] = old -> child[1];
            cur -> num = old -> num + 1;
        }
        else {
            cur -> child[x] = new node;
            cur = cur -> child[x];
            cur -> num++;
        }
    }
}
bool check(int u, node *cur) {
    assert(cur != nullptr);
    rep2(i, 16, 0) {
        int x = bit(i, u);
        if (cur -> child[x] == nullptr) return 0;
        cur = cur -> child[x];
    }
    return 1;
}
void dfs(int u, int par, vector<node*> &root) {
    root[u] = new node;
    root[u] -> child[0] = root[par] -> child[0];
    root[u] -> child[1] = root[par] -> child[1];
    root[u] -> num = root[par] -> num;
    add(a[u], root[u]);
    parr[u] = par;

    sz[u] = 1, big[u] = 0;
    for(int v : G[u]) if (v != par) {
        depth[v] = depth[u] + 1;
        dfs(v, u, root);
        sz[u] += sz[v];
        if (sz[big[u]] < sz[v]) big[u] = v;
    }
}
void rebuild(int u, int topp) {
    in[u] = ++cnt;
    top[u] = topp;
    if (big[u]) rebuild(big[u], topp);
    for(int v : G[u]) if (v != parr[u] && v != big[u]) {
        rebuild(v, v);
    }
}
int lca(int x, int y) {
    while (top[x] != top[y]) {
        if (depth[top[x]] < depth[top[y]]) swap(x, y);
        x = parr[top[x]];
    }
    if (depth[x] > depth[y]) swap(x, y);
    return x;
}
int get(node *cur, int x) {
    if (cur == nullptr) return 0;
    if (cur -> child[x] == nullptr) return 0;
    return cur -> child[x] -> num;
}
void ask(node *x, node *y, node *p, node *pp, int val) {
    int res = 0;
    assert(x != nullptr);
    assert(y != nullptr);
    assert(p != nullptr);
    assert(pp != nullptr);
    rep2(i, 16, 0) {
        int s[2];
        s[0] = get(x, 0) + get(y, 0) - get(p, 0) - get(pp, 0);
        s[1] = get(x, 1) + get(y, 1) - get(p, 1) - get(pp, 1);
        int v = bit(i, val);
        if (s[v ^ 1] > 0) {
            res |= (1 << i);
            if (x != nullptr) x = x -> child[v ^ 1];
            if (y != nullptr) y = y -> child[v ^ 1];
            if (p != nullptr) p = p -> child[v ^ 1];
            if (pp != nullptr) pp = pp -> child[v ^ 1];
        }
        else {
            if (x != nullptr) x = x -> child[v];
            if (y != nullptr) y = y -> child[v];
            if (p != nullptr) p = p -> child[v];
            if (pp != nullptr) pp = pp -> child[v];
        }
    }
    cout << res << "\n";
}
void inp() {
//    cin >> n >> m;
    rep(i, 1, n) cin >> a[i];
    rep(i, 1, n - 1) {
        int x, y; cin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
}
void solve() {
    vector<node*> root(n + 3);
    root[0] = new node;
    dfs(1, 0, root);
    rebuild(1, 1);
    rep(i, 1, m) {
        int x, y, z; cin >> x >> y >> z;
        int p = lca(x, y);
        ask(root[x], root[y], root[p], root[parr[p]], z);
    }
    rep(i, 1, n) G[i].clear();
    cnt = 0;
}
node *root[N];
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    #define task "bus"
//    freopen(task".inp", "r", stdin);
//    freopen(task".out", "w", stdout);

//    freopen("testing.txt", "r", stdin);

    while (cin >> n >> m) {
        inp();
        solve();
    }

//    root[0] = new node;
//
//    root[1] = new node;
//    root[1] -> child[0] = root[0] -> child[0];
//    root[1] -> child[1] = root[0] -> child[1];
//    root[1] -> num = root[0] -> num;
//
//    add(2, root[1]);
//    root[2] = new node;
//    root[2] -> child[0] = root[1] -> child[0];
//    root[2] -> child[1] = root[1] -> child[1];
//    root[2] -> num = root[1] -> num;
//
//    add(3, root[2]);
//
//    cout << check(3, root[1]);

    return 0 ^ 0;
}
// Identify Thief O_O
