#include <bits/stdc++.h>
using namespace std;
long long Sum[300005 << 2];
long long A[300005];
int rev[300005];
void PushUp(int rt) { Sum[rt] = Sum[rt << 1] + Sum[rt << 1 | 1]; }
void Build(int l, int r, int rt) {
  if (l == r) {
    Sum[rt] = A[l];
    return;
  }
  int m = (l + r) >> 1;
  Build(l, m, rt << 1);
  Build(m + 1, r, rt << 1 | 1);
  PushUp(rt);
}
void Update_leaf(int L, int C, int l, int r, int rt, int depth) {
  if (l == r) {
    Sum[rt] = C;
    return;
  }
  int m = (l + r) >> 1;
  if (L <= m)
    Update_leaf(L, C, l, m, (rt << 1) + (rev[depth] == 1), depth - 1);
  else
    Update_leaf(L, C, m + 1, r, (rt << 1 | 1) - (rev[depth] == 1), depth - 1);
  PushUp(rt);
}
long long Query(int L, int R, int l, int r, int rt, int depth) {
  if (L <= l && r <= R) {
    return Sum[rt];
  }
  int m = (l + r) >> 1;
  long long ANS = 0;
  if (L <= m)
    ANS += Query(L, R, l, m, (rt << 1) + (rev[depth] == 1), depth - 1);
  if (R > m)
    ANS += Query(L, R, m + 1, r, (rt << 1 | 1) - (rev[depth] == 1), depth - 1);
  return ANS;
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  memset(rev, 0, sizeof(rev));
  for (int i = 1; i <= (1 << n); i++) {
    scanf("%lld", &A[i]);
  }
  Build(1, 1 << n, 1);
  while (m--) {
    int t, x, y;
    scanf("%d %d", &t, &x);
    long long ans;
    if (t == 1) {
      scanf("%d", &y);
      Update_leaf(x, y, 1, 1 << n, 1, n);
    } else if (t == 2) {
      for (int i = 0; i <= x; i++) rev[i] ^= 1;
    } else if (t == 3) {
      rev[x + 1] ^= 1;
    } else if (t == 4) {
      scanf("%d", &y);
      printf("%lld\n", Query(x, y, 1, 1 << n, 1, n));
    }
  }
}
