#include <bits/stdc++.h>
using namespace std;
const int MaxQ = 15e4, N = 5e4 + 1, LOG = 16, SQ = 9;
int ans[MaxQ], a[N], st[N], fn[N], par[N], hd[N], timer, n, q;
vector<int> g[N];
vector<pair<int, int> > Q[N];
int t[LOG * (1 << SQ)][2], sz;
int add(const int &x) {
  int cur = 0;
  for (int i = LOG - 1; i >= 0; i--) {
    bool b = (x >> i) & 1;
    if (!t[cur][b]) t[cur][b] = ++sz;
    cur = t[cur][b];
  }
  return cur;
}
int get(const int &x) {
  int cur = 0, res = 0;
  for (int i = LOG - 1; i >= 0; i--) {
    bool b = (x >> i) & 1;
    if (t[cur][!b])
      cur = t[cur][!b], res ^= (1 << i);
    else
      cur = t[cur][b];
  }
  return res;
}
void Build(int id) {
  memset(t, 0, sizeof t), sz = 0;
  int v = id, res = 0;
  while (v && v != hd[id]) {
    add(a[v] ^ res);
    v = par[v], res++;
  }
}
bool Ispar(int u, int v) { return st[u] <= st[v] && st[v] < fn[u]; }
void dfs(int v) {
  st[v] = timer++, hd[v] = v;
  for (int i = 0; i < (1 << SQ); i++) hd[v] = par[hd[v]];
  for (int u : g[v])
    if (u != par[v]) par[u] = v, dfs(u);
  fn[v] = timer;
}
void AddQ(int u, int v, int id) {
  int res = 0;
  while (!Ispar(hd[v], par[u])) {
    Q[v].push_back({id, res});
    v = hd[v], res += (1 << SQ);
  }
  while (v != u) {
    ans[id] = max(ans[id], a[v] ^ res);
    v = par[v], res++;
  }
  return;
}
void Solve(int v) {
  for (int u : g[v])
    if (u != par[v]) Solve(u);
  Build(v);
  for (auto [id, res] : Q[v]) ans[id] = max(ans[id], get(res));
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> q;
  for (int i = 1; i <= n; i++) cin >> a[i];
  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v), g[v].push_back(u);
  }
  st[0] = -1, fn[0] = n, dfs(1);
  for (int i = 0; i < q; i++) {
    int u, v;
    cin >> u >> v;
    AddQ(par[u], v, i);
  }
  Solve(1);
  for (int i = 0; i < q; i++) cout << ans[i] << "\n";
  return 0;
}
