class SegmentTree(): def __init__(self, arr, func=min, ie=2**63): self.n = 2**(len(arr) - 1).bit_length() self.ie = ie self.func = func self.tree = [ie for _ in range(2 * self.n)] for i in range(len(arr)): self.tree[self.n + i - 1] = arr[i] for i in range(self.n - 1)[::-1]: self.tree[i] = func(self.tree[2 * i + 1], self.tree[2 * i + 2]) def set(self, index, x): index += self.n - 1 self.tree[index] = x while index: index = (index - 1) // 2 self.tree[index] = self.func(self.tree[2 * index + 1], self.tree[2 * index + 2]) def query(self, left, right): if right <= left: return self.ie left += self.n - 1 right += self.n - 2 tmp_l = self.ie tmp_r = self.ie while right - left > 1: if left & 1 == 0: tmp_l = self.func(tmp_l, self.tree[left]) if right & 1 == 1: tmp_r = self.func(self.tree[right], tmp_r) right -= 1 left = left // 2 right = (right - 1) // 2 if left == right: tmp_l = self.func(tmp_l, self.tree[left]) else: tmp_l = self.func( self.func(tmp_l, self.tree[left]), self.tree[right]) return self.func(tmp_l, tmp_r) class SegmentTreeDual(): def __init__(self, arr, op=lambda x, y: y if y != -1 else x, ie=-1): self.h = (len(arr) - 1).bit_length() self.n = 2**self.h self.ie = ie self.op = op self.val = [ie for _ in range(self.n)] self.laz = [ie for _ in range(2 * self.n)] for i in range(len(arr)): self.val[i] = arr[i] def propagate(self, k): if self.laz[k] == self.ie: return if self.n <= k: self.val[k - self.n] = self.op(self.val[k - self.n], self.laz[k]) self.laz[k] = self.ie else: self.laz[2 * k] = self.op(self.laz[2 * k], self.laz[k]) self.laz[2 * k + 1] = self.op(self.laz[2 * k + 1], self.laz[k]) self.laz[k] = self.ie def update(self, left, right, x): left += self.n right += self.n ''' for i in range(self.h)[::-1]: self.propagate(left >> i) self.propagate(right >> i) ''' while right - left > 0: if right & 1: right -= 1 self.laz[right] = self.op(self.laz[right], x) if left & 1: self.laz[left] = self.op(self.laz[left], x) left += 1 left >>= 1 right >>= 1 def get(self, index): res = self.val[index] index += self.n while index > 0: res = self.op(res, self.laz[index]) index //= 2 return res import sys input = sys.stdin.readline from operator import add N, Q = map(int, input().split()) A = list(map(int, input().split())) B = [A[i] != A[i + 1] for i in range(N - 1)] std = SegmentTreeDual(A, add, 0) st = SegmentTree(B, add, 0) ans = [] for _ in range(Q): q = list(map(int, input().split())) if q[0] == 1: l, r, x = q[1:] std.update(l - 1, r, x) if l > 1: if std.get(l - 1) == std.get(l - 2): st.set(l - 2, 0) else: st.set(l - 2, 1) if r < N: if std.get(r) == std.get(r - 1): st.set(r - 1, 0) else: st.set(r - 1, 1) if q[0] == 2: l, r = q[1:] ans.append(st.query(l - 1, r - 1) + 1) print('\n'.join(map(str, ans)))