import sys from math import isqrt def main(): data = sys.stdin.buffer.read().split() idx = 0 n, q = int(data[idx]), int(data[idx+1]); idx += 2 A = [int(data[idx+i]) for i in range(n)]; idx += n size = 1 while size < n: size <<= 1 INF = -1 sm = [0] * (2 * size) mn = [0] * (2 * size) mx = [0] * (2 * size) lazy = [INF] * (2 * size) for i in range(n): sm[size+i] = mn[size+i] = mx[size+i] = A[i] for i in range(size-1, 0, -1): sm[i] = sm[2*i] + sm[2*i+1] mn[i] = min(mn[2*i], mn[2*i+1]) mx[i] = max(mx[2*i], mx[2*i+1]) def apply_node(v, l, r, val): sm[v] = val * (r - l) mn[v] = val mx[v] = val lazy[v] = val def push(v, l, r): if lazy[v] != INF: mid = (l + r) >> 1 apply_node(2*v, l, mid, lazy[v]) apply_node(2*v+1, mid, r, lazy[v]) lazy[v] = INF def pull(v): sm[v] = sm[2*v] + sm[2*v+1] mn[v] = min(mn[2*v], mn[2*v+1]) mx[v] = max(mx[2*v], mx[2*v+1]) def node_range(v): depth = v.bit_length() - 1 seg_size = size >> depth pos = v - (1 << depth) return pos * seg_size, pos * seg_size + seg_size def push_path(ql, qr): nodes = [] lo, hi = ql + size, qr + size lo >>= 1; hi = (hi-1) >> 1 while lo > 0: nodes.append(lo) nodes.append(hi) lo >>= 1; hi >>= 1 for v in reversed(nodes): l, r = node_range(v) push(v, l, r) def query_sum(ql, qr): push_path(ql, qr) res = 0 l, r = ql + size, qr + size while l < r: if l & 1: res += sm[l]; l += 1 if r & 1: r -= 1; res += sm[r] l >>= 1; r >>= 1 return res def update_assign(ql, qr, val): push_path(ql, qr) l, r = ql + size, qr + size l0, r0 = l, r while l < r: if l & 1: nl, nr = node_range(l) apply_node(l, nl, nr, val); l += 1 if r & 1: r -= 1 nl, nr = node_range(r) apply_node(r, nl, nr, val) l >>= 1; r >>= 1 l, r = l0 >> 1, (r0-1) >> 1 while l > 0: if lazy[l] == INF: pull(l) if lazy[r] == INF: pull(r) l >>= 1; r >>= 1 def update_isqrt_range(ql, qr): stack = [(1, 0, size, False)] while stack: v, l, r, returning = stack.pop() if returning: pull(v) continue if ql >= r or l >= qr: continue sq_mn = isqrt(mn[v]) sq_mx = isqrt(mx[v]) if ql <= l and r <= qr and sq_mn == sq_mx: apply_node(v, l, r, sq_mn) continue if l + 1 == r: sm[v] = mn[v] = mx[v] = sq_mn lazy[v] = INF continue push(v, l, r) mid = (l + r) >> 1 stack.append((v, l, r, True)) stack.append((2*v+1, mid, r, False)) stack.append((2*v, l, mid, False)) out = [] for _ in range(q): t = int(data[idx]); idx += 1 if t == 0: l, r = int(data[idx]), int(data[idx+1]); idx += 2 out.append(query_sum(l, r)) elif t == 1: l, r, x = int(data[idx]), int(data[idx+1]), int(data[idx+2]); idx += 3 update_assign(l, r, x) else: l, r = int(data[idx]), int(data[idx+1]); idx += 2 update_isqrt_range(l, r) sys.stdout.write('\n'.join(map(str, out)) + '\n') main()