#include <bits/stdc++.h>
using namespace std;
const long double eps = 1e-12;
const int maxn = 100000 + 3;
int n, m, Q;
vector<int> V[maxn];
int a[maxn];
void ReadData() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for (int i = 1; i <= n - 1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    V[u].push_back(v);
    V[v].push_back(u);
  }
  scanf("%d", &Q);
}
int timer = 0, tin[maxn], tout[maxn], euler[maxn];
inline void dfs(const int u, const int prev) {
  tin[u] = ++timer;
  euler[timer] = u;
  for (int i = 0; i < ((int)V[u].size()); i++) {
    int v = V[u][i];
    if (v == prev) continue;
    dfs(v, u);
  }
  tout[u] = timer;
}
int l[maxn * 4], h[maxn * 4], lazy[maxn * 4];
bitset<1000> it[maxn * 4], P[1004];
void Rotate(bitset<1000> &a, int r) {
  if (!r) return;
  int l = m - r;
  a = (((a & P[r]) >> l) | ((a << r) & P[m]));
}
void Build(const int &x, const int &low, const int &high) {
  l[x] = low;
  h[x] = high;
  if (low == high) {
    it[x] = bitset<1000>(0);
    it[x].set(a[euler[low]] % m, 1);
  } else {
    int mid = (low + high) >> 1;
    Build((x << 1), low, mid);
    Build(((x << 1) | 1), mid + 1, high);
    it[x] = (it[(x << 1)] | it[((x << 1) | 1)]);
  }
}
void Add(int x, int val) {
  lazy[x] = (lazy[x] + val) % m;
  Rotate(it[x], val);
}
void Down(int x) {
  if (lazy[x]) {
    Add((x << 1), lazy[x]);
    Add(((x << 1) | 1), lazy[x]);
    lazy[x] = 0;
  }
}
void Update(const int x, const int u, const int v, int val) {
  if (l[x] > v || h[x] < u) return;
  if (u <= l[x] && h[x] <= v) {
    Add(x, val);
    return;
  }
  Down(x);
  Update((x << 1), u, v, val);
  Update(((x << 1) | 1), u, v, val);
  it[x] = it[(x << 1)] | it[((x << 1) | 1)];
}
bitset<1000> Query(const int x, const int u, const int v) {
  if (l[x] > v || h[x] < u) return P[0];
  if (u <= l[x] && h[x] <= v) return it[x];
  Down(x);
  return Query((x << 1), u, v) | Query(((x << 1) | 1), u, v);
}
bool isPrime(int x) {
  if (x == 2) return true;
  if (x == 2 || x % 2 == 0) return false;
  for (int i = 3; i * i <= x; i += 2)
    if (x % i == 0) return false;
  return true;
}
vector<int> Prime;
void Process() {
  for (int i = 1; i <= m; i++) P[i] = P[i - 1], P[i].set(m - i, 1);
  for (int i = 2; i <= m - 1; i++)
    if (isPrime(i)) Prime.push_back(i);
  dfs(1, 0);
  Build(1, 1, n);
  while (Q--) {
    int type;
    scanf("%d", &type);
    if (type == 1) {
      int u, x;
      scanf("%d%d", &u, &x);
      Update(1, tin[u], tout[u], x % m);
    } else {
      int u;
      scanf("%d", &u);
      bitset<1000> lol = Query(1, tin[u], tout[u]);
      int res = 0;
      for (int i = 0; i < ((int)Prime.size()); i++)
        if (lol[Prime[i]]) res++;
      cout << res << "\n";
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  ReadData();
  Process();
}
