← Home
package main

import (
	"bufio"
	"fmt"
	"math/bits"
	"os"
)

var (
	a          []int
	in         []int
	out        []int
	euler      []int
	adj        [][]int
	timer      int
	tree       [400005]SegNode
	m          int
	primesMask [16]uint64
)

type SegNode struct {
	b    [16]uint64
	lazy int
}

func readInt(r *bufio.Reader) int {
	var n int
	var c byte
	for {
		c, _ = r.ReadByte()
		if c >= '0' && c <= '9' {
			n = int(c - '0')
			break
		}
	}
	for {
		c, _ = r.ReadByte()
		if c < '0' || c > '9' {
			break
		}
		n = n*10 + int(c-'0')
	}
	return n
}

func dfs(u, p int) {
	timer++
	in[u] = timer
	euler[timer] = u
	for _, v := range adj[u] {
		if v != p {
			dfs(v, u)
		}
	}
	out[u] = timer
}

func shiftBitset(b *[16]uint64, s int, m int) [16]uint64 {
	if s == 0 {
		return *b
	}
	var tmp [32]uint64
	q := s / 64
	r := s % 64
	if r == 0 {
		for i := 0; i < 16; i++ {
			tmp[i+q] = b[i]
		}
	} else {
		for i := 0; i < 16; i++ {
			tmp[i+q] |= b[i] << r
			tmp[i+q+1] |= b[i] >> (64 - r)
		}
	}

	var high [32]uint64
	mq := m / 64
	mr := m % 64

	for i := mq; i < 32; i++ {
		high[i] = tmp[i]
	}
	if mr > 0 {
		high[mq] &= ^((uint64(1) << mr) - 1)
	}

	for i := mq + 1; i < 32; i++ {
		tmp[i] = 0
	}
	if mr > 0 {
		tmp[mq] &= (uint64(1) << mr) - 1
	} else {
		tmp[mq] = 0
	}

	if mr == 0 {
		for i := mq; i < 32; i++ {
			tmp[i-mq] |= high[i]
		}
	} else {
		for i := mq; i < 32; i++ {
			val := high[i] >> mr
			if i+1 < 32 {
				val |= high[i+1] << (64 - mr)
			}
			tmp[i-mq] |= val
		}
	}

	var res [16]uint64
	for i := 0; i < 16; i++ {
		res[i] = tmp[i]
	}
	return res
}

func build(node, l, r int) {
	if l == r {
		val := a[euler[l]] % m
		tree[node].b[val/64] |= uint64(1) << (val % 64)
		return
	}
	mid := (l + r) / 2
	build(node*2, l, mid)
	build(node*2+1, mid+1, r)
	for i := 0; i < 16; i++ {
		tree[node].b[i] = tree[node*2].b[i] | tree[node*2+1].b[i]
	}
}

func push(node int) {
	if tree[node].lazy != 0 {
		lz := tree[node].lazy

		tree[node*2].b = shiftBitset(&tree[node*2].b, lz, m)
		tree[node*2].lazy = (tree[node*2].lazy + lz) % m

		tree[node*2+1].b = shiftBitset(&tree[node*2+1].b, lz, m)
		tree[node*2+1].lazy = (tree[node*2+1].lazy + lz) % m

		tree[node].lazy = 0
	}
}

func update(node, l, r, ql, qr, x int) {
	if ql <= l && r <= qr {
		tree[node].b = shiftBitset(&tree[node].b, x, m)
		tree[node].lazy = (tree[node].lazy + x) % m
		return
	}
	push(node)
	mid := (l + r) / 2
	if ql <= mid {
		update(node*2, l, mid, ql, qr, x)
	}
	if qr > mid {
		update(node*2+1, mid+1, r, ql, qr, x)
	}
	for i := 0; i < 16; i++ {
		tree[node].b[i] = tree[node*2].b[i] | tree[node*2+1].b[i]
	}
}

func query(node, l, r, ql, qr int) [16]uint64 {
	if ql <= l && r <= qr {
		return tree[node].b
	}
	push(node)
	mid := (l + r) / 2
	var res [16]uint64
	if ql <= mid {
		res = query(node*2, l, mid, ql, qr)
	}
	if qr > mid {
		rightRes := query(node*2+1, mid+1, r, ql, qr)
		for i := 0; i < 16; i++ {
			res[i] |= rightRes[i]
		}
	}
	return res
}

func main() {
	reader := bufio.NewReaderSize(os.Stdin, 1<<20)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	n := readInt(reader)
	m = readInt(reader)

	a = make([]int, n+1)
	for i := 1; i <= n; i++ {
		a[i] = readInt(reader)
	}

	adj = make([][]int, n+1)
	for i := 0; i < n-1; i++ {
		u := readInt(reader)
		v := readInt(reader)
		adj[u] = append(adj[u], v)
		adj[v] = append(adj[v], u)
	}

	in = make([]int, n+1)
	out = make([]int, n+1)
	euler = make([]int, n+1)
	dfs(1, 0)

	isPrime := make([]bool, m)
	for i := 2; i < m; i++ {
		isPrime[i] = true
	}
	for i := 2; i*i < m; i++ {
		if isPrime[i] {
			for j := i * i; j < m; j += i {
				isPrime[j] = false
			}
		}
	}

	for i := 2; i < m; i++ {
		if isPrime[i] {
			primesMask[i/64] |= uint64(1) << (i % 64)
		}
	}

	build(1, 1, n)

	q := readInt(reader)
	for i := 0; i < q; i++ {
		typ := readInt(reader)
		if typ == 1 {
			v := readInt(reader)
			x := readInt(reader)
			x %= m
			if x > 0 {
				update(1, 1, n, in[v], out[v], x)
			}
		} else {
			v := readInt(reader)
			res := query(1, 1, n, in[v], out[v])
			count := 0
			for j := 0; j < 16; j++ {
				count += bits.OnesCount64(res[j] & primesMask[j])
			}
			fmt.Fprintln(writer, count)
		}
	}
}