#include <bits/stdc++.h>
using namespace std;
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
const int mod = 1000000007;
vector<int> graph[400005];
int arr[400005];
int vis[400005];
int start[400005], en[400005], id[400005], cnt = 0;
long long seg[4000005], lazy[4000005];
int ele[400005];
void dfs(int x) {
  vis[x] = 1;
  start[x] = cnt;
  id[cnt] = x;
  cnt++;
  for (int u : graph[x]) {
    if (!vis[u]) dfs(u);
  }
  en[x] = cnt - 1;
}
void build(int node, int l, int r) {
  lazy[node] = 0;
  if (l > r) return;
  if (l == r) {
    seg[node] = 1LL << ele[l];
    return;
  }
  int mid = (l + r) / 2;
  build(node * 2, l, mid);
  build(node * 2 + 1, mid + 1, r);
  seg[node] = seg[node * 2] | seg[2 * node + 1];
}
void refresh(int node, int l, int r) {
  if (lazy[node]) {
    seg[node] = 1LL << lazy[node];
    if (l != r) {
      lazy[node * 2] = lazy[node];
      lazy[2 * node + 1] = lazy[node];
    }
    lazy[node] = 0;
  }
}
void update(int node, int l, int r, int i, int j, int val) {
  refresh(node, l, r);
  if (r < i || l > r || l > j) return;
  if (l >= i && r <= j) {
    lazy[node] = val;
    refresh(node, l, r);
    return;
  }
  int mid = (l + r) / 2;
  update(2 * node, l, mid, i, j, val);
  update(2 * node + 1, mid + 1, r, i, j, val);
  seg[node] = seg[node * 2] | seg[node * 2 + 1];
}
long long query(int node, int l, int r, int i, int j) {
  refresh(node, l, r);
  if (l > r || r < i || l > j) return 0LL;
  if (l >= i && r <= j) {
    return seg[node];
  }
  int mid = (l + r) / 2;
  long long p1 = query(2 * node, l, mid, i, j);
  long long p2 = query(2 * node + 1, mid + 1, r, i, j);
  return (p1 | p2);
}
int main() {
  ios::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> arr[i];
  for (int i = 0; i < n - 1; i++) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    graph[x].push_back(y);
    graph[y].push_back(x);
  }
  dfs(0);
  for (int i = 0; i < n; i++) ele[i] = arr[id[i]];
  build(1, 0, n - 1);
  while (m--) {
    int ty, x, y;
    cin >> ty;
    if (ty == 1) {
      cin >> x >> y;
      --x;
      update(1, 0, n - 1, start[x], en[x], y);
    } else {
      cin >> x;
      --x;
      long long ans = query(1, 0, n - 1, start[x], en[x]);
      cout << __builtin_popcountll(ans) << endl;
    }
  }
}
