#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 = 4e5 + 5;
int n, q;
int c[N];
vector<int> adj[N];
int tin[N], tout[N], timer;
void dfs(int u, int p) {
tin[u] = ++timer;
for (int v : adj[u]) {
if (v == p) continue;
dfs(v, u);
}
tout[u] = timer;
}
struct SegTree {
int n;
vector<ll> seg;
vector<ll> lazy;
SegTree(int n) : n(n) {
seg.resize(4 * n, 0);
lazy.resize(4 * n, -1);
}
void push(int id) {
if (lazy[id] != -1) {
seg[id * 2] = lazy[id * 2] = lazy[id];
seg[id * 2 + 1] = lazy[id * 2 + 1] = lazy[id];
lazy[id] = -1;
}
}
void update(int id, int l, int r, int u, int v, ll val) {
if (l > v || r < u) return;
if (u <= l && r <= v) {
seg[id] = val;
lazy[id] = val;
return;
}
push(id);
int mid = (l + r) >> 1;
update(id * 2, l, mid, u, v, val);
update(id * 2 + 1, mid + 1, r, u, v, val);
seg[id] = seg[id * 2] | seg[id * 2 + 1];
}
ll get(int id, int l, int r, int u, int v) {
if (l > v || r < u) return 0;
if (u <= l && r <= v) return seg[id];
push(id);
int mid = (l + r) >> 1;
return (get(id * 2, l, mid, u, v) | get(id * 2 + 1, mid + 1, r, u, v));
}
};
// - Cây con gốc u sẽ tương ứng với đoạn [tin(u), tout(u)] trên Euler Tour
// => Biến đổi lại truy vấn trong bài sẽ là update 1 đoạn và get 1 đoạn
// - Do giới hạn của c(i) đủ nhỏ (1 <= c(i) <= 60) nên ta có thể dùng 60 cây segment tree để quản lí mỗi màu
// => Độ phức tạp O(q * 60 * log2(n))
// - Nhưng giới hạn bài này khá căng nên cần phải tối ưu thêm
// - Cũng dựa vào giới hạn của c(i), ta có thể xem mỗi màu c ứng với một mask 2^c (chỉ có bit c bật và các bit còn lại đều tắt)
// Khi đó giá trị mask tương ứng với 1 đoạn sẽ là tổng OR của đoạn đó (tức các màu c có xuất hiện trong đoạn thì các bit tương ứng sẽ được bật)
// Và giá trị mask lớn nhất sẽ là 2^61 - 1 (các bit từ 0 đến 60 đều được bật) => Đủ trong phạm vi kiểu long long
// => Chỉ cần dùng 1 cây Segment Tree
// => Độ phức tạp O(q * log2(n))
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> q;
for (int u = 1; u <= n; u++) {
cin >> c[u];
}
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);
SegTree segtree(n + 1);
for (int u = 1; u <= n; u++) {
segtree.update(1, 1, n, tin[u], tin[u], 1ll << c[u]);
}
while (q--) {
int type, u;
cin >> type >> u;
if (type == 1) {
int val;
cin >> val;
segtree.update(1, 1, n, tin[u], tout[u], 1ll << val);
}
else {
ll mask = segtree.get(1, 1, n, tin[u], tout[u]);
cout << __builtin_popcountll(mask) << '\n';
}
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsgIAoKdHlwZWRlZiBsb25nIGxvbmcgbGw7ICAKdHlwZWRlZiBwYWlyPGludCwgaW50PiBpaTsgIAoKY29uc3QgaW50IElORiA9IDFlOTsgIApjb25zdCBsbCBMSU5GID0gMWUxODsgIAoKY29uc3QgaW50IE4gPSA0ZTUgKyA1OyAKCmludCBuLCBxOyAgCmludCBjW05dOyAKdmVjdG9yPGludD4gYWRqW05dOyAKCmludCB0aW5bTl0sIHRvdXRbTl0sIHRpbWVyOyAgCgp2b2lkIGRmcyhpbnQgdSwgaW50IHApIHsKCXRpblt1XSA9ICsrdGltZXI7IAoJZm9yIChpbnQgdiA6IGFkalt1XSkgewoJCWlmICh2ID09IHApIGNvbnRpbnVlOyAKCQlkZnModiwgdSk7IAoJfQoJdG91dFt1XSA9IHRpbWVyOyAKfQoKc3RydWN0IFNlZ1RyZWUgewoJaW50IG47ICAgCgl2ZWN0b3I8bGw+IHNlZzsgCgl2ZWN0b3I8bGw+IGxhenk7ICAKCglTZWdUcmVlKGludCBuKSA6IG4obikgewoJCXNlZy5yZXNpemUoNCAqIG4sIDApOyAgCgkJbGF6eS5yZXNpemUoNCAqIG4sIC0xKTsgCgl9CgoJdm9pZCBwdXNoKGludCBpZCkgewoJCWlmIChsYXp5W2lkXSAhPSAtMSkgewoJCQlzZWdbaWQgKiAyXSA9IGxhenlbaWQgKiAyXSA9IGxhenlbaWRdOyAKCQkJc2VnW2lkICogMiArIDFdID0gbGF6eVtpZCAqIDIgKyAxXSA9IGxhenlbaWRdOyAKCQkJbGF6eVtpZF0gPSAtMTsgCgkJfQoJfQoKCXZvaWQgdXBkYXRlKGludCBpZCwgaW50IGwsIGludCByLCBpbnQgdSwgaW50IHYsIGxsIHZhbCkgewoJCWlmIChsID4gdiB8fCByIDwgdSkgcmV0dXJuOyAKCQlpZiAodSA8PSBsICYmIHIgPD0gdikgewoJCQlzZWdbaWRdID0gdmFsOyAgIAoJCQlsYXp5W2lkXSA9IHZhbDsgIAoJCQlyZXR1cm47IAoJCX0KCQlwdXNoKGlkKTsgCgkJaW50IG1pZCA9IChsICsgcikgPj4gMTsgCgkJdXBkYXRlKGlkICogMiwgbCwgbWlkLCB1LCB2LCB2YWwpOyAKCQl1cGRhdGUoaWQgKiAyICsgMSwgbWlkICsgMSwgciwgdSwgdiwgdmFsKTsgCgkJc2VnW2lkXSA9IHNlZ1tpZCAqIDJdIHwgc2VnW2lkICogMiArIDFdOyAKCX0KCglsbCBnZXQoaW50IGlkLCBpbnQgbCwgaW50IHIsIGludCB1LCBpbnQgdikgewoJCWlmIChsID4gdiB8fCByIDwgdSkgcmV0dXJuIDA7IAoJCWlmICh1IDw9IGwgJiYgciA8PSB2KSByZXR1cm4gc2VnW2lkXTsgCgkJcHVzaChpZCk7IAoJCWludCBtaWQgPSAobCArIHIpID4+IDE7IAoJCXJldHVybiAoZ2V0KGlkICogMiwgbCwgbWlkLCB1LCB2KSB8IGdldChpZCAqIDIgKyAxLCBtaWQgKyAxLCByLCB1LCB2KSk7IAoJfQp9OyAKCi8vIC0gQ8OieSBjb24gZ+G7kWMgdSBz4bq9IHTGsMahbmcg4bupbmcgduG7m2kgxJFv4bqhbiBbdGluKHUpLCB0b3V0KHUpXSB0csOqbiBFdWxlciBUb3VyCi8vID0+IEJp4bq/biDEkeG7lWkgbOG6oWkgdHJ1eSB24bqlbiB0cm9uZyBiw6BpIHPhur0gbMOgIHVwZGF0ZSAxIMSRb+G6oW4gdsOgIGdldCAxIMSRb+G6oW4KLy8gLSBEbyBnaeG7m2kgaOG6oW4gY+G7p2EgYyhpKSDEkeG7pyBuaOG7jyAoMSA8PSBjKGkpIDw9IDYwKSBuw6puIHRhIGPDsyB0aOG7gyBkw7luZyA2MCBjw6J5IHNlZ21lbnQgdHJlZSDEkeG7gyBxdeG6o24gbMOtIG3hu5dpIG3DoHUKLy8gPT4gxJDhu5kgcGjhu6ljIHThuqFwIE8ocSAqIDYwICogbG9nMihuKSkKLy8gLSBOaMawbmcgZ2nhu5tpIGjhuqFuIGLDoGkgbsOgeSBraMOhIGPEg25nIG7Dqm4gY+G6p24gcGjhuqNpIHThu5FpIMawdSB0aMOqbQovLyAtIEPFqW5nIGThu7FhIHbDoG8gZ2nhu5tpIGjhuqFuIGPhu6dhIGMoaSksIHRhIGPDsyB0aOG7gyB4ZW0gbeG7l2kgbcOgdSBjIOG7qW5nIHbhu5tpIG3hu5l0IG1hc2sgMl5jIChjaOG7iSBjw7MgYml0IGMgYuG6rXQgdsOgIGPDoWMgYml0IGPDsm4gbOG6oWkgxJHhu4F1IHThuq90KQovLwkgS2hpIMSRw7MgZ2nDoSB0cuG7iyBtYXNrIHTGsMahbmcg4bupbmcgduG7m2kgMSDEkW/huqFuIHPhur0gbMOgIHThu5VuZyBPUiBj4bunYSDEkW/huqFuIMSRw7MgKHThu6ljIGPDoWMgbcOgdSBjIGPDsyB4deG6pXQgaGnhu4duIHRyb25nIMSRb+G6oW4gdGjDrCBjw6FjIGJpdCB0xrDGoW5nIOG7qW5nIHPhur0gxJHGsOG7o2MgYuG6rXQpCi8vICAgVsOgIGdpw6EgdHLhu4sgbWFzayBs4bubbiBuaOG6pXQgc+G6vSBsw6AgMl42MSAtIDEgKGPDoWMgYml0IHThu6sgMCDEkeG6v24gNjAgxJHhu4F1IMSRxrDhu6NjIGLhuq10KSA9PiDEkOG7pyB0cm9uZyBwaOG6oW0gdmkga2nhu4N1IGxvbmcgbG9uZwovLyA9PiBDaOG7iSBj4bqnbiBkw7luZyAxIGPDonkgU2VnbWVudCBUcmVlCi8vID0+IMSQ4buZIHBo4bupYyB04bqhcCBPKHEgKiBsb2cyKG4pKQoKaW50IG1haW4oKSB7Cglpb3M6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7IAoJY2luLnRpZShudWxscHRyKTsgCQoJY2luID4+IG4gPj4gcTsgIAoJZm9yIChpbnQgdSA9IDE7IHUgPD0gbjsgdSsrKSB7CgkJY2luID4+IGNbdV07Cgl9CgoJZm9yIChpbnQgaSA9IDA7IGkgPCBuIC0gMTsgaSsrKSB7CgkJaW50IHUsIHY7IAoJCWNpbiA+PiB1ID4+IHY7IAoJCWFkalt1XS5wdXNoX2JhY2sodik7IAoJCWFkalt2XS5wdXNoX2JhY2sodSk7IAoJfQoKCXRpbWVyID0gMDsgCglkZnMoMSwgLTEpOyAKCglTZWdUcmVlIHNlZ3RyZWUobiArIDEpOyAgCglmb3IgKGludCB1ID0gMTsgdSA8PSBuOyB1KyspIHsKCQlzZWd0cmVlLnVwZGF0ZSgxLCAxLCBuLCB0aW5bdV0sIHRpblt1XSwgMWxsIDw8IGNbdV0pOyAKCX0KCgl3aGlsZSAocS0tKSB7CgkJaW50IHR5cGUsIHU7IAoJCWNpbiA+PiB0eXBlID4+IHU7ICAKCgkJaWYgKHR5cGUgPT0gMSkgewoJCQlpbnQgdmFsOyAKCQkJY2luID4+IHZhbDsgIAoJCQlzZWd0cmVlLnVwZGF0ZSgxLCAxLCBuLCB0aW5bdV0sIHRvdXRbdV0sIDFsbCA8PCB2YWwpOyAKCQl9CQoJCWVsc2UgewoJCQlsbCBtYXNrID0gc2VndHJlZS5nZXQoMSwgMSwgbiwgdGluW3VdLCB0b3V0W3VdKTsgCgkJCWNvdXQgPDwgX19idWlsdGluX3BvcGNvdW50bGwobWFzaykgPDwgJ1xuJzsgCgkJfQoJfQp9