#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5;
int n, m, c[maxn + 5], head[maxn + 5], cnt;
int fa[maxn + 5], son[maxn + 5];
int dep[maxn + 5], size[maxn + 5];
int top[maxn + 5], dfn[maxn + 5], rk[maxn + 5], ysx;
long long s[(maxn << 2) + 5];
int tag[(maxn << 2) + 5];
struct node {
  int to, next;
} t[(maxn << 1) + 5];
inline int read() {
  int a = 0, b = 1;
  char s = getchar();
  while (s < 48 || s > 57) {
    if (s == '-') b = -1;
    s = getchar();
  }
  while (s >= 48 && s <= 57) a = (a << 1) + (a << 3) + s - 48, s = getchar();
  return a * b;
}
inline void add(int u, int v) {
  t[++cnt].to = v;
  t[cnt].next = head[u];
  head[u] = cnt;
}
void dfs1(int u, int f) {
  dep[u] = dep[f] + 1;
  size[u] = 1;
  for (register int i = head[u]; i; i = t[i].next) {
    int v = t[i].to;
    if (v == f) continue;
    fa[v] = u;
    dfs1(v, u);
    size[u] += size[v];
    if (size[v] > size[son[u]]) son[u] = v;
  }
}
void dfs2(int u, int tp) {
  top[u] = tp;
  dfn[u] = ++ysx;
  rk[ysx] = u;
  if (!son[u]) return;
  dfs2(son[u], tp);
  for (register int i = head[u]; i; i = t[i].next) {
    int v = t[i].to;
    if (v == fa[u] || v == son[u]) continue;
    dfs2(v, v);
  }
}
inline void pushup(int num) { s[num] = s[num << 1] | s[num << 1 | 1]; }
void build(int num, int l, int r) {
  tag[num] = -1;
  if (l == r) {
    s[num] = 1LL << (1LL * c[rk[l]]);
    return;
  }
  int mid = (l + r) >> 1;
  build(num << 1, l, mid);
  build(num << 1 | 1, mid + 1, r);
  pushup(num);
}
inline void pushdown(int num) {
  if (tag[num] == -1) return;
  tag[num << 1] = tag[num << 1 | 1] = tag[num];
  s[num << 1] = s[num << 1 | 1] = 1LL << tag[num];
  tag[num] = -1;
}
void change(int num, int l, int r, int le, int ri, int c) {
  if (le <= l && r <= ri) {
    s[num] = 1LL << c;
    tag[num] = c;
    return;
  }
  pushdown(num);
  int mid = (l + r) >> 1;
  if (le <= mid) change(num << 1, l, mid, le, ri, c);
  if (mid < ri) change(num << 1 | 1, mid + 1, r, le, ri, c);
  pushup(num);
}
long long ask(int num, int l, int r, int le, int ri) {
  if (le <= l && r <= ri) return s[num];
  pushdown(num);
  int mid = (l + r) >> 1;
  long long ans = 0;
  if (le <= mid) ans |= ask(num << 1, l, mid, le, ri);
  if (mid < ri) ans |= ask(num << 1 | 1, mid + 1, r, le, ri);
  return ans;
}
int main() {
  n = read(), m = read();
  for (register int i = 1; i <= n; i = -~i) c[i] = read() - 1;
  for (register int i = 1; i < n; i = -~i) {
    int u = read(), v = read();
    add(u, v), add(v, u);
  }
  dfs1(1, 0), dfs2(1, 1);
  build(1, 1, n);
  for (register int i = 1; i <= m; i = -~i) {
    int opt = read();
    if (opt == 1) {
      int u = read(), c = read() - 1;
      change(1, 1, n, dfn[u], dfn[u] + size[u] - 1, c);
    } else {
      int u = read();
      long long get = ask(1, 1, n, dfn[u], dfn[u] + size[u] - 1);
      int ans = 0;
      while (get) ++ans, get -= get & -get;
      printf("%d\n", ans);
    }
  }
  return 0;
}
