package main
import (
"bufio"
"math/rand"
"os"
)
const W = 40
func readInt(reader *bufio.Reader) int {
res := 0
for {
b, err := reader.ReadByte()
if err != nil {
return res
}
if b >= '0' && b <= '9' {
res = int(b - '0')
break
}
}
for {
b, err := reader.ReadByte()
if err != nil || b < '0' || b > '9' {
break
}
res = res*10 + int(b-'0')
}
return res
}
func main() {
reader := bufio.NewReaderSize(os.Stdin, 1<<20)
writer := bufio.NewWriterSize(os.Stdout, 1<<20)
defer writer.Flush()
n := readInt(reader)
q := readInt(reader)
idMap := make(map[int]int)
var vals [][W]uint32
getID := func(x int) int {
if id, ok := idMap[x]; ok {
return id
}
id := len(vals)
idMap[x] = id
var v [W]uint32
for i := 0; i < W; i++ {
v[i] = rand.Uint32()
}
vals = append(vals, v)
return id
}
a := make([]int, n+1)
tree := make([][W]uint64, n+1)
for i := 1; i <= n; i++ {
x := readInt(reader)
id := getID(x)
a[i] = id
for w := 0; w < W; w++ {
tree[i][w] += uint64(vals[id][w])
}
}
for i := 1; i <= n; i++ {
p := i + (i & -i)
if p <= n {
for w := 0; w < W; w++ {
tree[p][w] += tree[i][w]
}
}
}
for i := 0; i < q; i++ {
typ := readInt(reader)
if typ == 1 {
idx := readInt(reader)
x := readInt(reader)
oldID := a[idx]
newID := getID(x)
if oldID != newID {
a[idx] = newID
for j := idx; j <= n; j += j & -j {
for w := 0; w < W; w++ {
tree[j][w] += uint64(vals[newID][w])
tree[j][w] -= uint64(vals[oldID][w])
}
}
}
} else {
l := readInt(reader)
r := readInt(reader)
k := readInt(reader)
if (r-l+1)%k != 0 {
writer.WriteString("NO\n")
} else if k == 1 {
writer.WriteString("YES\n")
} else {
var sum [W]uint64
for j := r; j > 0; j -= j & -j {
for w := 0; w < W; w++ {
sum[w] += tree[j][w]
}
}
for j := l - 1; j > 0; j -= j & -j {
for w := 0; w < W; w++ {
sum[w] -= tree[j][w]
}
}
ok := true
uk := uint64(k)
for w := 0; w < W; w++ {
if sum[w]%uk != 0 {
ok = false
break
}
}
if ok {
writer.WriteString("YES\n")
} else {
writer.WriteString("NO\n")
}
}
}
}
}