#include <bits/stdc++.h>
using namespace std;
void err(istream_iterator<string> it) { cerr << endl; }
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << "\t";
  err(++it, args...);
}
template <typename T1, typename T2>
ostream& operator<<(ostream& c, pair<T1, T2>& v) {
  c << "(" << v.first << "," << v.second << ")";
  return c;
}
template <template <class...> class TT, class... T>
ostream& operator<<(ostream& out, TT<T...>& c) {
  out << "{ ";
  for (auto& x : c) out << x << " ";
  out << "}";
  return out;
}
const int N = 4e5 + 5;
int timer, c[N], st[N], fn[N], rev[N];
vector<int> adj[N];
void dfs(int u, int pr) {
  st[u] = ++timer;
  rev[timer] = u;
  for (auto& v : adj[u])
    if (v != pr) dfs(v, u);
  fn[u] = timer;
}
long long seg[4 * N];
int lazy[4 * N];
void build(int l, int r, int node) {
  if (l == r) {
    seg[node] = 1ll << c[rev[l]];
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, 2 * node);
  build(mid + 1, r, 2 * node + 1);
  seg[node] = seg[2 * node] | seg[2 * node + 1];
}
void push(int l, int r, int node) {
  if (!lazy[node]) return;
  seg[node] = 1ll << lazy[node];
  if (l != r) lazy[2 * node] = lazy[2 * node + 1] = lazy[node];
  lazy[node] = 0;
}
void update(int l, int r, int node, int ql, int qr, int val) {
  push(l, r, node);
  if (l > qr || r < ql) return;
  if (ql <= l && r <= qr) {
    lazy[node] = val;
    push(l, r, node);
    return;
  }
  int mid = (l + r) >> 1;
  update(l, mid, 2 * node, ql, qr, val);
  update(mid + 1, r, 2 * node + 1, ql, qr, val);
  seg[node] = seg[2 * node] | seg[2 * node + 1];
}
long long query(int l, int r, int node, int ql, int qr) {
  push(l, r, node);
  if (l > qr || r < ql) return 0LL;
  if (ql <= l && r <= qr) return seg[node];
  int mid = (l + r) >> 1;
  return query(l, mid, 2 * node, ql, qr) |
         query(mid + 1, r, 2 * node + 1, ql, qr);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) cin >> c[i];
  for (int i = 0, u, v; i < n - 1; i++) {
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  dfs(1, 1);
  build(1, n, 1);
  while (m--) {
    int type, node;
    cin >> type >> node;
    if (type == 1) {
      int col;
      cin >> col;
      update(1, n, 1, st[node], fn[node], col);
    } else {
      cout << __builtin_popcountll(query(1, n, 1, st[node], fn[node])) << "\n";
    }
  }
}
