#include <bits/stdc++.h>
using namespace std;
const int N = 4 * 1000 * 100 + 10;
int n, c[N], st[N], en[N], who[N], TM;
vector<int> adj[N];
void dfs(int root, int par = 0) {
  st[root] = TM++;
  who[st[root]] = root;
  for (auto u : adj[root])
    if (u ^ par) dfs(u, root);
  en[root] = TM;
}
struct Node {
  int lazy = -1;
  long long lol = 0;
  void merge(Node L, Node R) { lol = L.lol | R.lol; }
  void add(int x) {
    if (x == -1) return;
    lazy = x;
    lol = 1LL << x;
  }
} seg[N << 2];
void push(int root) {
  seg[root << 1].add(seg[root].lazy), seg[root << 1 | 1].add(seg[root].lazy);
  seg[root].lazy = -1;
}
void build(int l = 0, int r = n, int root = 1) {
  if (l + 1 == r) {
    seg[root].add(c[who[l]]);
    return;
  }
  int mid = l + r >> 1;
  build(l, mid, root << 1), build(mid, r, root << 1 | 1);
  seg[root].merge(seg[root << 1], seg[root << 1 | 1]);
}
void upd(int s, int e, int w, int l = 0, int r = n, int root = 1) {
  if (s <= l && e >= r) {
    seg[root].add(w);
    return;
  }
  if (s >= r || e <= l) return;
  push(root);
  int mid = l + r >> 1;
  upd(s, e, w, l, mid, root << 1), upd(s, e, w, mid, r, root << 1 | 1);
  seg[root].merge(seg[root << 1], seg[root << 1 | 1]);
}
Node get(int s, int e, int l = 0, int r = n, int root = 1) {
  if (s <= l && e >= r) return seg[root];
  if (s >= r || e <= l) return seg[0];
  push(root);
  int mid = l + r >> 1;
  Node res;
  res.merge(get(s, e, l, mid, root << 1), get(s, e, mid, r, root << 1 | 1));
  return res;
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int Q;
  cin >> n >> Q;
  for (int i = 1; i <= n; i++) cin >> c[i];
  for (int i = 1, v, u; i < n; i++) {
    cin >> v >> u;
    adj[v].push_back(u);
    adj[u].push_back(v);
  }
  dfs(1);
  build();
  while (Q--) {
    int t, v, c;
    cin >> t;
    if (t == 1) {
      cin >> v >> c;
      upd(st[v], en[v], c);
    } else {
      cin >> v;
      cout << __builtin_popcountll(get(st[v], en[v]).lol) << '\n';
    }
  }
  return 0;
}
