#include <bits/stdc++.h>
using namespace std;
long long int power_mod(long long int a, long long int x) {
  if (x == 0) return 1;
  long long int y = power_mod(a, x / 2);
  long long int ans = (y * y) % 1000000007;
  if (x % 2) ans = (ans * a) % 1000000007;
  return ans;
}
long long int inv(long long int a) { return power_mod(a, 1000000007 - 2); }
long long int power(long long int a, long long int x) {
  if (x == 0) return 1;
  long long int y = power(a, x / 2);
  long long int ans = (y * y);
  if (x % 2) ans *= a;
  return ans;
}
const long long int N = 1 + 1ll << 18;
int level[20] = {};
long long int a[N] = {};
long long int tree[4 * N] = {};
void build(long long int st, long long int ed, long long int node) {
  if (st == ed) {
    tree[node] = a[st];
    return;
  }
  long long int mid = (st + ed) / 2;
  long long int left = 2 * node;
  long long int right = 2 * node + 1;
  build(st, mid, left);
  build(mid + 1, ed, right);
  tree[node] = tree[left] + tree[right];
}
inline void update(long long int st, long long int ed, long long int node,
                   long long int dep, long long int i) {
  if (i < st or i > ed) return;
  if (st == ed) {
    if (st == i) {
      tree[node] = a[st];
    }
    return;
  }
  long long int mid = (st + ed) / 2;
  long long int left = 2 * node;
  long long int right = 2 * node + 1;
  if (level[dep]) {
    swap(left, right);
  }
  update(st, mid, left, dep - 1, i);
  update(mid + 1, ed, right, dep - 1, i);
  tree[node] = tree[left] + tree[right];
}
inline long long int query(long long int st, long long int ed, long long int l,
                           long long int r, long long int node,
                           long long int dep) {
  if (ed < l or st > r) return 0;
  if (st >= l and ed <= r) return tree[node];
  long long int mid = (st + ed) / 2;
  long long int left = 2 * node;
  long long int right = 2 * node + 1;
  long long int x = st, y = mid;
  long long int go = left;
  if (l > mid) {
    x = mid + 1;
    y = ed;
    go = right;
  }
  if (level[dep]) {
    if (go == left) {
      go = right;
    } else
      go = left;
  }
  return query(x, y, l, r, go, dep - 1);
}
inline long long int get(long long int x, long long int n) {
  if (x == 0) return 0;
  long long int sum = 0;
  long long int left = 1;
  long long int m = 1 << n;
  for (long long int i = 18; i >= 0; i--) {
    if (x & (1 << i)) {
      sum += query(1, m, left, left - 1 + (1 << i), 1, n);
      left += (1 << i);
    }
  }
  return sum;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  long long int n, q;
  cin >> n >> q;
  long long int m = 1ll << n;
  for (long long int i = 1; i <= m; i++) {
    cin >> a[i];
  }
  build(1, m, 1);
  while (q--) {
    long long int c;
    cin >> c;
    if (c == 1) {
      long long int x, k;
      cin >> x >> k;
      a[x] = k;
      update(1, m, 1, n, x);
    }
    if (c == 2) {
      long long int x;
      cin >> x;
      for (long long int i = 0; i <= x; i++) {
        level[i] = 1 - level[i];
      }
    }
    if (c == 3) {
      long long int x;
      cin >> x;
      level[x + 1] = 1 - level[x + 1];
    }
    if (c == 4) {
      long long int l, r;
      cin >> l >> r;
      long long int ans = get(r, n) - get(l - 1, n);
      cout << ans << endl;
    }
  }
}
