← Home
package main

import (
	"bufio"
	"io"
	"os"
	"strconv"
	"strings"
)

var data []byte
var idx int
var seg []int64
var mask int

func nextInt() int {
	n := len(data)
	for idx < n && (data[idx] < '0' || data[idx] > '9') && data[idx] != '-' {
		idx++
	}
	sign := 1
	if data[idx] == '-' {
		sign = -1
		idx++
	}
	val := 0
	for idx < n && data[idx] >= '0' && data[idx] <= '9' {
		val = val*10 + int(data[idx]-'0')
		idx++
	}
	return val * sign
}

func build(node, level, start int, arr []int64) {
	if level == 0 {
		seg[node] = arr[start]
		return
	}
	half := 1 << (level - 1)
	build(node<<1, level-1, start, arr)
	build(node<<1|1, level-1, start+half, arr)
	seg[node] = seg[node<<1] + seg[node<<1|1]
}

func update(node, level, pos int, val int64) {
	if level == 0 {
		seg[node] = val
		return
	}
	half := 1 << (level - 1)
	leftNode, rightNode := node<<1, node<<1|1
	if (mask>>uint(level-1))&1 == 1 {
		leftNode, rightNode = rightNode, leftNode
	}
	if pos < half {
		update(leftNode, level-1, pos, val)
	} else {
		update(rightNode, level-1, pos-half, val)
	}
	seg[node] = seg[node<<1] + seg[node<<1|1]
}

func query(node, level, l, r int) int64 {
	if l == 0 && r == (1<<level)-1 {
		return seg[node]
	}
	if level == 0 {
		return seg[node]
	}
	half := 1 << (level - 1)
	leftNode, rightNode := node<<1, node<<1|1
	if (mask>>uint(level-1))&1 == 1 {
		leftNode, rightNode = rightNode, leftNode
	}
	if r < half {
		return query(leftNode, level-1, l, r)
	}
	if l >= half {
		return query(rightNode, level-1, l-half, r-half)
	}
	return query(leftNode, level-1, l, half-1) + query(rightNode, level-1, 0, r-half)
}

func main() {
	data, _ = io.ReadAll(os.Stdin)
	n := nextInt()
	q := nextInt()
	size := 1 << n
	arr := make([]int64, size)
	for i := 0; i < size; i++ {
		arr[i] = int64(nextInt())
	}
	seg = make([]int64, size*4)
	build(1, n, 0, arr)

	var out strings.Builder
	out.Grow(q * 20)

	for i := 0; i < q; i++ {
		t := nextInt()
		switch t {
		case 1:
			x := nextInt() - 1
			k := int64(nextInt())
			update(1, n, x, k)
		case 2:
			k := nextInt()
			mask ^= (1 << k) - 1
		case 3:
			k := nextInt()
			mask ^= 1 << k
		case 4:
			l := nextInt() - 1
			r := nextInt() - 1
			out.WriteString(strconv.FormatInt(query(1, n, l, r), 10))
			out.WriteByte('\n')
		}
	}

	w := bufio.NewWriterSize(os.Stdout, 1<<20)
	w.WriteString(out.String())
	w.Flush()
}