#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;       }     }   }