package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
var sum []int64
var swapped [20]bool
func build(v int, L int, R int, arr []int64) {
if L == R {
sum[v] = arr[L]
return
}
M := L + (R-L)/2
build(2*v, L, M, arr)
build(2*v+1, M+1, R, arr)
sum[v] = sum[2*v] + sum[2*v+1]
}
func update(v int, d int, L int, R int, x int, k int64) {
if L == R {
sum[v] = k
return
}
M := L + (R-L)/2
left := 2 * v
right := 2*v + 1
if swapped[d] {
left = 2*v + 1
right = 2 * v
}
if x <= M {
update(left, d-1, L, M, x, k)
} else {
update(right, d-1, M+1, R, x, k)
}
sum[v] = sum[2*v] + sum[2*v+1]
}
func query(v int, d int, L int, R int, l int, r int) int64 {
if l <= L && R <= r {
return sum[v]
}
M := L + (R-L)/2
left := 2 * v
right := 2*v + 1
if swapped[d] {
left = 2*v + 1
right = 2 * v
}
var res int64 = 0
if l <= M {
res += query(left, d-1, L, M, l, r)
}
if r > M {
res += query(right, d-1, M+1, R, l, r)
}
return res
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Buffer(make([]byte, 1024*1024), 1024*1024*10)
scanner.Split(bufio.ScanWords)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
nextInt := func() int {
scanner.Scan()
v, _ := strconv.Atoi(scanner.Text())
return v
}
nextInt64 := func() int64 {
scanner.Scan()
v, _ := strconv.ParseInt(scanner.Text(), 10, 64)
return v
}
n := nextInt()
q := nextInt()
sz := 1 << n
arr := make([]int64, sz+1)
for i := 1; i <= sz; i++ {
arr[i] = nextInt64()
}
sum = make([]int64, 4*sz+1)
build(1, 1, sz, arr)
for i := 0; i < q; i++ {
t := nextInt()
if t == 1 {
x := nextInt()
k := nextInt64()
update(1, n, 1, sz, x, k)
} else if t == 2 {
k := nextInt()
for j := 1; j <= k; j++ {
swapped[j] = !swapped[j]
}
} else if t == 3 {
k := nextInt()
swapped[k+1] = !swapped[k+1]
} else if t == 4 {
l := nextInt()
r := nextInt()
ans := query(1, n, 1, sz, l, r)
fmt.Fprintln(out, ans)
}
}
}