#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int maxn = (1 << 18) + 5;
int a[maxn], stu[20];
struct node {
  int l, r;
  long long sum;
} tree[maxn * 4];
void pushup(int k) { tree[k].sum = tree[k << 1].sum + tree[k << 1 | 1].sum; }
void build(int k, int l, int r) {
  tree[k].l = l;
  tree[k].r = r;
  if (l == r) {
    tree[k].sum = a[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(k << 1, l, mid);
  build(k << 1 | 1, mid + 1, r);
  pushup(k);
}
void update(int k, int p, int x, int d) {
  if (tree[k].l == tree[k].r) {
    tree[k].sum = x;
    return;
  }
  int mid = (tree[k].l + tree[k].r) >> 1;
  if (!stu[d]) {
    if (p <= mid)
      update(k << 1, p, x, d - 1);
    else
      update(k << 1 | 1, p, x, d - 1);
  } else {
    if (p <= mid)
      update(k << 1 | 1, p - tree[k].l + mid + 1, x, d - 1);
    else
      update(k << 1, p - mid - 1 + tree[k].l, x, d - 1);
  }
  pushup(k);
}
long long query(int k, int l, int r, int d) {
  if (tree[k].l == l && tree[k].r == r) {
    return tree[k].sum;
  }
  int mid = (tree[k].l + tree[k].r) >> 1;
  if (!stu[d]) {
    if (mid >= r)
      return query(k << 1, l, r, d - 1);
    else if (mid < l)
      return query(k << 1 | 1, l, r, d - 1);
    return query(k << 1, l, mid, d - 1) + query(k << 1 | 1, mid + 1, r, d - 1);
  } else {
    if (mid >= r)
      return query(k << 1 | 1, l - tree[k].l + mid + 1, r - tree[k].l + mid + 1,
                   d - 1);
    else if (mid < l)
      return query(k << 1, l - mid - 1 + tree[k].l, r - mid - 1 + tree[k].l,
                   d - 1);
    return query(k << 1, tree[k].l, r - mid - 1 + tree[k].l, d - 1) +
           query(k << 1 | 1, l - tree[k].l + mid + 1, tree[k].r, d - 1);
  }
}
int main() {
  int dep, m;
  scanf("%d%d", &dep, &m);
  int n = 1 << dep;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  build(1, 1, n);
  int op, x, y;
  while (m--) {
    scanf("%d%d", &op, &x);
    if (op == 1 || op == 4) scanf("%d", &y);
    if (op == 1) {
      update(1, x, y, dep);
    } else if (op == 2) {
      for (int i = 0; i <= x; i++) stu[i] ^= 1;
    } else if (op == 3) {
      stu[x + 1] ^= 1;
    } else {
      printf("%lld\n", query(1, x, y, dep));
    }
  }
  return 0;
}
