#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
const int N = 4e4 + 5;
const int Q = 1e5 + 5;
const int B = 282; // sqrt(2 * N)
// Ở bài này ta sẽ áp dụng kiến thức Euler Tour cho Truy vấn Đường đi, kết hợp với Thuật toán Mo
// Tham khảo Thuật toán Mo trên Cây (Mo's Algorithm on Trees [Tutorial] (blog Codeforces))
struct Query {
int l, r, lca_uv, idx;
bool operator<(const Query &other) const {
if (l / B == other.l / B) {
return (l / B & 1) ? (r > other.r) : (r < other.r);
}
return (l < other.l);
}
};
int n, q;
int c[N];
vector<int> adj[N];
void compress(int c[]) {
vector<int> vals;
for (int u = 1; u <= n; u++) {
vals.push_back(c[u]);
}
sort(vals.begin(), vals.end());
vals.resize(unique(vals.begin(), vals.end()) - vals.begin());
for (int u = 1; u <= n; u++) {
c[u] = lower_bound(vals.begin(), vals.end(), c[u]) - vals.begin();
}
}
int up[16][N];
int euler_tour[2 * N];
int tin[N], tout[N], timer;
void dfs(int u, int p) {
tin[u] = ++timer;
euler_tour[timer] = u;
up[0][u] = p;
for (int i = 1; i <= 15; i++) {
up[i][u] = up[i - 1][up[i - 1][u]];
}
for (int v : adj[u]) {
if (v == p) continue;
dfs(v, u);
}
tout[u] = ++timer;
euler_tour[timer] = u;
}
bool isAncestor(int u, int v) {
return (tin[u] <= tin[v] && tout[v] <= tout[u]);
}
int lca(int u, int v) {
if (isAncestor(u, v)) return u;
if (isAncestor(v, u)) return v;
for (int i = 15; i >= 0; i--) {
if (!isAncestor(up[i][u], v)) {
u = up[i][u];
}
}
return up[0][u];
}
vector<Query> queries;
int cur_ans; // Số giá trị phân biệt hiện tại
bool active[N]; // active[u] = 0/1: Đỉnh u có tham gia vào truy vấn hiện tại hay không
int cnt[N]; // cnt[val] = Số lần xuất hiện của giá trị val
int ans[Q]; // ans[i] = Đáp án của truy vấn thứ i
void add(int u) {
cnt[c[u]]++;
cur_ans += (cnt[c[u]] == 1);
}
void remove(int u) {
cnt[c[u]]--;
cur_ans -= (cnt[c[u]] == 0);
}
void update(int i) {
int u = euler_tour[i];
active[u] ^= 1;
if (active[u]) add(u);
else remove(u);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> q;
for (int u = 1; u <= n; u++) {
cin >> c[u];
}
compress(c);
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
timer = 0;
dfs(1, 1);
for (int i = 0; i < q; i++) {
int u, v;
cin >> u >> v;
if (tin[u] > tin[v]) swap(u, v);
int lca_uv = lca(u, v);
if (u == lca_uv) {
queries.push_back({tin[u], tin[v], -1, i});
}
else {
queries.push_back({tout[u], tin[v], lca_uv, i});
}
}
sort(queries.begin(), queries.end());
cur_ans = 0;
int cur_l = 1, cur_r = 0;
for (Query &q : queries) {
while (cur_l < q.l) update(cur_l++);
while (cur_r > q.r) update(cur_r--);
while (cur_l > q.l) update(--cur_l);
while (cur_r < q.r) update(++cur_r);
if (q.lca_uv != -1) update(tin[q.lca_uv]);
ans[q.idx] = cur_ans;
if (q.lca_uv != -1) update(tin[q.lca_uv]);
}
for (int i = 0; i < q; i++) {
cout << ans[i] << '\n';
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsgIAoKdHlwZWRlZiBsb25nIGxvbmcgbGw7ICAKdHlwZWRlZiBwYWlyPGludCwgaW50PiBpaTsgIAoKY29uc3QgaW50IElORiA9IDFlOTsgIApjb25zdCBsbCBMSU5GID0gMWUxODsgIAoKY29uc3QgaW50IE4gPSA0ZTQgKyA1OyAKY29uc3QgaW50IFEgPSAxZTUgKyA1OyAKY29uc3QgaW50IEIgPSAyODI7IC8vIHNxcnQoMiAqIE4pICAgCiAKLy8g4bueIGLDoGkgbsOgeSB0YSBz4bq9IMOhcCBk4bulbmcga2nhur9uIHRo4bupYyBFdWxlciBUb3VyIGNobyBUcnV5IHbhuqVuIMSQxrDhu51uZyDEkWksIGvhur90IGjhu6NwIHbhu5tpIFRodeG6rXQgdG/DoW4gTW8KLy8gVGhhbSBraOG6o28gVGh14bqtdCB0b8OhbiBNbyB0csOqbiBDw6J5IChNbydzIEFsZ29yaXRobSBvbiBUcmVlcyBbVHV0b3JpYWxdIChibG9nIENvZGVmb3JjZXMpKQoKc3RydWN0IFF1ZXJ5IHsKCWludCBsLCByLCBsY2FfdXYsIGlkeDsgIAoJYm9vbCBvcGVyYXRvcjwoY29uc3QgUXVlcnkgJm90aGVyKSBjb25zdCB7CgkJaWYgKGwgLyBCID09IG90aGVyLmwgLyBCKSB7CgkJCXJldHVybiAobCAvIEIgJiAxKSA/IChyID4gb3RoZXIucikgOiAociA8IG90aGVyLnIpOyAKCQl9CgkJcmV0dXJuIChsIDwgb3RoZXIubCk7IAoJfQp9OyAKCmludCBuLCBxOyAgCmludCBjW05dOyAKdmVjdG9yPGludD4gYWRqW05dOyAKCnZvaWQgY29tcHJlc3MoaW50IGNbXSkgewoJdmVjdG9yPGludD4gdmFsczsgIAoJZm9yIChpbnQgdSA9IDE7IHUgPD0gbjsgdSsrKSB7CgkJdmFscy5wdXNoX2JhY2soY1t1XSk7IAoJfQoJc29ydCh2YWxzLmJlZ2luKCksIHZhbHMuZW5kKCkpOyAKCXZhbHMucmVzaXplKHVuaXF1ZSh2YWxzLmJlZ2luKCksIHZhbHMuZW5kKCkpIC0gdmFscy5iZWdpbigpKTsgCglmb3IgKGludCB1ID0gMTsgdSA8PSBuOyB1KyspIHsKCQljW3VdID0gbG93ZXJfYm91bmQodmFscy5iZWdpbigpLCB2YWxzLmVuZCgpLCBjW3VdKSAtIHZhbHMuYmVnaW4oKTsKCX0KfQoKaW50IHVwWzE2XVtOXTsgCmludCBldWxlcl90b3VyWzIgKiBOXTsgCmludCB0aW5bTl0sIHRvdXRbTl0sIHRpbWVyOyAKCnZvaWQgZGZzKGludCB1LCBpbnQgcCkgewoJdGluW3VdID0gKyt0aW1lcjsgIAoJZXVsZXJfdG91clt0aW1lcl0gPSB1OyAgCgl1cFswXVt1XSA9IHA7ICAgCglmb3IgKGludCBpID0gMTsgaSA8PSAxNTsgaSsrKSB7CgkJdXBbaV1bdV0gPSB1cFtpIC0gMV1bdXBbaSAtIDFdW3VdXTsgCgl9Cglmb3IgKGludCB2IDogYWRqW3VdKSB7CgkJaWYgKHYgPT0gcCkgY29udGludWU7ICAKCQlkZnModiwgdSk7IAoJfQoJdG91dFt1XSA9ICsrdGltZXI7IAoJZXVsZXJfdG91clt0aW1lcl0gPSB1OyAgCn0KCmJvb2wgaXNBbmNlc3RvcihpbnQgdSwgaW50IHYpIHsKCXJldHVybiAodGluW3VdIDw9IHRpblt2XSAmJiB0b3V0W3ZdIDw9IHRvdXRbdV0pOyAKfQoKaW50IGxjYShpbnQgdSwgaW50IHYpIHsKCWlmIChpc0FuY2VzdG9yKHUsIHYpKSByZXR1cm4gdTsgCglpZiAoaXNBbmNlc3Rvcih2LCB1KSkgcmV0dXJuIHY7Cglmb3IgKGludCBpID0gMTU7IGkgPj0gMDsgaS0tKSB7CgkJaWYgKCFpc0FuY2VzdG9yKHVwW2ldW3VdLCB2KSkgewoJCQl1ID0gdXBbaV1bdV07IAoJCX0KCX0KCXJldHVybiB1cFswXVt1XTsgCn0KCnZlY3RvcjxRdWVyeT4gcXVlcmllczsKaW50IGN1cl9hbnM7IC8vIFPhu5EgZ2nDoSB0cuG7iyBwaMOibiBiaeG7h3QgaGnhu4duIHThuqFpCmJvb2wgYWN0aXZlW05dOyAvLyBhY3RpdmVbdV0gPSAwLzE6IMSQ4buJbmggdSBjw7MgdGhhbSBnaWEgdsOgbyB0cnV5IHbhuqVuIGhp4buHbiB04bqhaSBoYXkga2jDtG5nIAppbnQgY250W05dOyAvLyBjbnRbdmFsXSA9IFPhu5EgbOG6p24geHXhuqV0IGhp4buHbiBj4bunYSBnacOhIHRy4buLIHZhbAppbnQgYW5zW1FdOyAvLyBhbnNbaV0gPSDEkMOhcCDDoW4gY+G7p2EgdHJ1eSB24bqlbiB0aOG7qSBpIAoKdm9pZCBhZGQoaW50IHUpIHsKCWNudFtjW3VdXSsrOyAKCWN1cl9hbnMgKz0gKGNudFtjW3VdXSA9PSAxKTsgCn0KCnZvaWQgcmVtb3ZlKGludCB1KSB7CgljbnRbY1t1XV0tLTsgCgljdXJfYW5zIC09IChjbnRbY1t1XV0gPT0gMCk7IAp9Cgp2b2lkIHVwZGF0ZShpbnQgaSkgewoJaW50IHUgPSBldWxlcl90b3VyW2ldOyAKCWFjdGl2ZVt1XSBePSAxOyAKCWlmIChhY3RpdmVbdV0pIGFkZCh1KTsgCgllbHNlIHJlbW92ZSh1KTsgCn0KCmludCBtYWluKCkgewoJaW9zOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyAKCWNpbi50aWUobnVsbHB0cik7IAkKCWNpbiA+PiBuID4+IHE7IAoJZm9yIChpbnQgdSA9IDE7IHUgPD0gbjsgdSsrKSB7CgkJY2luID4+IGNbdV07IAoJfQoJY29tcHJlc3MoYyk7IAoJCQoJZm9yIChpbnQgaSA9IDA7IGkgPCBuIC0gMTsgaSsrKSB7CgkJaW50IHUsIHY7IAoJCWNpbiA+PiB1ID4+IHY7IAoJCWFkalt1XS5wdXNoX2JhY2sodik7IAoJCWFkalt2XS5wdXNoX2JhY2sodSk7ICAKCX0KCgl0aW1lciA9IDA7ICAKCWRmcygxLCAxKTsgIAoKCWZvciAoaW50IGkgPSAwOyBpIDwgcTsgaSsrKSB7CgkJaW50IHUsIHY7IAoJCWNpbiA+PiB1ID4+IHY7IAoJCWlmICh0aW5bdV0gPiB0aW5bdl0pIHN3YXAodSwgdik7IAoJCWludCBsY2FfdXYgPSBsY2EodSwgdik7IAoJCWlmICh1ID09IGxjYV91dikgewoJCQlxdWVyaWVzLnB1c2hfYmFjayh7dGluW3VdLCB0aW5bdl0sIC0xLCBpfSk7IAoJCX0KCQllbHNlIHsKCQkJcXVlcmllcy5wdXNoX2JhY2soe3RvdXRbdV0sIHRpblt2XSwgbGNhX3V2LCBpfSk7IAoJCX0KCX0KCglzb3J0KHF1ZXJpZXMuYmVnaW4oKSwgcXVlcmllcy5lbmQoKSk7ICAKCgljdXJfYW5zID0gMDsgIAoJaW50IGN1cl9sID0gMSwgY3VyX3IgPSAwOyAgCglmb3IgKFF1ZXJ5ICZxIDogcXVlcmllcykgewoJCXdoaWxlIChjdXJfbCA8IHEubCkgdXBkYXRlKGN1cl9sKyspOyAKCQl3aGlsZSAoY3VyX3IgPiBxLnIpIHVwZGF0ZShjdXJfci0tKTsgIAoJCXdoaWxlIChjdXJfbCA+IHEubCkgdXBkYXRlKC0tY3VyX2wpOyAKCQl3aGlsZSAoY3VyX3IgPCBxLnIpIHVwZGF0ZSgrK2N1cl9yKTsgCgkJaWYgKHEubGNhX3V2ICE9IC0xKSB1cGRhdGUodGluW3EubGNhX3V2XSk7ICAKCQlhbnNbcS5pZHhdID0gY3VyX2FuczsgIAoJCWlmIChxLmxjYV91diAhPSAtMSkgdXBkYXRlKHRpbltxLmxjYV91dl0pOyAKCX0KCglmb3IgKGludCBpID0gMDsgaSA8IHE7IGkrKykgewoJCWNvdXQgPDwgYW5zW2ldIDw8ICdcbic7IAoJfQp9