#include <bits/stdc++.h>
using namespace std;
int n, q, position;
long long seg[1 << 20];
long long query(int s, int e, int l, int r, int node, int lev) {
  if (position & (1 << lev)) {
    l = s + e - l;
    r = s + e - r;
    swap(l, r);
  }
  if (e < l || r < s) return 0LL;
  if (s == l && e == r) return seg[node];
  int m = (s + e) / 2;
  if (r <= m) return query(s, m, l, r, node * 2, lev - 1);
  if (l > m) return query(m + 1, e, l, r, node * 2 + 1, lev - 1);
  return query(s, m, l, m, node * 2, lev - 1) +
         query(m + 1, e, m + 1, r, node * 2 + 1, lev - 1);
}
int main() {
  scanf("%d %d", &n, &q);
  int sze = 1 << n;
  for (int i = sze; i < 2 * sze; i++) scanf("%lld", &seg[i]);
  for (int i = sze - 1; i > 0; i--) seg[i] = seg[2 * i] + seg[2 * i + 1];
  while (q--) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      int x;
      long long k;
      scanf("%d %lld", &x, &k);
      x--;
      int l = 0, r = sze - 1;
      for (int i = n; i > 0; i--) {
        if (position & (1 << i)) x = l + r - x;
        int m = (l + r) / 2;
        if (x <= m)
          r = m;
        else
          l = m + 1;
      }
      x += sze;
      long long diff = k - seg[x];
      while (x) {
        seg[x] += diff;
        x /= 2;
      }
    } else if (t == 2) {
      int k;
      scanf("%d", &k);
      position ^= (1 << k);
    } else if (t == 3) {
      int k;
      scanf("%d", &k);
      position ^= (3 << k);
    } else {
      int l, r;
      scanf("%d %d", &l, &r);
      printf("%lld\n", query(0, sze - 1, l - 1, r - 1, 1, n));
    }
  }
}
