#include <bits/stdc++.h>
using namespace std;
struct Segment {
  long long sum;
};
Segment seg[8 * 500005];
long long n, q, a[500005], rev[500005];
long long lson(long long p) { return 2 * p; }
long long rson(long long p) { return 2 * p + 1; }
void push_up(long long p) { seg[p].sum = seg[lson(p)].sum + seg[rson(p)].sum; }
void build(long long l, long long r, long long p) {
  if (l == r) {
    seg[p].sum = a[l];
    return;
  }
  long long mid = (l + r) / 2;
  build(l, mid, lson(p));
  build(mid + 1, r, rson(p));
  push_up(p);
}
void update(long long l, long long r, long long p, long long dep, long long x,
            long long k) {
  if (l == r) {
    seg[p].sum = k;
    return;
  }
  long long mid = (l + r) / 2;
  if (x <= mid)
    update(l, mid, lson(p) ^ rev[dep], dep - 1, x, k);
  else
    update(mid + 1, r, rson(p) ^ rev[dep], dep - 1, x, k);
  push_up(p);
}
long long query(long long l, long long r, long long p, long long dep,
                long long nl, long long nr) {
  long long res = 0;
  if (l >= nl && r <= nr) {
    return seg[p].sum;
  }
  long long mid = (l + r) / 2;
  if (nl <= mid) res += query(l, mid, lson(p) ^ rev[dep], dep - 1, nl, nr);
  if (nr > mid) res += query(mid + 1, r, rson(p) ^ rev[dep], dep - 1, nl, nr);
  push_up(p);
  return res;
}
signed main(void) {
  cin >> n >> q;
  long long d = n;
  n = (1 << n);
  for (long long i = 1; i <= n; i++) cin >> a[i];
  build(1, n, 1);
  while (q--) {
    long long opt;
    cin >> opt;
    if (opt == 1) {
      long long x, k;
      cin >> x >> k;
      update(1, n, 1, d, x, k);
    }
    if (opt == 2) {
      long long k;
      cin >> k;
      for (long long i = 0; i <= k; i++) rev[i] ^= 1;
    }
    if (opt == 3) {
      long long k;
      cin >> k;
      rev[k + 1] ^= 1;
    }
    if (opt == 4) {
      long long l, r;
      cin >> l >> r;
      cout << query(1, n, 1, d, l, r) << '\n';
    }
  }
  return 0;
}
