#include <bits/stdc++.h>
using namespace std;
const int MAXS = 1e6, MAXN = 2e5 + 100;
inline bool isPrime(int x) {
  for (int i = 2; i * i <= x; i++)
    if (x % i == 0) return false;
  return true;
}
int n, m;
bitset<1010> seg[MAXS], prime;
int lazy[MAXS], cnt[MAXS];
int a[MAXN], s[MAXN], e[MAXN], at[MAXN];
vector<int> G[MAXN];
bitset<1010> pull(bitset<1010> a, int cnta, bitset<1010> b, int cntb) {
  return ((a << cnta) | (b << cntb) | (a >> (m - cnta)) | (b >> (m - cntb)));
}
void apply(int x, int q) {
  lazy[x] = (lazy[x] + q) % m;
  cnt[x] = (cnt[x] + q) % m;
}
inline void relax(int x) {
  int l = 2 * x, r = l + 1;
  apply(l, lazy[x]);
  apply(r, lazy[x]);
  lazy[x] = 0;
}
void add(int ql, int qr, int q, int x = 1, int xl = 0, int xr = n) {
  if (xl >= qr || xr <= ql) return;
  if (xl >= ql && xr <= qr) {
    apply(x, q);
    return;
  }
  int mid = (xl + xr) / 2, l = 2 * x, r = l + 1;
  relax(x);
  add(ql, qr, q, l, xl, mid);
  add(ql, qr, q, r, mid, xr);
  seg[x] = pull(seg[l], cnt[l], seg[r], cnt[r]);
  cnt[x] = 0;
}
void build(int x, int xl, int xr) {
  if (xr - xl == 1) {
    a[at[xl]] %= m;
    seg[x][a[at[xl]]] = 1;
    return;
  }
  int mid = (xl + xr) / 2, l = 2 * x, r = l + 1;
  build(l, xl, mid);
  build(r, mid, xr);
  seg[x] = (seg[l] | seg[r]);
}
bitset<1010> get(int ql, int qr, int x = 1, int xl = 0, int xr = n) {
  if (xl >= qr || xr <= ql) return bitset<1010>();
  if (xl >= ql && xr <= qr) {
    return pull(seg[x], cnt[x], bitset<1010>(), 0);
  }
  relax(x);
  int mid = (xl + xr) / 2, l = 2 * x, r = l + 1;
  return (get(ql, qr, l, xl, mid) | get(ql, qr, r, mid, xr));
}
int indN = 0;
void dfs(int u, int p) {
  at[indN] = u;
  s[u] = indN++;
  for (int i = 0; i < G[u].size(); i++)
    if (G[u][i] != p) dfs(G[u][i], u);
  e[u] = indN;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++)
    if (i > 1 && isPrime(i)) prime[i] = 1;
  for (int i = 0; i < n; i++) scanf("%d", &a[i]);
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--;
    v--;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  dfs(0, -1);
  build(1, 0, n);
  int q;
  scanf("%d", &q);
  while (q--) {
    int t, x;
    scanf("%d%d", &t, &x);
    x--;
    if (t == 1) {
      int y;
      scanf("%d", &y);
      y %= m;
      add(s[x], e[x], y);
    } else {
      printf("%d\n", (get(s[x], e[x]) & prime).count());
    }
  }
}
