#include <bits/stdc++.h>
using namespace std;
int n, m, a[100005], b[100005];
vector<int> g[100005];
int next_id, from[100005], to[100005];
bitset<1000> tree[4 * 100005], primes;
int lazy[4 * 100005];
void dfs(int u) {
  from[u] = next_id++;
  b[from[u]] = a[u] % m;
  for (int i = 0; i < g[u].size(); i++)
    if (from[g[u][i]] == -1) dfs(g[u][i]);
  to[u] = next_id;
}
void rot(bitset<1000> &b, int k) {
  b = (b << k) | (b >> (m - k));
  b ^= (b >> m) << m;
}
void init(int no, int l, int r) {
  if (r - l == 1) {
    tree[no].set(b[l]);
    return;
  }
  int m = (l + r) / 2;
  init(2 * no, l, m);
  init(2 * no + 1, m, r);
  tree[no] = tree[2 * no] | tree[2 * no + 1];
}
void prop(int no, int l, int r) {
  lazy[no] %= m;
  if (lazy[no] > 0) {
    rot(tree[no], lazy[no]);
    if (r - l > 1) {
      lazy[2 * no] += lazy[no];
      lazy[2 * no + 1] += lazy[no];
    }
    lazy[no] = 0;
  }
}
void update(int no, int l, int r, int a, int b, int x) {
  if (a <= l && r <= b) {
    lazy[no] += x;
    return;
  }
  prop(no, l, r);
  int m = (l + r) / 2;
  if (a < m) update(2 * no, l, m, a, b, x);
  if (m < b) update(2 * no + 1, m, r, a, b, x);
  prop(2 * no, l, m);
  prop(2 * no + 1, m, r);
  tree[no] = tree[2 * no] | tree[2 * no + 1];
}
bitset<1000> query(int no, int l, int r, int a, int b) {
  prop(no, l, r);
  if (a <= l && r <= b) return tree[no];
  int m = (l + r) / 2;
  bitset<1000> ret;
  if (a < m) ret = query(2 * no, l, m, a, b);
  if (m < b) ret |= query(2 * no + 1, m, r, a, b);
  return ret;
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; i++) scanf("%d", &a[i]);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    u--, v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  memset(from, -1, sizeof(from));
  next_id = 0;
  dfs(0);
  memset(lazy, 0, sizeof(lazy));
  init(1, 0, n);
  primes[2].flip();
  for (int i = 3; i < m; i += 2) primes.set(i);
  for (int i = 3; i * i < m; i += 2)
    if (primes[i])
      for (int j = i * i; j < m; j += i) primes.reset(j);
  int q, op, v, x;
  scanf("%d", &q);
  while (q--) {
    scanf("%d %d", &op, &v);
    v--;
    if (op == 1) {
      scanf("%d", &x);
      update(1, 0, n, from[v], to[v], x % m);
    } else {
      bitset<1000> bs = query(1, 0, n, from[v], to[v]) & primes;
      printf("%d\n", (int)bs.count());
    }
  }
}
