#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int __OneWan_2024 = [](){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
return 0;
}();
bitset<40000> bs[205][205], res;
vector<int> adj[40005];
int a[40005];
int deep[40005], fa[40005][17], mxdeep[40005];
int id[40005], rev[205], tot;
void dfs(int u, int p) {
mxdeep[u] = deep[u] = deep[p] + 1;
fa[u][0] = p;
for (int i = 1 ; (1 << i) <= deep[u] ; i++) {
fa[u][i] = fa[fa[u][i - 1]][i - 1];
}
for (auto &to : adj[u]) {
if (to == p) continue;
dfs(to, u);
mxdeep[u] = max(mxdeep[u], mxdeep[to]);
}
// 选择点个数超过 200 的作为关键点, 以保证期望距离 <= 200
if (mxdeep[u] - deep[u] >= 200 && u != 1) {
id[u] = ++tot;
rev[tot] = u;
mxdeep[u] = deep[u];
}
}
int ttot, top, st[40005], up[40005];
void build(int u, int p) {
if (id[u] != 0) {
// u 是关键点
top = fa[u][0];
bs[st[ttot]][id[u]][a[u]] = 1;
while (id[top] == 0 && top != 0) {
// 暴力跳到上一个关键点或者跳出去为止
bs[st[ttot]][id[u]][a[top]] = 1;
top = fa[top][0];
}
if (top != 0) {
bs[st[ttot]][id[u]][a[top]] = 1;
}
// bs[a][b] 表示从关键点 b 到关键点 a 路径的颜色(包含点 a 和点 b)
up[u] = rev[st[ttot]]; // up[u] 表示点 u 的上一个关键点
st[++ttot] = id[u]; // 把当前关键点 u 入栈
for (int i = ttot - 2 ; i >= 1 ; i--) { // 前缀和处理从当前关键点 u 到它前方关键点的颜色
// bs[st[i]][st[ttot - 1]] 表示关键点 u 的前一个关键点到前方关键点 st[i] 的颜色
// bs[st[ttot - 1]][id[u]] 表示关键点 u 到前一个关键点的颜色
// bs[st[i]][id[u]] 表示关键点 u 到前方关键点 st[i] 的颜色
bs[st[i]][id[u]] = bs[st[i]][st[ttot - 1]] | bs[st[ttot - 1]][id[u]];
}
}
for (auto &to : adj[u]) {
if (to == p) continue;
build(to, u);
}
if (id[u] != 0) {
// 关键点 u 出栈
ttot--;
}
}
int LCA(int x, int y) {
if (deep[x] < deep[y]) swap(x, y);
for (int i = 16 ; i >= 0 ; i--) {
if (deep[fa[x][i]] < deep[y]) continue;
x = fa[x][i];
}
if (x == y) return x;
for (int i = 16 ; i >= 0 ; i--) {
if (fa[x][i] == fa[y][i]) continue;
x = fa[x][i];
y = fa[y][i];
}
return fa[x][0];
}
int main() {
int n, m;
cin >> n >> m;
vector<int> idx;
for (int i = 1 ; i <= n ; i++) {
cin >> a[i];
idx.push_back(a[i]);
}
sort(begin(idx), end(idx));
idx.resize(unique(begin(idx), end(idx)) - begin(idx));
for (int i = 1 ; i <= n ; i++) {
a[i] = lower_bound(begin(idx), end(idx), a[i]) - begin(idx);
}
for (int i = 1 ; i < n ; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
id[1] = ++tot;
rev[tot] = 1;
dfs(1, 0);
build(1, 0);
int ans = 0;
for (int i = 1 ; i <= m ; i++) {
int x, y;
cin >> x >> y;
x ^= ans;
int z = LCA(x, y);
res.reset();
while (id[x] == 0 && x != z) {
// 暴力跳到上一个关键点或者 z 为止
res[a[x]] = 1;
x = fa[x][0];
}
while (id[y] == 0 && y != z) {
// 暴力跳到上一个关键点或者 z 为止
res[a[y]] = 1;
y = fa[y][0];
}
if (x != z) {
int k = x;
while (deep[up[x]] >= deep[z]) {
// 暴力跳到离 z 最近且在z下方的关键点
x = up[x];
}
if (k != x) {
// 小优化, 如果没有跳就不用操作
res |= bs[id[x]][id[k]];
}
while (x != z) {
// 暴力跳到 z
res[a[x]] = 1;
x = fa[x][0];
}
}
if (y != z) {
int k = y;
while (deep[up[y]] >= deep[z]) {
// 暴力跳到离 z 最近且在z下方的关键点
y = up[y];
}
if (k != y) {
// 小优化, 如果没有跳就不用操作
res |= bs[id[y]][id[k]];
}
while (y != z) {
// 暴力跳到 z
res[a[y]] = 1;
y = fa[y][0];
}
}
// 加上 z
res[a[z]] = 1;
ans = res.count();
cout << ans << "\n";
}
return 0;
}