"""Point updates and range products for an arbitrary monoid. Use this when values change one position at a time and a half-open interval must be folded with an associative operation. ``max_right`` and ``min_left`` also find the first boundary where a monotone predicate stops holding. """ class SegTree: __slots__ = ("n", "size", "log", "data", "op", "identity") def __init__(self, op, identity, values): if isinstance(values, int): n = values values = [identity] * n else: values = list(values) n = len(values) size = 1 << (n - 1).bit_length() if n else 1 data = [identity] * (size << 1) data[size : size + n] = values for node in range(size - 1, 0, -1): data[node] = op(data[node << 1], data[node << 1 | 1]) self.n = n self.size = size self.log = size.bit_length() - 1 self.data = data self.op = op self.identity = identity def set(self, index, value): node = index + self.size data = self.data data[node] = value op = self.op node >>= 1 while node: data[node] = op(data[node << 1], data[node << 1 | 1]) node >>= 1 def add(self, index, value): """indexの現在値をop(value, current)で置き換える。O(log N)。""" node = index + self.size data = self.data op = self.op data[node] = op(value, data[node]) node >>= 1 while node: data[node] = op(data[node << 1], data[node << 1 | 1]) node >>= 1 def get(self, index): return self.data[index + self.size] def tolist(self): """現在の要素列をlistで返す。O(N)。""" return self.data[self.size:self.size + self.n] def __str__(self): return str(self.tolist()) def __repr__(self): return "SegTree(%r)" % self.tolist() def prod(self, left, right): left += self.size right += self.size first = self.identity second = self.identity data = self.data op = self.op while left < right: if left & 1: first = op(first, data[left]) left += 1 if right & 1: right -= 1 second = op(data[right], second) left >>= 1 right >>= 1 return op(first, second) query = prod def all_prod(self): return self.data[1] def max_right(self, left, predicate): if left == self.n: return self.n left += self.size value = self.identity data = self.data op = self.op while True: while not left & 1: left >>= 1 merged = op(value, data[left]) if not predicate(merged): while left < self.size: left <<= 1 merged = op(value, data[left]) if predicate(merged): value = merged left += 1 return min(left - self.size, self.n) value = merged left += 1 if left & -left == left: break return self.n def min_left(self, right, predicate): if right == 0: return 0 right += self.size value = self.identity data = self.data op = self.op while True: right -= 1 while right > 1 and right & 1: right >>= 1 merged = op(data[right], value) if not predicate(merged): while right < self.size: right = right << 1 | 1 merged = op(data[right], value) if predicate(merged): value = merged right -= 1 return max(0, right + 1 - self.size) value = merged if right & -right == right: break return 0 def __getitem__(self, index): return self.get(index) # haru: pypy import sys input = sys.stdin.readline II = lambda : int(input()) MI = lambda : map(int, input().split()) LI = lambda : [int(a) for a in input().split()] SI = lambda : input().rstrip() LLI = lambda n : [[int(a) for a in input().split()] for _ in range(n)] LSI = lambda n : [input().rstrip() for _ in range(n)] MI_1 = lambda : map(lambda x:int(x)-1, input().split()) LI_1 = lambda : [int(a)-1 for a in input().split()] mod = 998244353 inf = 1001001001001001001 ordalp = lambda s : ord(s)-65 if s.isupper() else ord(s)-97 ordallalp = lambda s : ord(s)-39 if s.isupper() else ord(s)-97 yes = lambda : print("Yes") no = lambda : print("No") yn = lambda flag : print("Yes" if flag else "No") prinf = lambda ans : print(ans if ans < 1000001001001001001 else -1) alplow = "abcdefghijklmnopqrstuvwxyz" alpup = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" alpall = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" URDL = {'U':(-1,0), 'R':(0,1), 'D':(1,0), 'L':(0,-1)} DIR_4 = [[-1,0],[0,1],[1,0],[0,-1]] DIR_8 = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]] DIR_BISHOP = [[-1,1],[1,1],[1,-1],[-1,-1]] prime60 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59] sys.set_int_max_str_digits(0) # sys.setrecursionlimit(10**6) # import pypyjit # pypyjit.set_param('max_unroll_recursion=-1') from collections import defaultdict,deque from heapq import heappop,heappush from bisect import bisect_left,bisect_right DD = defaultdict BSL = bisect_left BSR = bisect_right """ この必要十分はしっていて すべてについて S / ai が 2 べきかつ prefix / ai とかだっけか --- モノイドですか? -> まじでわからん笑 区間内で要請したいこと ひとつめ - 区間和 - もっとも大きい値 - それ以下がすべてべきである bool ふたつめ - ? mod ? がたされれば一致するか? - 2 つ目は最大値のハズ """ def op(x, y): if x[0] == -1: return y if y[0] == -1: return x r0 = x[0] + y[0] r2 = 0 r3 = -1 if x[1] == y[1]: r1 = x[1] r2 = x[2] & y[2] if (y[3] - x[0] - x[3]) % x[1] == 0: r3 = x[3] elif x[1] < y[1]: # 後ろが大きい r1 = y[1] d = y[1]//x[1] if y[1] % x[1] == 0 and (d).bit_count() == 1: r2 = x[2] & y[2] if (y[3] - x[0] - x[3]) % x[1] == 0: r3 = (y[3] - x[0]) % y[1] else: # 前が大きい r1 = x[1] if x[1] % y[1] == 0 and (x[1]//y[1]).bit_count() == 1: r2 = x[2] & y[2] if (y[3] - x[0] - x[3]) % y[1] == 0: r3 = x[3] # print(x, y, (r0, r1, r2, r3)) return (r0, r1, r2, r3) n, q = MI() a = LI() seg = SegTree(op, (-1, -1, -1, -1), [(x, x, 1, 0) for x in a]) for i in range(q): t, k, x = MI() k -= 1 if t == 1: seg.set(k, (x, x, 1, 0)) else: ans = seg.prod(k, x) if ans[0] % ans[1] == 0 and (ans[0] // ans[1]).bit_count() == 1 and ans[2] and ans[3] == 0: print("Yes") else: print("No") # print(seg, ans, [seg[i][0] for i in range(k, x)])