// This code wrote by chtholly_micromaker(MicroMaker)
#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC target("avx,avx2")
#include <bits/stdc++.h>
#define reg register
#define int long long
#define ALL(x) (x).begin(),(x).end()
#define mem(x,y) memset(x,y,sizeof x)
#define sz(x) (int)(x).size()
using namespace std;
const int MaxN=(1<<18)+50;
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c))s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
template <class t> inline void write(t x)
{
	if(x<0)putchar('-'),x=-x;
	int buf[21],top=0;
	while(x)buf[++top]=x%10,x/=10;
	if(!top)buf[++top]=0;
	while(top)putchar(buf[top--]^'0');
	return;
}
int n,q;
#define lson (u<<1)
#define rson (u<<1|1)
int val[MaxN<<2],Xor;
inline void pushup(int u)
{
	val[u]=val[lson]+val[rson];
	return;
}
inline void buildtr(int u,int l,int r)
{
	if(l==r)
	{
		read(val[u]);
		return;
	}
	reg int mid=(l+r)>>1;
	buildtr(lson,l,mid);
	buildtr(rson,mid+1,r);
	pushup(u);
	return;
}
inline void modify(int u,int l,int r,int p,int k)
{
	if(l==r)
	{
		val[u]=k;
		return;
	}
	reg int mid=(l+r)>>1;
	if(p<=mid)
		modify(lson,l,mid,p,k);
	else
		modify(rson,mid+1,r,p,k);
	pushup(u);
	return;
}
inline int query(int u,int l,int r,int ql,int qr)
{
	if(ql<=l&&r<=qr)
		return val[u];
	reg int mid=(l+r)>>1,res=0;
	if(ql<=mid)
		res+=query(lson,l,mid,ql,qr);
	if(mid<qr)
		res+=query(rson,mid+1,r,ql,qr);
	return res;
}
inline int get(int x)
{
	reg int cnt=0;
	while(x)
	{
		if(x&1)
			break;
		x>>=1;
		++cnt;
	}
	return cnt;
}
inline int lowbit(int x)
{
	return x&(-x);
}
inline int calc(int pos)
{
	reg int res=0;
	while(pos)
	{
		reg int g=get(pos);
		pos-=lowbit(pos);
		reg int L=(pos^Xor)&(n-(1<<g));
		res+=query(1,0,n-1,L,L+(1<<g)-1);
	}
	return res;
}
signed main(void)
{
	cin>>n>>q;
	n=(1<<n);
	buildtr(1,0,n-1);
	reg int opt,x,y;
	while(q--)
	{
		read(opt);read(x);
		if(opt==1)
		{
			read(y);--x;
			modify(1,0,n-1,x^Xor,y);
		}
		else if(opt==2)
			Xor^=(1<<x)-1;
		else if(opt==3)
			Xor^=(1<<x);
		else
		{
			read(y);
			write(calc(y)-calc(x-1)),puts("");
		}
	}
	return 0;
}

// asd


// This code wrote by chtholly_micromaker(MicroMaker)
#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC target("avx,avx2")
#include <bits/stdc++.h>
#define reg register
#define int long long
#define ALL(x) (x).begin(),(x).end()
#define mem(x,y) memset(x,y,sizeof x)
#define sz(x) (int)(x).size()
using namespace std;
const int MaxN=(1<<18)+50;
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c))s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
template <class t> inline void write(t x)
{
	if(x<0)putchar('-'),x=-x;
	int buf[21],top=0;
	while(x)buf[++top]=x%10,x/=10;
	if(!top)buf[++top]=0;
	while(top)putchar(buf[top--]^'0');
	return;
}
int n,q;
#define lson (u<<1)
#define rson (u<<1|1)
int val[MaxN<<2],Xor;
inline void pushup(int u)
{
	val[u]=val[lson]+val[rson];
	return;
}
inline void buildtr(int u,int l,int r)
{
	if(l==r)
	{
		read(val[u]);
		return;
	}
	reg int mid=(l+r)>>1;
	buildtr(lson,l,mid);
	buildtr(rson,mid+1,r);
	pushup(u);
	return;
}
inline void modify(int u,int l,int r,int p,int k)
{
	if(l==r)
	{
		val[u]=k;
		return;
	}
	reg int mid=(l+r)>>1;
	if(p<=mid)
		modify(lson,l,mid,p,k);
	else
		modify(rson,mid+1,r,p,k);
	pushup(u);
	return;
}
inline int query(int u,int l,int r,int ql,int qr)
{
	if(ql<=l&&r<=qr)
		return val[u];
	reg int mid=(l+r)>>1,res=0;
	if(ql<=mid)
		res+=query(lson,l,mid,ql,qr);
	if(mid<qr)
		res+=query(rson,mid+1,r,ql,qr);
	return res;
}
inline int get(int x)
{
	reg int cnt=0;
	while(x)
	{
		if(x&1)
			break;
		x>>=1;
		++cnt;
	}
	return cnt;
}
inline int lowbit(int x)
{
	return x&(-x);
}
inline int calc(int pos)
{
	reg int res=0;
	while(pos)
	{
		reg int g=get(pos);
		pos-=lowbit(pos);
		reg int L=(pos^Xor)&(n-(1<<g));
		res+=query(1,0,n-1,L,L+(1<<g)-1);
	}
	return res;
}
signed main(void)
{
	cin>>n>>q;
	n=(1<<n);
	buildtr(1,0,n-1);
	reg int opt,x,y;
	while(q--)
	{
		read(opt);read(x);
		if(opt==1)
		{
			read(y);--x;
			modify(1,0,n-1,x^Xor,y);
		}
		else if(opt==2)
			Xor^=(1<<x)-1;
		else if(opt==3)
			Xor^=(1<<x);
		else
		{
			read(y);
			write(calc(y)-calc(x-1)),puts("");
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define lson now<<1
#define rson now<<1|1
using namespace std;
const int maxn=1000009;

int n,m;
int a[maxn];

long long sum[maxn];
void build(int now,int l,int r){
	if(l==r){
		sum[now]=a[l];return;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);

	sum[now]=sum[lson]+sum[rson];
}

int rev[maxn],swp[maxn];

void update(int now,int l,int r,int p,int val,int d){
	if(l==r){
		sum[now]=val;return;
	}
	int mid=(l+r)>>1,k=(1<<d)/2;
	if(!rev[d]&&!swp[d]){
		if(p<=mid)update(lson,l,mid,p,val,d-1);
		else update(rson,mid+1,r,p,val,d-1);
	}else if(!rev[d]){
		if(p<=mid)update(rson,mid+1,r,p+k,val,d-1);
		else update(lson,l,mid,p-k,val,d-1);
	}else if(!swp[d]){
		p=2*mid+1-p;
		if(p<=mid)update(lson,l,mid,p,val,d-1);
		else update(rson,mid+1,r,p,val,d-1);
	}else{
		if(p<=mid)update(lson,l,mid,2*mid-k-p+1,val,d-1);
		else update(rson,mid+1,r,2*mid+k-p+1,val,d-1);
	}

	sum[now]=sum[lson]+sum[rson];
}

long long query(int now,int l,int r,int ll,int rr,int d){
	if(ll>rr)return 0;
	if(l>=ll&&r<=rr){
		return sum[now];
	}
	int mid=(l+r)>>1,k=(1<<d)/2;
	long long ret=0;
	int a=max(l,ll),b=min(mid,rr);
	if(!rev[d]&&!swp[d]){
		ret+=query(lson,l,mid,a,b,d-1);
	}else if(!rev[d]){
		a+=k;b+=k;
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else if(!swp[d]){
		a=2*mid+1-a;b=2*mid+1-b;swap(a,b);
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else{
		a=2*mid-k-a+1;b=2*mid-k-b+1;swap(a,b);
		ret+=query(lson,l,mid,a,b,d-1);
	}
	a=max(mid+1,ll);b=min(r,rr);
	if(!rev[d]&&!swp[d]){
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else if(!rev[d]){
		a-=k;b-=k;
		ret+=query(lson,l,mid,a,b,d-1);
	}else if(!swp[d]){
		a=2*mid+1-a;b=2*mid+1-b;swap(a,b);
		ret+=query(lson,l,mid,a,b,d-1);
	}else{
		a=2*mid+k-a+1;b=2*mid-k-b+1;swap(a,b);
		ret+=query(rson,mid+1,r,a,b,d-1);
	}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=(1<<n);++i)scanf("%d",&a[i]);
	build(1,1,1<<n);
	while(m--){
		int opty,x,y;
		scanf("%d%d",&opty,&x);
		if(opty==1){
			scanf("%d",&y);
			update(1,1,1<<n,x,y,n);
		}
		if(opty==2){
			rev[x]^=1;
		}
		if(opty==3){
			swp[x+1]^=1;
		}
		if(opty==4){
			scanf("%d",&y);
			printf("%lld\n",query(1,1,1<<n,x,y,n));
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define lson now<<1
#define rson now<<1|1
using namespace std;
const int maxn=1000009;

int n,m;
int a[maxn];

long long sum[maxn];
void build(int now,int l,int r){
	if(l==r){
		sum[now]=a[l];return;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);

	sum[now]=sum[lson]+sum[rson];
}

int rev[maxn],swp[maxn];

void update(int now,int l,int r,int p,int val,int d){
	if(l==r){
		sum[now]=val;return;
	}
	int mid=(l+r)>>1,k=(1<<d)/2;
	if(!rev[d]&&!swp[d]){
		if(p<=mid)update(lson,l,mid,p,val,d-1);
		else update(rson,l,mid,p,val,d-1);
	}else if(!rev[d]){
		if(p<=mid)update(rson,mid+1,r,p+k,val,d-1);
		else update(lson,l,mid,p-k,val,d-1);
	}else if(!swp[d]){
		p=2*mid+1-p;
		if(p<=mid)update(lson,l,mid,p,val,d-1);
		else update(rson,mid+1,r,p,val,d-1);
	}else{
		if(d<=mid)update(lson,l,mid,2*mid-k-p+1,val,d-1);
		else update(rson,mid+1,r,2*mid+k-p+1,val,d-1);
	}

	sum[now]=sum[lson]+sum[rson];
}

long long query(int now,int l,int r,int ll,int rr,int d){
	if(ll>rr)return 0;
	if(l>=ll&&r<=rr){
		return sum[now];
	}
	int mid=(l+r)>>1,k=(1<<d)/2;
	long long ret=0;
	int a=max(l,ll),b=min(mid,rr);
	if(!rev[d]&&!swp[d]){
		ret+=query(lson,l,mid,a,b,d-1);
	}else if(!rev[d]){
		a+=k;b+=k;
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else if(!swp[d]){
		a=2*mid+1-a;b=2*mid+1-b;swap(a,b);
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else{
		a=2*mid-k-a+1;b=2*mid-k-b+1;swap(a,b);
		ret+=query(lson,l,mid,a,b,d-1);
	}
	a=max(mid+1,ll);b=min(r,rr);
	if(!rev[d]&&!swp[d]){
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else if(!rev[d]){
		a-=k;b-=k;
		ret+=query(lson,l,mid,a,b,d-1);
	}else if(!swp[d]){
		a=2*mid+1-a;b=2*mid+1-b;swap(a,b);
		ret+=query(lson,l,mid,a,b,d-1);
	}else{
		a=2*mid+k-a+1;b=2*mid-k-b+1;swap(a,b);
		ret+=query(rson,mid+1,r,a,b,d-1);
	}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=(1<<n);++i)scanf("%d",&a[i]);
	build(1,1,1<<n);
	while(m--){
		int opty,x,y;
		scanf("%d%d",&opty,&x);
		if(opty==1){
			scanf("%d",&y);
			update(1,1,1<<n,x,y,n);
		}
		if(opty==2){
			rev[x]^=1;
		}
		if(opty==3){
			swp[x+1]^=1;
		}
		if(opty==4){
			scanf("%d",&y);
			printf("%lld\n",query(1,1,1<<n,x,y,n));
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define lson now<<1
#define rson now<<1|1
using namespace std;
const int maxn=1000009;

int n,m;
int a[maxn];

long long sum[maxn];
void build(int now,int l,int r){
	if(l==r){
		sum[now]=a[l];return;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);

	sum[now]=sum[lson]+sum[rson];
}

int rev[maxn],swp[maxn];

void update(int now,int l,int r,int p,int val,int d){
	if(l==r){
		sum[now]=val;return;
	}
	int mid=(l+r)>>1,k=(1<<d)/2;
	if(!rev[d]&&!swp[d]){
		if(p<=mid)update(lson,l,mid,p,val,d-1);
		else update(rson,mid+1,r,p,val,d-1);
	}else if(!rev[d]){
		if(p<=mid)update(rson,mid+1,r,p+k,val,d-1);
		else update(lson,l,mid,p-k,val,d-1);
	}else if(!swp[d]){
		p=2*mid+1-p;
		if(p<=mid)update(lson,l,mid,p,val,d-1);
		else update(rson,mid+1,r,p,val,d-1);
	}else{
		if(p<=mid)update(lson,l,mid,2*mid-k-p+1,val,d-1);
		else update(rson,mid+1,r,2*mid+k-p+1,val,d-1);
	}

	sum[now]=sum[lson]+sum[rson];
}

long long query(int now,int l,int r,int ll,int rr,int d){
	if(ll>rr)return 0;
	if(l>=ll&&r<=rr){
		return sum[now];
	}
	int mid=(l+r)>>1,k=(1<<d)/2;
	long long ret=0;
	int a=max(l,ll),b=min(mid,rr);
	if(!rev[d]&&!swp[d]){
		ret+=query(lson,l,mid,a,b,d-1);
	}else if(!rev[d]){
		a+=k;b+=k;
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else if(!swp[d]){
		a=2*mid+1-a;b=2*mid+1-b;swap(a,b);
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else{
		a=2*mid-k-a+1;b=2*mid-k-b+1;swap(a,b);
		ret+=query(lson,l,mid,a,b,d-1);
	}
	a=max(mid+1,ll);b=min(r,rr);
	if(!rev[d]&&!swp[d]){
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else if(!rev[d]){
		a-=k;b-=k;
		ret+=query(lson,l,mid,a,b,d-1);
	}else if(!swp[d]){
		a=2*mid+1-a;b=2*mid+1-b;swap(a,b);
		ret+=query(lson,l,mid,a,b,d-1);
	}else{
		a=2*mid+k-a+1;b=2*mid+k-b+1;swap(a,b);
		ret+=query(rson,mid+1,r,a,b,d-1);
	}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=(1<<n);++i)scanf("%d",&a[i]);
	build(1,1,1<<n);
	while(m--){
		int opty,x,y;
		scanf("%d%d",&opty,&x);
		if(opty==1){
			scanf("%d",&y);
			update(1,1,1<<n,x,y,n);
		}
		if(opty==2){
			rev[x]^=1;
		}
		if(opty==3){
			swp[x+1]^=1;
		}
		if(opty==4){
			scanf("%d",&y);
			printf("%lld\n",query(1,1,1<<n,x,y,n));
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define lson now<<1
#define rson now<<1|1
using namespace std;
const int maxn=1000009;

int n,m;
int a[maxn];

long long sum[maxn];
void build(int now,int l,int r){
	if(l==r){
		sum[now]=a[l];return;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);

	sum[now]=sum[lson]+sum[rson];
}

int rev[maxn],swp[maxn];

void update(int now,int l,int r,int p,int val,int d){
	if(l==r){
		sum[now]=val;return;
	}
	int mid=(l+r)>>1,k=(1<<d)/2;
	if(!rev[d]&&!swp[d]){
		if(p<=mid)update(lson,l,mid,p,val,d-1);
		else update(rson,l,mid,p,val,d-1);
	}else if(!rev[d]){
		if(p<=mid)update(rson,mid+1,r,p+k,val,d-1);
		else update(lson,l,mid,p-k,val,d-1);
	}else if(!swp[d]){
		p=2*mid+1-p;
		if(p<=mid)update(lson,l,mid,p,val,d-1);
		else update(rson,mid+1,r,p,val,d-1);
	}else{
		if(p<=mid)update(lson,l,mid,2*mid-k-p+1,val,d-1);
		else update(rson,mid+1,r,2*mid+k-p+1,val,d-1);
	}

	sum[now]=sum[lson]+sum[rson];
}

long long query(int now,int l,int r,int ll,int rr,int d){
	if(ll>rr)return 0;
	if(l>=ll&&r<=rr){
		return sum[now];
	}
	int mid=(l+r)>>1,k=(1<<d)/2;
	long long ret=0;
	int a=max(l,ll),b=min(mid,rr);
	if(!rev[d]&&!swp[d]){
		ret+=query(lson,l,mid,a,b,d-1);
	}else if(!rev[d]){
		a+=k;b+=k;
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else if(!swp[d]){
		a=2*mid+1-a;b=2*mid+1-b;swap(a,b);
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else{
		a=2*mid-k-a+1;b=2*mid-k-b+1;swap(a,b);
		ret+=query(lson,l,mid,a,b,d-1);
	}
	a=max(mid+1,ll);b=min(r,rr);
	if(!rev[d]&&!swp[d]){
		ret+=query(rson,mid+1,r,a,b,d-1);
	}else if(!rev[d]){
		a-=k;b-=k;
		ret+=query(lson,l,mid,a,b,d-1);
	}else if(!swp[d]){
		a=2*mid+1-a;b=2*mid+1-b;swap(a,b);
		ret+=query(lson,l,mid,a,b,d-1);
	}else{
		a=2*mid+k-a+1;b=2*mid-k-b+1;swap(a,b);
		ret+=query(rson,mid+1,r,a,b,d-1);
	}
	return ret;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=(1<<n);++i)scanf("%d",&a[i]);
	build(1,1,1<<n);
	while(m--){
		int opty,x,y;
		scanf("%d%d",&opty,&x);
		if(opty==1){
			scanf("%d",&y);
			update(1,1,1<<n,x,y,n);
		}
		if(opty==2){
			rev[x]^=1;
		}
		if(opty==3){
			swp[x+1]^=1;
		}
		if(opty==4){
			scanf("%d",&y);
			printf("%lld\n",query(1,1,1<<n,x,y,n));
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define ll long long
const int maxn=27e4;
int n;
int a[maxn],idx,lc[maxn<<1],rc[maxn<<1],rt;
ll sum[maxn<<1];
int q1[maxn<<1],q2[maxn<<1];

void build(int &x,int l,int r)
{
	x=++idx;
	if(l==r){
		sum[x]=a[l]; return;
	}
	int mid=(l+r)>>1;
	build(lc[x],l,mid); build(rc[x],mid+1,r);
	sum[x]=sum[lc[x]]+sum[rc[x]];
}

void pushdown(int x,int k)
{
	if((q1[x]>>k)&1)swap(lc[x],rc[x]),q1[x]^=1<<k;
	q1[lc[x]]^=q1[x]; q1[rc[x]]^=q1[x]; q1[x]=0;
	int cnt=0;
	for(int i=k;i<=n;i++){
		if((q2[x]>>i)&1)cnt++;
	}
	cnt%=2;
	if(cnt)swap(lc[x],rc[x]);
	q2[lc[x]]^=q2[x]; q2[rc[x]]^=q2[x]; q2[x]=0;
}

void ins(int x,int l,int r,int p,int k)
{
	if(l==r){
		sum[x]=k; return;
	}
	pushdown(x,log2(r-l+1));
	int mid=(l+r)>>1;
	if(p<=mid)ins(lc[x],l,mid,p,k);
	else ins(rc[x],mid+1,r,p,k);
	sum[x]=sum[lc[x]]+sum[rc[x]];
}

ll ask(int x,int l,int r,int al,int ar)
{
	if(al<=l&&r<=ar)return sum[x];
	pushdown(x,log2(r-l+1));
	int mid=(l+r)>>1;
	ll res=0;
	if(al<=mid)res+=ask(lc[x],l,mid,al,ar);
	if(ar>mid)res+=ask(rc[x],mid+1,r,al,ar);
	return res;
}

int main()
{
	int q,l,r,p,k,op;
	scanf("%d%d",&n,&q);
	int m=1<<n;
	for(int i=1;i<=m;i++)scanf("%d",&a[i]);
	build(rt,1,m);
	while(q--){
		scanf("%d",&op);
		if(op==1)scanf("%d%d",&p,&k),ins(rt,1,m,p,k);
		else if(op==2)scanf("%d",&k),k=1<<k,q2[rt]^=k;
		else if(op==3)scanf("%d",&k),k=1<<(k+1),q1[rt]^=k;
		else scanf("%d%d",&l,&r),printf("%lld\n",ask(rt,1,m,l,r));
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define ll long long
const int maxn=27e4;
int n;
int a[maxn],idx,lc[maxn<<1],rc[maxn<<1],rt;
ll sum[maxn<<1];
int q1[maxn<<1],q2[maxn<<1];

void build(int &x,int l,int r)
{
	x=++idx;
	if(l==r){
		sum[x]=a[l]; return;
	}
	int mid=(l+r)>>1;
	build(lc[x],l,mid); build(rc[x],mid+1,r);
	sum[x]=sum[lc[x]]+sum[rc[x]];
}

void pushdown(int x,int k)
{
	if((q1[x]>>k)&1)swap(lc[x],rc[x]),q1[x]^=1<<k;
	q1[lc[x]]|=q1[x]; q1[rc[x]]|=q1[x]; q1[x]=0;
	int cnt=0;
	for(int i=k;i<=n;i++){
		if((q2[x]>>i)&1)cnt++;
	}
	cnt%=2;
	if(cnt)swap(lc[x],rc[x]);
	q2[lc[x]]|=q2[x]; q2[rc[x]]|=q2[x]; q2[x]=0;
}

void ins(int x,int l,int r,int p,int k)
{
	if(l==r){
		sum[x]=k; return;
	}
	pushdown(x,log2(r-l+1));
	int mid=(l+r)>>1;
	if(p<=mid)ins(lc[x],l,mid,p,k);
	else ins(rc[x],mid+1,r,p,k);
	sum[x]=sum[lc[x]]+sum[rc[x]];
}

ll ask(int x,int l,int r,int al,int ar)
{
	if(al<=l&&r<=ar)return sum[x];
	pushdown(x,log2(r-l+1));
	int mid=(l+r)>>1;
	ll res=0;
	if(al<=mid)res+=ask(lc[x],l,mid,al,ar);
	if(ar>mid)res+=ask(rc[x],mid+1,r,al,ar);
	return res;
}

int main()
{
	int q,l,r,p,k,op;
	scanf("%d%d",&n,&q);
	int m=1<<n;
	for(int i=1;i<=m;i++)scanf("%d",&a[i]);
	build(rt,1,m);
	while(q--){
		scanf("%d",&op);
		if(op==1)scanf("%d%d",&p,&k),ins(rt,1,m,p,k);
		else if(op==2)scanf("%d",&k),k=1<<k,q2[rt]|=k;
		else if(op==3)scanf("%d",&k),k=1<<(k+1),q1[rt]|=k;
		else scanf("%d%d",&l,&r),printf("%lld\n",ask(rt,1,m,l,r));
	}
	return 0;
}


#include<bits/stdc++.h>
#define I inline
#define R register
namespace IO{
    const int IOsize=1<<21;
    I void read(){};I void Write(){};
    char buf[IOsize],*pa=buf,*pb=buf;
    char buffer[IOsize];int p1=-1;const int p2=(IOsize)-1;
    I char gc(){return pa==pb&&(pb=(pa=buf)+fread(buf,1,IOsize,stdin),pa==pb)?EOF:*pa++;}
    template<typename T,typename... T2>I void read(T &x,T2 &... oth){
        x=0;R short y=0;R char ch=gc();
        for(;!isdigit(ch);ch=gc())y=ch=='-';
        for(;isdigit(ch);ch=gc())x=x*10+(ch^48);
        (y)&&(x=-x);read(oth...);return;}
    I void flush(){fwrite(buffer,1,p1+1,stdout);p1=-1;return;}
    I void pc(int ch){if(p1==p2)flush();buffer[++p1]=ch;return;}
    template<class T>I void write(T x){
        static char buf[20];static short len =-1;
        if(x>=0){do buf[++len]=(x%10)^48,x/=10;while(x);}
        else{pc('-');do buf[++len]=(-(x%10))^48,x/=10;while(x);}
        while(len>=0)pc(buf[len--]);return;}
    template<typename T,typename...T2>I void Write(T x,T2... oth){write(x),pc('\n'),Write(oth...);return;}}
using namespace IO;
using namespace std;
using ll = long long ;
const int N = 1<<18;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<2];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    tr[o].ls=o<<1;
    tr[o].rs=o<<1|1;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
    int mid=(l+r)>>1;
    build(tr[o].ls,l,mid);
    build(tr[o].rs,mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
void dfs(int o,int l,int r)
{
    if(l==r) return void(printf("%d ",tr[o].val));
    int mid=(l+r)>>1;
    dfs(tr[o].ls,l,mid),dfs(tr[o].rs,mid+1,r);
}
signed main()
{
    read(n),read(m),tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)read(a[i]);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        read(opt);
        if(opt==1)
        {
            read(pos,k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
            read(k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
            read(k);tag[++k]^=1;
        }
        if(opt==4)
        {
            read(pos,k);
            printf("%lld\n",query(1,1,n,pos,k));
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1<<19;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<3];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    tr[o].ls=o<<1;
    tr[o].rs=o<<1|1;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
    int mid=(l+r)>>1;
    build(tr[o].ls,l,mid);
    build(tr[o].rs,mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
signed main()
{
    scanf("%d%d",&n,&m);
    tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)scanf("%d",a+i);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        scanf("%d",&opt);
        if(opt==1)
        {
            scanf("%d%d",&pos,&k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
            scanf("%d",&k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
            scanf("%d",&k);
            tag[++k]^=1;
        }
        if(opt==4)
        {
            scanf("%d%d",&pos,&k);
            printf("%lld\n",query(1,1,n,pos,k));
        }
    }
    return 0;
}


#include<bits/stdc++.h>
#define I inline
#define R register
namespace IO{
    const int IOsize=1<<21;
    I void read(){};I void Write(){};
    char buf[IOsize],*pa=buf,*pb=buf;
    char buffer[IOsize];int p1=-1;const int p2=(IOsize)-1;
    I char gc(){return pa==pb&&(pb=(pa=buf)+fread(buf,1,IOsize,stdin),pa==pb)?EOF:*pa++;}
    template<typename T,typename... T2>I void read(T &x,T2 &... oth){
        x=0;R short y=0;R char ch=gc();
        for(;!isdigit(ch);ch=gc())y=ch=='-';
        for(;isdigit(ch);ch=gc())x=x*10+(ch^48);
        (y)&&(x=-x);read(oth...);return;}
    I void flush(){fwrite(buffer,1,p1+1,stdout);p1=-1;return;}
    I void pc(int ch){if(p1==p2)flush();buffer[++p1]=ch;return;}
    template<class T>I void write(T x){
        static char buf[20];static short len =-1;
        if(x>=0){do buf[++len]=(x%10)^48,x/=10;while(x);}
        else{pc('-');do buf[++len]=(-(x%10))^48,x/=10;while(x);}
        while(len>=0)pc(buf[len--]);return;}
    template<typename T,typename...T2>I void Write(T x,T2... oth){write(x),pc('\n'),Write(oth...);return;}}
using namespace IO;
using namespace std;
using ll = long long ;
const int N = 1<<18;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<3];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    tr[o].ls=o<<1;
    tr[o].rs=o<<1|1;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
    int mid=(l+r)>>1;
    build(tr[o].ls,l,mid);
    build(tr[o].rs,mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
void dfs(int o,int l,int r)
{
    if(l==r) return void(printf("%d ",tr[o].val));
    int mid=(l+r)>>1;
    dfs(tr[o].ls,l,mid),dfs(tr[o].rs,mid+1,r);
}
signed main()
{
    read(n),read(m),tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)read(a[i]);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        read(opt);
        if(opt==1)
        {
            read(pos,k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
            read(k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
            read(k);tag[++k]^=1;
        }
        if(opt==4)
        {
            read(pos,k);
            printf("%lld\n",query(1,1,n,pos,k));
        }
    }
    return 0;
}


#include<bits/stdc++.h>
#define I inline
#define R register
namespace IO{
    const int IOsize=1<<21;
    I void read(){};I void Write(){};
    char buf[IOsize],*pa=buf,*pb=buf;
    char buffer[IOsize];int p1=-1;const int p2=(IOsize)-1;
    I char gc(){return pa==pb&&(pb=(pa=buf)+fread(buf,1,IOsize,stdin),pa==pb)?EOF:*pa++;}
    template<typename T,typename... T2>I void read(T &x,T2 &... oth){
        x=0;R short y=0;R char ch=gc();
        for(;!isdigit(ch);ch=gc())y=ch=='-';
        for(;isdigit(ch);ch=gc())x=x*10+(ch^48);
        (y)&&(x=-x);read(oth...);return;}
    I void flush(){fwrite(buffer,1,p1+1,stdout);p1=-1;return;}
    I void pc(int ch){if(p1==p2)flush();buffer[++p1]=ch;return;}
    template<class T>I void write(T x){
        static char buf[20];static short len =-1;
        if(x>=0){do buf[++len]=(x%10)^48,x/=10;while(x);}
        else{pc('-');do buf[++len]=(-(x%10))^48,x/=10;while(x);}
        while(len>=0)pc(buf[len--]);return;}
    template<typename T,typename...T2>I void Write(T x,T2... oth){write(x),pc('\n'),Write(oth...);return;}}
using namespace IO;
using namespace std;
#define int long long
using ll = long long ;
const int N = 1<<18;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<2];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    tr[o].ls=o<<1;
    tr[o].rs=o<<1|1;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
    int mid=(l+r)>>1;
    build(tr[o].ls,l,mid);
    build(tr[o].rs,mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
void dfs(int o,int l,int r)
{
    if(l==r) return void(printf("%d ",tr[o].val));
    int mid=(l+r)>>1;
    dfs(tr[o].ls,l,mid),dfs(tr[o].rs,mid+1,r);
}
signed main()
{
    read(n),read(m),tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)read(a[i]);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        read(opt);
        if(opt==1)
        {
            read(pos,k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
            read(k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
            read(k);tag[++k]^=1;
        }
        if(opt==4)
        {
            read(pos,k);
            Write(query(1,1,n,pos,k));
        }
    }
    return flush(),0;
}


#include<bits/stdc++.h>
#define I inline
#define R register
namespace IO{
    const int IOsize=1<<21;
    I void read(){};I void Write(){};
    char buf[IOsize],*pa=buf,*pb=buf;
    char buffer[IOsize];int p1=-1;const int p2=(IOsize)-1;
    I char gc(){return pa==pb&&(pb=(pa=buf)+fread(buf,1,IOsize,stdin),pa==pb)?EOF:*pa++;}
    template<typename T,typename... T2>I void read(T &x,T2 &... oth){
        x=0;R short y=0;R char ch=gc();
        for(;!isdigit(ch);ch=gc())y=ch=='-';
        for(;isdigit(ch);ch=gc())x=x*10+(ch^48);
        (y)&&(x=-x);read(oth...);return;}
    I void flush(){fwrite(buffer,1,p1+1,stdout);p1=-1;return;}
    I void pc(int ch){if(p1==p2)flush();buffer[++p1]=ch;return;}
    template<class T>I void write(T x){
        static char buf[20];static short len =-1;
        if(x>=0){do buf[++len]=(x%10)^48,x/=10;while(x);}
        else{pc('-');do buf[++len]=(-(x%10))^48,x/=10;while(x);}
        while(len>=0)pc(buf[len--]);return;}
    template<typename T,typename...T2>I void Write(T x,T2... oth){write(x),pc('\n'),Write(oth...);return;}}
using namespace IO;
using namespace std;
using ll = long long ;
const int N = 1<<18;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<2];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    tr[o].ls=o<<1;
    tr[o].rs=o<<1|1;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
    int mid=(l+r)>>1;
    build(tr[o].ls,l,mid);
    build(tr[o].rs,mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
void dfs(int o,int l,int r)
{
    if(l==r) return void(printf("%d ",tr[o].val));
    int mid=(l+r)>>1;
    dfs(tr[o].ls,l,mid),dfs(tr[o].rs,mid+1,r);
}
signed main()
{
    read(n),read(m),tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)read(a[i]);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        read(opt);
        if(opt==1)
        {
            read(pos,k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
            read(k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
            read(k);tag[++k]^=1;
        }
        if(opt==4)
        {
            read(pos,k);
            Write(query(1,1,n,pos,k));
        }
    }
    return flush(),0;
}


#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1<<18;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<3];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    tr[o].ls=o<<1;
    tr[o].rs=o<<1|1;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
    int mid=(l+r)>>1;
    build(tr[o].ls,l,mid);
    build(tr[o].rs,mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
signed main()
{
    scanf("%d%d",&n,&m);
    tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)scanf("%d",a+i);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        scanf("%d",&opt);
        if(opt==1)
        {
            scanf("%d%d",&pos,&k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
            scanf("%d",&k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
            scanf("%d",&k);
            tag[++k]^=1;
        }
        if(opt==4)
        {
            scanf("%d%d",&pos,&k);
            printf("%lld\n",query(1,1,n,pos,k));
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1<<18;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<3];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    tr[o].ls=o<<1;
    tr[o].rs=o<<1|1;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
    int mid=(l+r)>>1;
    build(tr[o].ls,l,mid);
    build(tr[o].rs,mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
signed main()
{
    scanf("%d%d",&n,&m);
    tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)scanf("%d",a+i);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        scanf("%d",&opt);
        if(opt==1)
        {
            scanf("%d%d",&pos,&k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
        scanf("%d",&k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
        scanf("%d",&k);
            tag[++k]^=1;
        }
        if(opt==4)
        {
            scanf("%d%d",&pos,&k);
            printf("%lld\n",query(1,1,n,pos,k));
        }
    }
    return 0;
}


#include<bits/stdc++.h>
#define I inline
#define R register
namespace IO{
    const int IOsize=1<<21;
    I void read(){};I void Write(){};
    char buf[IOsize],*pa=buf,*pb=buf;
    char buffer[IOsize];int p1=-1;const int p2=(IOsize)-1;
    I char gc(){return pa==pb&&(pb=(pa=buf)+fread(buf,1,IOsize,stdin),pa==pb)?EOF:*pa++;}
    template<typename T,typename... T2>I void read(T &x,T2 &... oth){
        x=0;R short y=0;R char ch=gc();
        for(;!isdigit(ch);ch=gc())y=ch=='-';
        for(;isdigit(ch);ch=gc())x=x*10+(ch^48);
        (y)&&(x=-x);read(oth...);return;}
    I void flush(){fwrite(buffer,1,p1+1,stdout);p1=-1;return;}
    I void pc(int ch){if(p1==p2)flush();buffer[++p1]=ch;return;}
    template<class T>I void write(T x){
        static char buf[20];static short len =-1;
        if(x>=0){do buf[++len]=(x%10)^48,x/=10;while(x);}
        else{pc('-');do buf[++len]=(-(x%10))^48,x/=10;while(x);}
        while(len>=0)pc(buf[len--]);return;}
    template<typename T,typename...T2>I void Write(T x,T2... oth){write(x),pc('\n'),Write(oth...);return;}}
using namespace IO;
using namespace std;
#define int long long
using ll = long long ;
const int N = 1<<18;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<2];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    int mid=(l+r)>>1;
    build(tr[o].ls=(o<<1),l,mid);
    build(tr[o].rs=(o<<1|1),mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;
    pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;
    pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
void dfs(int o,int l,int r)
{
    if(l==r) return void(printf("%d ",tr[o].val));
    int mid=(l+r)>>1;
    dfs(tr[o].ls,l,mid),dfs(tr[o].rs,mid+1,r);
}
signed main()
{
    read(n),read(m),tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)read(a[i]);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        read(opt);
        if(opt==1)
        {
            read(pos,k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
            read(k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
            read(k);tag[++k]^=1;
        }
        if(opt==4)
        {
            read(pos,k);
            Write(query(1,1,n,pos,k));
        }
    }
    return flush(),0;
}


#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1<<18;
int n,m,a[N],tag[20];
struct node
{
    int ls,rs,dep,rev;
    ll val;
}tr[N<<3];
void pushdown(int o)
{
    if(tag[tr[o].dep]^tr[o].rev)
        swap(tr[o].ls,tr[o].rs),tr[o].rev^=1,
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void build(int o,int l,int r)
{
    if(l==r)return void(tr[o].val=a[l]);
    tr[o].ls=o<<1;
    tr[o].rs=o<<1|1;
    tr[tr[o].ls].dep=tr[tr[o].rs].dep=tr[o].dep-1;
    int mid=(l+r)>>1;
    build(tr[o].ls,l,mid);
    build(tr[o].rs,mid+1,r);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
void modify(int o,int l,int r,int pos,int val)
{
    if(l==r)return void(tr[o].val=val);
    int mid=(l+r)>>1;pushdown(o);
    if(pos<=mid)modify(tr[o].ls,l,mid,pos,val);
    else modify(tr[o].rs,mid+1,r,pos,val);
    tr[o].val=tr[tr[o].ls].val+tr[tr[o].rs].val;
}
ll query(int o,int l,int r,int li,int ri)
{
    if(li<=l&&r<=ri)return tr[o].val;
    int mid=(l+r)>>1;pushdown(o);
    if(ri<=mid)return query(tr[o].ls,l,mid,li,ri);
    if(li>mid)return query(tr[o].rs,mid+1,r,li,ri);
    return query(tr[o].ls,l,mid,li,ri)+query(tr[o].rs,mid+1,r,li,ri);
}
signed main()
{
    scanf("%d%d",&n,&m);
    read(n),read(m),tr[1].dep=n;n=1<<n;
    for(int i=1;i<=n;++i)scanf("%d",a+i);
    build(1,1,n);
    for(int i=1,opt,pos,k;i<=m;++i)
    {
        read(opt);
        if(opt==1)
        {
            read(pos,k);
            modify(1,1,n,pos,k);
        }
        if(opt==2)
        {
            read(k);
            while(k)tag[k--]^=1;
        }
        if(opt==3)
        {
            read(k);tag[++k]^=1;
        }
        if(opt==4)
        {
            read(pos,k);
            printf("%lld\n",query(1,1,n,pos,k));
        }
    }
    return 0;
}


//Link : https://codeforces.com/contest/1253

#include <bits/stdc++.h>
using namespace std;
#define ll long long
/*
#include <limits.h>
INT_MAX
LLONG_MAX
*/
#define B 18
#define N (1<<18)

int a[N];
ll seg[N*4];

void init(int pos,int l,int r) {
  if(l==r) {
    seg[pos] = a[l];
    return;
  }
  int mid = (l+r)/2;
  init(pos*2,l,mid);
  init(pos*2+1,mid+1,r);
  seg[pos] = seg[pos*2] + seg[pos*2+1];
}

void update(int pos,int l,int r,int ind,int val) {
  if(l==r) {
    seg[pos] = val;
    return;
  }
  int mid = (l+r)/2;
  if(ind<=mid)
    update(pos*2,l,mid,ind,val);
  else
    update(pos*2+1,mid+1,r,ind,val);
  seg[pos] = seg[pos*2] + seg[pos*2+1];
}

ll query(int pos,int l,int r,int ql,int qr) {
  if(r<ql || qr<l) {
    return 0LL;
  }
  if(ql<=l && r<=qr) {
    return seg[pos];
  }
  int mid = (l+r)/2;
  return query(pos*2,l,mid,ql,qr) + query(pos*2+1,mid+1,r,ql,qr);
}

ll getSum(int totalBit,int n,int b,int l) {
  ll ret = 0;
  if(l==n) {
    return query(1,0,n-1,0,n-1);
  }
  int cur = 0,curBit = 0;
  for(int bit=b-1;bit>=0;--bit) {
    if(totalBit&(1<<bit)) {
      curBit ^= (1<<bit);
    }
    if(l&(1<<bit)) {
      int ncur = cur^curBit;
      int ed = ncur + (1<<bit) - 1;
      assert(ed<n);
      ret += query(1,0,n-1,ncur,ed);
      cur += (1<<bit);
    }

  }
  return ret;
}

void solve() {
  int b,q;
  scanf("%d %d ",&b,&q);
  int n = (1<<b);
  for(int i=0;i<n;++i) {
    scanf("%d ", &a[i]);
  }
  int bit=0;
  init(1,0,n-1);
  while(q--) {
    int type;
    scanf("%d ", &type);
    int x,y;
    if(type==1) {
      scanf("%d %d", &x,&y);
      --x;
      update(1,0,n-1,x,y);
    } else if(type==2) {
      scanf("%d ", &x);
      int g = (1<<x)-1;
      bit ^= g;
    } else if(type==3) {
      scanf("%d ", &x);
      bit ^= (1<<x);
    } else if(type==4) {
      scanf("%d %d", &x,&y);
      --x,--y;
      ll ret = getSum(bit,n,b,y+1);
      if(x-1>=0) {
        ret -= getSum(bit,n,b,x);
      }
      printf("%lld\n", ret);
    } else {
      assert(0);
    }
  }
}

int main() {
  //freopen("input.txt","r",stdin);
  solve();
  return 0;
}


//Link : https://codeforces.com/contest/1253

#include <bits/stdc++.h>
using namespace std;
#define ll long long
/*
#include <limits.h>
INT_MAX
LLONG_MAX
*/
#define B 18
#define N (1<<18)

int a[N];
ll seg[N*4];

void init(int pos,int l,int r) {
  if(l==r) {
    seg[pos] = a[l];
    return;
  }
  int mid = (l+r)/2;
  init(pos*2,l,mid);
  init(pos*2+1,mid+1,r);
  seg[pos] = seg[pos*2] + seg[pos*2+1];
}

void update(int pos,int l,int r,int ind,int val) {
  if(l==r) {
    seg[pos] = val;
    return;
  }
  int mid = (l+r)/2;
  if(ind<=mid)
    update(pos*2,l,mid,ind,val);
  else
    update(pos*2+1,mid+1,r,ind,val);
  seg[pos] = seg[pos*2] + seg[pos*2+1];
}

ll query(int pos,int l,int r,int ql,int qr) {
  if(r<ql || qr<l) {
    return 0LL;
  }
  if(ql<=l && r<=qr) {
    return seg[pos];
  }
  int mid = (l+r)/2;
  return query(pos*2,l,mid,ql,qr) + query(pos*2+1,mid+1,r,ql,qr);
}

ll getSum(int totalBit,int n,int b,int l) {
  ll ret = 0;
  if(l==n) {
    return query(1,0,n-1,0,n-1);
  }
  int cur = 0,curBit = 0;
  for(int bit=b-1;bit>=0;--bit) {
    if(totalBit&(1<<bit)) {
      curBit ^= (1<<bit);
    }
    if(l&(1<<bit)) {
      int ncur = cur^curBit;
      int ed = ncur + (1<<bit) - 1;
      assert(ed<n);
      ret += query(1,0,n-1,ncur,ed);
      cur += (1<<bit);
    }
  }
  return ret;
}

void solve() {
  int b,q;
  scanf("%d %d ",&b,&q);
  int n = (1<<b);
  for(int i=0;i<n;++i) {
    scanf("%d ", &a[i]);
  }
  int bit=0;
  init(1,0,n-1);
  while(q--) {
    int type;
    scanf("%d ", &type);
    int x,y;
    if(type==1) {
      scanf("%d %d", &x,&y);
      --x;
      x^=bit;
      update(1,0,n-1,x,y);
    } else if(type==2) {
      scanf("%d ", &x);
      int g = (1<<x)-1;
      bit ^= g;
    } else if(type==3) {
      scanf("%d ", &x);
      bit ^= (1<<x);
    } else if(type==4) {
      scanf("%d %d", &x,&y);
      --x,--y;
      ll ret = getSum(bit,n,b,y+1);
      if(x-1>=0) {
        ret -= getSum(bit,n,b,x);
      }
      printf("%lld\n", ret);
    } else {
      assert(0);
    }
  }
}

int main() {
  //freopen("input.txt","r",stdin);
  solve();
  return 0;
}


#include<bits/stdc++.h>
#define lson (rt<<1|(rev[d[rt]]))
#define rson (rt<<1|(rev[d[rt]]^1))
using namespace std;const int N=(1<<20);typedef long long ll;
int n,m,i,j,rev[22],d[N*4],q,op;ll a[N*4];
void update(int rt){a[rt]=a[lson]+a[rson];}
void build(int rt,int l,int r,int dep){
	d[rt]=dep;if(l==r){scanf("%lld",a+rt);return;}int mid=l+r>>1;
	build(lson,l,mid,dep-1);build(rson,mid+1,r,dep-1);update(rt);
}
void modify(int rt,int l,int r,int pos,int v){
	if(l==r){a[rt]=v;return;}int mid=l+r>>1;
	pos<=mid?modify(lson,l,mid,pos,v):modify(rson,mid+1,r,pos,v);update(rt);
}
ll query(int rt,int l,int r,int L,int R){
	if(L<=l&&r<=R)return a[rt];int mid=l+r>>1;ll res=0;
	if(L<=mid)res=query(lson,l,mid,L,R);if(R>mid)res+=query(rson,mid+1,r,L,R);return res;
}
int main(){
	for(scanf("%d%d",&n,&q),build(1,1,(1<<n),n),n=(1<<n);q--;){
		scanf("%d",&op);
		if(op==1)scanf("%d%d",&i,&j),modify(1,1,n,i,j);
		if(op==2)for(scanf("%d",&j),i=0;i<=j;++i)rev[i]^=1;
		if(op==3)scanf("%d",&j),rev[j+1]^=1;
		if(op==4)scanf("%d%d",&i,&j),printf("%lld\n",query(1,1,n,i,j));
	}
}


#include<map>
#include<list>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define in inline
#define ll long long
#define INF 2147483647
#define ri register int
#define rc register char
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
in int read(){
	rc c=' ';
	ri v=0,x=1;
	while((c<'0')||(c>'9')){if(c=='-') x=-1;c=getchar();}
	while((c>='0')&&(c<='9')){v=(v<<1)+(v<<3)+(c^48);c=getchar();}
	return v*x;
}
in void write(ri x){
	if(x<0) x=-x,putchar('-');
	if(x>9) write(x/10);
	putchar(x%10^48);
}
const int N=1<<20|15;
int n,m,val[N];
bool rev[N];
void build(ri l,ri r,ri rt){
	if(l==r){
		val[rt]=read();
		return;
	}
	ri mid=l+r>>1;
	build(l,mid,ls),build(mid+1,r,rs);
	val[rt]=val[ls]+val[rs];
}
void modify(ri l,ri r,ri rt,ri dep,ri p,ri v){
	if(l==r){
		val[rt]=v;
		return;
	}
	ri mid=l+r>>1;
	if(p<=mid) modify(l,mid,ls|rev[dep],dep-1,p,v);
	else modify(mid+1,r,ls|rev[dep]^1,dep-1,p,v);
	val[rt]=val[ls]+val[rs];
}
int query(ri l,ri r,ri rt,ri dep,ri L,ri R){
	if(L<=l&&r<=R) return val[rt];
	ri mid=l+r>>1,res=0;
	if(L<=mid) res+=query(l,mid,ls|rev[dep],dep-1,L,R);
	if(R>mid) res+=query(mid+1,r,ls|rev[dep]^1,dep-1,L,R);
	return res;
}
in void reverse(ri k){
	for(ri i=0;i<=k;i++)
		rev[i]^=1;
}
int main(){
	n=read(),m=read();
	build(1,1<<n,1);
	for(ri i=1;i<=m;i++){
		ri op=read();
		if(op==1){
			ri x=read(),y=read();
			modify(1,1<<n,1,n,x,y);
		}
		if(op==2) reverse(read());
		if(op==3) rev[read()+1]^=1;
		if(op==4){
			ri x=read(),y=read();
			write(query(1,1<<n,1,n,x,y)),putchar('\n');
		}
	}
	return ~~(0-0);
}


#include<iostream>
#include<cstdio>
using namespace std;
int n,q;
long long a[(1<<18)+1];
bool k_rev[19],k_swp[19];
struct Node
{
	int l,r;
	long long vl;
};
Node t[4*(1<<18)+1];
void bld(int k,int l_,int r_)
{
	t[k].l=l_;
	t[k].r=r_;
	if(l_==r_)
	{
		t[k].vl=a[l_];
		return ;
	}
	int md=(l_+r_)>>1;
	bld(k*2,l_,md);
	bld(k*2+1,md+1,r_);
	t[k].vl=t[k*2].vl+t[k*2+1].vl;
	return ;
}
void mdf(int k,int x,long long v,bool ttd,int cnt)
{
	ttd^=k_rev[k];
	int md=(t[k].l+t[k].r)>>1;
	if(!k_swp[k])
	{

	}

}
int main()
{
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)
	scanf("%lld",&a[i]);
	bld(1,1,n);
	while(q--)
	{
		int op;
		scanf("%d",&op);
		if(op==1)
		{
			int x,k;
			scanf("%d%d",&x,&k);
			mdf(1,x,k,false,1);
		}
		if(op==2)
		{
			int k;
			scanf("%d",&k);
			k_rev[19-k]^=1;
		}
		if(op==3)
		{
			int k;
			scanf("%d",&k);
			k_swp[18-k]^=1;
		}
		if(op==4)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			printf("%d\n",qry(1,l,r,false,1));
		}
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls (u<<1)
#define rs (u<<1|1)
using namespace std;
typedef long long ll;
int n,q,op,x,y,a[262150],rev[25];
ll sum[1048580];
inline void pushup(int u){
	sum[u]=sum[ls]+sum[rs];
}
void build(int u,int l,int r){
	if(l==r){
		sum[u]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(u);
}
void modify(int u,int l,int r,int x,int y,int dep){
	if(l==r){
		sum[u]=y;
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid)modify(ls^rev[dep],l,mid,x,y,dep-1);
	else modify(rs^rev[dep],mid+1,r,x,y,dep-1);
	pushup(u);
}
ll query(int u,int l,int r,int x,int y,int dep){
	if(l>=x && r<=y)return sum[u];
	int mid=(l+r)>>1;
	ll res=0;
	if(x<=mid)res+=query(ls^rev[dep],l,mid,x,y,dep-1);
	if(y>mid)res+=query(rs^rev[dep],mid+1,r,x,y,dep-1);
	return res;
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<=1<<n;++i)
		scanf("%d",a+i);
	build(1,1,1<<n);
	while(q--){
		scanf("%d%d",&op,&x);
		if(op==1 || op==4)scanf("%d",&y);
		if(op==1)
			modify(1,1,1<<n,x,y,n);
		if(op==2)
			for(int i=0;i<=x;++i)rev[i]^=1;
		if(op==3)
			rev[x+1]^=1;
		if(op==4)
			printf("%lld\n",query(1,1,1<<n,x,y,n));
	}
	return 0;
}


#include "cstdio"
#include "algorithm"
#include "vector"
#include "map"

using namespace std;

long long seg[524299];
int lazy[524299];
int A[524299];

void build(int node, int ss, int se) {
	if(ss == se) {
		seg[node] = A[ss];
		lazy[node] = 0;
		return;
	}
	int mid = (ss + se) >> 1;
	build(node * 2, ss, mid);
	build(node * 2 + 1, mid + 1, se);
	seg[node] = seg[node * 2] + seg[node * 2 + 1];
	lazy[node] = 0;
}

// void updateLazy(int node, int ss, int se, int size, bool is_type_three = false) {
// 	if(se - ss + 1 == (1 << size)) {
// 		lazy[node]++;
// 		if(is_type_three) {
// 			lazy[node * 2]++;
// 			lazy[node * 2 + 1]++;
// 			lazy[node * 2] %= 2;
// 			lazy[node * 2 + 1] %= 2;
// 		}
// 		lazy[node] %= 2;
// 		return;
// 	}
// 	int mid = (ss + se) >> 1;
// 	updateLazy(node * 2, ss, mid, size, is_type_three);
// 	updateLazy(node * 2 + 1, mid + 1, se, size, is_type_three);
// }

long long lazyCountArr[20];
map<int, int> mp;
void populateMap() {
	for(int i = 0 ; i <= 20 ; i++) {
		mp[1 << i] = i;
	}
}

void updateValue(int node, int ss, int se, int index, int val, int lazyCount = 0) {
	if(index < ss || index > se) {
		return;
	}
	if(ss == se) {
		seg[node] = val;
		return;
	}
	lazyCount += lazyCountArr[mp[(se - ss + 1)]];
	int newIndex = index;
	if(lazyCount % 2) {
		newIndex = ss + se - index;
	}
	int mid = (ss + se) >> 1;
	updateValue(node * 2, ss, mid, newIndex, val);
	updateValue(node * 2 + 1, mid + 1, se, newIndex, val);
	seg[node] = seg[node * 2] + seg[node * 2 + 1];
}

long long query(int node, int ss, int se, int qs, int qe, int lazyCount = 0) {
	if(ss > se || qs > se || qe < ss) {
		return 0;
	}
	// printf("ADFDSFSDF %d %d %d %d %d\n", node, ss, se, qs, qe);
	if(ss >= qs && se <= qe) {
		return seg[node];
	}
	lazyCount += lazyCountArr[mp[(se - ss + 1)]];
	int new_qs = max(ss, qs);
	int new_qe = min(qe, se);
	if(lazyCount % 2) {
		int temp_new_qs = ss + se - new_qs;
		int temp_new_qe = ss + se - new_qe;
		new_qs = temp_new_qe;
		new_qe = temp_new_qs;
	}
	int mid = (ss + se) >> 1;
	return query(node * 2, ss, mid, new_qs, new_qe) + query(node * 2 + 1, mid + 1, se, new_qs, new_qe);
}

int main() {
	populateMap();
	int N, Q;
	scanf("%d%d", &N, &Q);
	for(int i = 1 ; i <= (1 << N) ; i++) {
		scanf("%d", A + i);
	}
	build(1, 1, 1 << N);
	while(Q--) {
		int type;
		scanf("%d", &type);
		if(type == 1) {
			int index, val;
			scanf("%d%d", &index, &val);
			updateValue(1, 1, 1 << N, index, val);
		}
		else if(type == 2) {
			int k;
			scanf("%d", &k);
			// updateLazy(1, 1, (1 << N), k);
			lazyCountArr[k]++;
		}
		else if(type == 3) {
			int k;
			scanf("%d", &k);
			lazyCountArr[k + 1]++;
			lazyCountArr[k]++;
			// if(k != N) {
			// 	updateLazy(1, 1, (1 << N), k + 1, true);
			// }
		}
		else {
			int l, r;
			scanf("%d%d", &l, &r);
			long long res = query(1, 1, 1 << N, l, r);
			printf("%lld\n", res);
		}
		// for(int i = 1 ; i <= 8 ; i++) {
		// 	printf("NODE %d : %lld\n", i, query(1, 1, 1 << N, i, i));
		// }
		// printf("-----------\n");
	}
	return 0;
}


#include "cstdio"
#include "algorithm"
#include "vector"

using namespace std;

long long seg[524299];
int lazy[524299];
int A[524299];

void build(int node, int ss, int se) {
	if(ss == se) {
		seg[node] = A[ss];
		lazy[node] = 0;
		return;
	}
	int mid = (ss + se) >> 1;
	build(node * 2, ss, mid);
	build(node * 2 + 1, mid + 1, se);
	seg[node] = seg[node * 2] + seg[node * 2 + 1];
	lazy[node] = 0;
}

void updateLazy(int node, int ss, int se, int size, bool is_type_three = false) {
	if(se - ss + 1 == (1 << size)) {
		lazy[node]++;
		if(is_type_three) {
			lazy[node * 2]++;
			lazy[node * 2 + 1]++;
			lazy[node * 2] %= 2;
			lazy[node * 2 + 1] %= 2;
		}
		lazy[node] %= 2;
		return;
	}
	int mid = (ss + se) >> 1;
	updateLazy(node * 2, ss, mid, size, is_type_three);
	updateLazy(node * 2 + 1, mid + 1, se, size, is_type_three);
}

void updateValue(int node, int ss, int se, int index, int val) {
	if(index < ss || index > se) {
		return;
	}
	if(ss == se) {
		seg[node] = val;
		return;
	}
	int newIndex = index;
	if(lazy[node] % 2) {
		newIndex = ss + se - index;
	}
	int mid = (ss + se) >> 1;
	updateValue(node * 2, ss, mid, newIndex, val);
	updateValue(node * 2 + 1, mid + 1, se, newIndex, val);
	seg[node] = seg[node * 2] + seg[node * 2 + 1];
}

long long query(int node, int ss, int se, int qs, int qe) {
	if(ss > se || qs > se || qe < ss) {
		return 0;
	}
	// printf("ADFDSFSDF %d %d %d %d %d\n", node, ss, se, qs, qe);
	if(ss >= qs && se <= qe) {
		return seg[node];
	}
	int new_qs = max(ss, qs);
	int new_qe = min(qe, se);
	if(lazy[node] % 2) {
		int temp_new_qs = ss + se - new_qs;
		int temp_new_qe = ss + se - new_qe;
		new_qs = temp_new_qe;
		new_qe = temp_new_qs;
	}
	int mid = (ss + se) >> 1;
	return query(node * 2, ss, mid, new_qs, new_qe) + query(node * 2 + 1, mid + 1, se, new_qs, new_qe);
}

int main() {
	int N, Q;
	scanf("%d%d", &N, &Q);
	for(int i = 1 ; i <= (1 << N) ; i++) {
		scanf("%d", A + i);
	}
	build(1, 1, 1 << N);
	while(Q--) {
		int type;
		scanf("%d", &type);
		if(type == 1) {
			int index, val;
			scanf("%d%d", &index, &val);
			updateValue(1, 1, 1 << N, index, val);
		}
		else if(type == 2) {
			int k;
			scanf("%d", &k);
			updateLazy(1, 1, (1 << N), k);
		}
		else if(type == 3) {
			int k;
			scanf("%d", &k);
			if(k != N) {
				updateLazy(1, 1, (1 << N), k + 1, true);
			}
		}
		else {
			int l, r;
			scanf("%d%d", &l, &r);
			long long res = query(1, 1, 1 << N, l, r);
			printf("%lld\n", res);
		}
		// for(int i = 1 ; i <= 8 ; i++) {
		// 	printf("NODE %d : %lld\n", i, query(1, 1, 1 << N, i, i));
		// }
		// printf("-----------\n");
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include <map>
#include <queue>
#include <set>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <bitset>
#include <array>
#include <cctype>
#include <time.h>

#pragma GCC optimize(2)

void read_f() { freopen("1.in", "r", stdin); freopen("1.out", "w", stdout);}
void fast_cin() { std::ios::sync_with_stdio(false); std::cin.tie(); }
void run_time() { std::cout << "ESC in : " << clock() * 1000.0 / CLOCKS_PER_SEC << "ms" << std::endl; }

#define ll long long
#define ull unsigned ll
#define _min(x, y) ((x)>(y)?(y):(x))
#define _max(x, y) ((x)>(y)?(x):(y))
#define max3(x, y, z) ( max( (x), max( (y), (z) ) ) )
#define min3(x, y, z) ( min( (x), min( (y), (z) ) ) )
#define pr(x, y) (make_pair((x), (y)))
#define pb(x) push_back(x);
using namespace std;

const int N = 2e6+5;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;

ll sum[N];
struct Sign
{
    bool rflag;
    bool tflag;
} de[N];
ll su[N];
void pushup(int p)
{
    sum[p] = sum[p<<1] + sum[p<<1|1];
}
void build(int p, int l, int r)
{
    sum[p] = 0;
    if (l == r) { sum[p] = su[l]; return;}
    int mid = (l + r) >> 1;
    build(p<<1, l, mid);
    build(p<<1|1, mid+1, r);
    pushup(p);
}
void change(int p, int l, int r, int k, int v, int dep, int rev)
{
    if (l == r)
    { sum[p] = v; return; }
    int mid = (l + r) >> 1;
    int revp = rev ^ de[dep].rflag;
    if (k <= mid)
    {
        if (revp ^ de[dep].tflag)
            change(p<<1|1, l, mid, k, v, dep+1, revp);
        else change(p<<1, l, mid, k, v, dep+1, revp);
    }
    else
    {
        if (revp ^ de[dep].tflag)
            change(p<<1, mid+1, r, k, v, dep+1, revp);
        else change(p<<1|1, mid+1, r, k, v, dep+1, revp);
    }
    pushup(p);
}
ll ask(int p, int l, int r, int cl, int cr, int dep, int rev)
{
    if (cl <= l && r <= cr)
        return sum[p];
    int mid = (l + r) >> 1;
    int revp = rev ^ de[dep].rflag;
    ll val = 0;
    if (cl <= mid)
    {
        if (revp ^ de[dep].tflag)
            val += ask(p<<1|1, l, mid, cl, cr, dep+1, revp);
        else val += ask(p<<1, l, mid, cl, cr, dep+1, revp);
    }
    if (cr > mid)
    {
        if (revp ^ de[dep].tflag)
            val += ask(p<<1, mid+1, r, cl, cr, dep+1, revp);
        else val += ask(p<<1|1, mid+1, r, cl, cr, dep+1, revp);
    }
    return val;
}
int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= (1 << n); i++)
        scanf("%d", &su[i]);
    build(1, 1, (1 << n));
    while(m--)
    {
        int op; scanf("%d", &op);
        if (op == 1)
        {
            int x, k; scanf("%d%d", &x, &k);
            change(1, 1, (1 << n), x, k, 1, 0);
        }
        else if (op == 2)
        {
            int k; scanf("%d", &k);
            de[n - k + 1].rflag ^= 1;
        }
        else if (op == 3)
        {
            int k; scanf("%d", &k);
            de[n - k].tflag ^= 1;
        }
        else
        {
            int l, r; scanf("%d%d", &l, &r);
            printf("%lld\n", ask(1, 1, (1 << n), l, r, 1, 0 ));
        }
    }
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include <map>
#include <queue>
#include <set>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <bitset>
#include <array>
#include <cctype>
#include <time.h>

#pragma GCC optimize(2)

void read_f() { freopen("1.in", "r", stdin); freopen("1.out", "w", stdout);}
void fast_cin() { std::ios::sync_with_stdio(false); std::cin.tie(); }
void run_time() { std::cout << "ESC in : " << clock() * 1000.0 / CLOCKS_PER_SEC << "ms" << std::endl; }

#define ll long long
#define ull unsigned ll
#define _min(x, y) ((x)>(y)?(y):(x))
#define _max(x, y) ((x)>(y)?(x):(y))
#define max3(x, y, z) ( max( (x), max( (y), (z) ) ) )
#define min3(x, y, z) ( min( (x), min( (y), (z) ) ) )
#define pr(x, y) (make_pair((x), (y)))
#define pb(x) push_back(x);
using namespace std;

const int N = 2e6+5;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;

int sum[N];
struct Sign
{
    bool rflag;
    bool tflag;
} de[N];
ll su[N];
void pushup(int p)
{
    sum[p] = sum[p<<1] + sum[p<<1|1];
}
void build(int p, int l, int r)
{
    sum[p] = 0;
    if (l == r) { sum[p] = su[l]; return;}
    int mid = (l + r) >> 1;
    build(p<<1, l, mid);
    build(p<<1|1, mid+1, r);
    pushup(p);
}
void change(int p, int l, int r, int k, int v, int dep, int rev)
{
    if (l == r)
    { sum[p] = v; return; }
    int mid = (l + r) >> 1;
    int revp = rev ^ de[dep].rflag;
    if (k <= mid)
    {
        if (revp ^ de[dep].tflag)
            change(p<<1|1, l, mid, k, v, dep+1, revp);
        else change(p<<1, l, mid, k, v, dep+1, revp);
    }
    else
    {
        if (revp ^ de[dep].tflag)
            change(p<<1, mid+1, r, k, v, dep+1, revp);
        else change(p<<1|1, mid+1, r, k, v, dep+1, revp);
    }
    pushup(p);
}
ll ask(int p, int l, int r, int cl, int cr, int dep, int rev)
{
    if (cl <= l && r <= cr)
        return sum[p];
    int mid = (l + r) >> 1;
    int revp = rev ^ de[dep].rflag;
    ll val = 0;
    if (cl <= mid)
    {
        if (revp ^ de[dep].tflag)
            val += ask(p<<1|1, l, mid, cl, cr, dep+1, revp);
        else val += ask(p<<1, l, mid, cl, cr, dep+1, revp);
    }
    if (cr > mid)
    {
        if (revp ^ de[dep].tflag)
            val += ask(p<<1, mid+1, r, cl, cr, dep+1, revp);
        else val += ask(p<<1|1, mid+1, r, cl, cr, dep+1, revp);
    }
    return val;
}
int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= (1 << n); i++)
        scanf("%d", &su[i]);
    build(1, 1, (1 << n));
    while(m--)
    {
        int op; scanf("%d", &op);
        if (op == 1)
        {
            int x, k; scanf("%d%d", &x, &k);
            change(1, 1, (1 << n), x, k, 1, 0);
        }
        else if (op == 2)
        {
            int k; scanf("%d", &k);
            de[n - k + 1].rflag ^= 1;
        }
        else if (op == 3)
        {
            int k; scanf("%d", &k);
            de[n - k].tflag ^= 1;
        }
        else
        {
            int l, r; scanf("%d%d", &l, &r);
            printf("%lld\n", ask(1, 1, (1 << n), l, r, 1, 0 ));
        }
        // for (int i = 1; i <= (1 << n); i++)
        //     cout << ask(1, 1, (1 << n), i, i, 1, 0 ) << " ";
        // cout << endl;
    }
}


#include <bits/stdc++.h>

#define int long long
#define F first
#define S second
#define pii pair <int,int>
#define all(x) x.begin(),x.end()
#define pb push_back
#define SZ(x) x.begin(),x.end()

using namespace std;

const int N=1e6+9;
int a[N],seg[N];
bool b[20];

void UPD(int pos,int l,int r,int ind,int val,int h){
	if(ind<l || ind>r) return ;
	if(l==r){
		seg[pos]=val;
		return ;
	}
	int mid=(l+r)/2;
	if(b[h]) UPD(pos*2+1,l,mid,ind,val,h-1),UPD(pos*2,mid+1,r,ind,val,h-1);
	else UPD(pos*2,l,mid,ind,val,h-1),UPD(pos*2+1,mid+1,r,ind,val,h-1);
	seg[pos]=seg[pos*2]+seg[pos*2+1];
}

int SUM(int pos,int l,int r,int ql,int qr,int h){
	if(r<ql || l>qr) return 0;
	if(l>=ql && r<=qr) return seg[pos];
	int mid=(l+r)/2;
	if(b[h]) return SUM(pos*2+1,l,mid,ql,qr,h-1)+SUM(pos*2,mid+1,r,ql,qr,h-1);
	else return SUM(pos*2,l,mid,ql,qr,h-1)+SUM(pos*2+1,mid+1,r,ql,qr,h-1);
}

int32_t main(){
	ios::sync_with_stdio(0);cin.tie(0);
	int n,q;
	cin>>n>>q;
	int len=(1<<n);
	for(int i=0;i<(1<<n);i++){
		cin>>a[i];
		UPD(1,0,len-1,i,a[i],n);
	}
	while(q--){
		int f;
		cin>>f;
		if(f==1){
			int ind,x;
			ind--;
			cin>>ind>>x;
			UPD(1,0,len-1,ind,x,n);
		}
		if(f==2){
			int k;
			cin>>k;
			for(int i=k;i>=0;i--) b[i]^=1;
		}
		if(f==3){
			int k;
			cin>>k;
			b[k+1]^=1;
		}
		if(f==4){
			int l,r;
			cin>>l>>r;
			l--; r--;
			cout<<SUM(1,0,len-1,l,r,n)<<'\n';
		}
	}
	return 0;
}


#include <bits/stdc++.h>

#define int long long
#define F first
#define S second
#define pii pair <int,int>
#define all(x) x.begin(),x.end()
#define pb push_back
#define SZ(x) x.begin(),x.end()

using namespace std;

const int N=1e6+9;
int a[N],seg[N];
bool b[20];

void UPD(int pos,int l,int r,int ind,int val,int h){
	if(ind<l || ind>r) return ;
	if(l==r){
		seg[pos]=val;
		return ;
	}
	int mid=(l+r)/2;
	if(b[h]) UPD(pos*2+1,l,mid,ind,val,h-1),UPD(pos*2,mid+1,r,ind,val,h-1);
	else UPD(pos*2,l,mid,ind,val,h-1),UPD(pos*2+1,mid+1,r,ind,val,h-1);
	seg[pos]=seg[pos*2]+seg[pos*2+1];
}

int SUM(int pos,int l,int r,int ql,int qr,int h){
	if(r<ql || l>qr) return 0;
	if(l>=ql && r<=qr) return seg[pos];
	int mid=(l+r)/2;
	if(b[h]) return SUM(pos*2+1,l,mid,ql,qr,h-1)+SUM(pos*2,mid+1,r,ql,qr,h-1);
	else return SUM(pos*2,l,mid,ql,qr,h-1)+SUM(pos*2+1,mid+1,r,ql,qr,h-1);
}

int32_t main(){
	ios::sync_with_stdio(0);cin.tie(0);
	int n,q;
	cin>>n>>q;
	int len=(1<<n);
	for(int i=0;i<(1<<n);i++){
		cin>>a[i];
		UPD(1,0,len-1,i,a[i],n);
	}
	while(q--){
		int f;
		cin>>f;
		if(f==1){
			int ind,x;
			cin>>ind>>x;
			ind--;
			UPD(1,0,len-1,ind,x,n);
		}
		if(f==2){
			int k;
			cin>>k;
			for(int i=k;i>=0;i--) b[i]^=1;
		}
		if(f==3){
			int k;
			cin>>k;
			b[k+1]^=1;
		}
		if(f==4){
			int l,r;
			cin>>l>>r;
			l--; r--;
			cout<<SUM(1,0,len-1,l,r,n)<<'\n';
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = (1 << 18) + 10;
LL a[N], sum[N];
int depth[N];

void build(int u, int l, int r, int dep) {
    depth[u] = dep;
    if(l == r) {
        scanf("%lld", &sum[u]);
        return;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid, dep + 1);
    build(u << 1 | 1, mid + 1, r, dep + 1);
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
}

void update(int u, int l, int r, int x, int num) {
    if (x < l || r < x) return;
    if(l == r && l == x) {
        sum[u] = num;
        return;
    }
    int mid = l + r >> 1, dep = depth[u];
    if(a[dep] & 1) {
        update(u << 1 | 1, l, mid, x, num);
        update(u << 1, mid + 1, r, x, num);
    } else {
        update(u << 1, l, mid, x, num);
        update(u << 1 | 1, mid + 1, r, x, num);
    }
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
}

LL query(int u, int l, int r, int L, int R) {
    if(R < l || L > r) return 0;
    if(L <= l && r <= R) {
        return sum[u];
    }
    int dep = depth[u], mid = l + r >> 1;
    LL sum = 0;
    if(a[dep] & 1) {
        sum += query(u << 1, mid + 1, r, L, R);
        sum += query(u << 1 | 1, l, mid, L, R);
    } else {
        sum += query(u << 1, l, mid, L, R);
        sum += query(u << 1 | 1, mid + 1, r, L, R);
    }
    return sum;
}

void solve() {
    int n, q;
    scanf("%d%d", &n, &q);
    int m = 1 << n;
    build(1, 1, m, 1);
    while(q--) {
        int op; scanf("%d", &op);
        if(op == 1) {
            int x, num; scanf("%d%d", &x, &num);
            update(1, 1, m, x, num);
        }
        else if (op == 2) {
            int k; scanf("%d", &k);
            for(int i = n - k + 1; i <= n; i++) {
                a[i]++;
            }
        }
        else if (op == 3) {
            int k; scanf("%d", &k);
            a[n - k]++;
        }
        else {
            int l, r; scanf("%d%d", &l, &r);
            printf("%lld\n", query(1, 1, m, l, r));
        }
    }
}

int main() {
//    freopen("in.txt", "r", stdin);
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = (1 << 18) + 10;
LL a[N], sum[N << 2];
int depth[N << 2];

void build(int u, int l, int r, int dep) {
    depth[u] = dep;
    if(l == r) {
        scanf("%lld", &sum[u]);
        return;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid, dep + 1);
    build(u << 1 | 1, mid + 1, r, dep + 1);
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
}

void update(int u, int l, int r, int x, int num) {
    if (x < l || r < x) return;
    if(l == r && l == x) {
        sum[u] = num;
        return;
    }
    int mid = l + r >> 1, dep = depth[u];
    if(a[dep] & 1) {
        update(u << 1 | 1, l, mid, x, num);
        update(u << 1, mid + 1, r, x, num);
    } else {
        update(u << 1, l, mid, x, num);
        update(u << 1 | 1, mid + 1, r, x, num);
    }
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
}

LL query(int u, int l, int r, int L, int R) {
    if(R < l || L > r) return 0;
    if(L <= l && r <= R) {
        return sum[u];
    }
    int dep = depth[u], mid = l + r >> 1;
    LL sum = 0;
    if(a[dep] & 1) {
        sum += query(u << 1, mid + 1, r, L, R);
        sum += query(u << 1 | 1, l, mid, L, R);
    } else {
        sum += query(u << 1, l, mid, L, R);
        sum += query(u << 1 | 1, mid + 1, r, L, R);
    }
    return sum;
}

void solve() {
    int n, q;
    scanf("%d%d", &n, &q);
    int m = 1 << n;
    build(1, 1, m, 1);
    while(q--) {
        int op; scanf("%d", &op);
        if(op == 1) {
            int x, num; scanf("%d%d", &x, &num);
            update(1, 1, m, x, num);
        }
        else if (op == 2) {
            int k; scanf("%d", &k);
            for(int i = n - k + 1; i <= n; i++) {
                a[i]++;
            }
        }
        else if (op == 3) {
            int k; scanf("%d", &k);
            a[n - k]++;
        }
        else {
            int l, r; scanf("%d%d", &l, &r);
            printf("%lld\n", query(1, 1, m, l, r));
        }
    }
}

int main() {
//    freopen("in.txt", "r", stdin);
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = (1 << 18) + 10;
LL a[20], sum[N];
int depth[N];

void build(int u, int l, int r, int dep) {
    depth[u] = dep;
    if(l == r) {
        scanf("%lld", &sum[u]);
        return;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid, dep + 1);
    build(u << 1 | 1, mid + 1, r, dep + 1);
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
}

void update(int u, int l, int r, int x, int num) {
    if (x < l || r < x) return;
    if(l == r && l == x) {
        sum[u] = num;
        return;
    }
    int mid = l + r >> 1, dep = depth[u];
    if(a[dep] & 1) {
        update(u << 1 | 1, l, mid, x, num);
        update(u << 1, mid + 1, r, x, num);
    } else {
        update(u << 1, l, mid, x, num);
        update(u << 1 | 1, mid + 1, r, x, num);
    }
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
}

LL query(int u, int l, int r, int L, int R) {
    if(R < l || L > r) return 0;
    if(L <= l && r <= R) {
        return sum[u];
    }
    int dep = depth[u], mid = l + r >> 1;
    LL sum = 0;
    if(a[dep] & 1) {
        sum += query(u << 1, mid + 1, r, L, R);
        sum += query(u << 1 | 1, l, mid, L, R);
    } else {
        sum += query(u << 1, l, mid, L, R);
        sum += query(u << 1 | 1, mid + 1, r, L, R);
    }
    return sum;
}

void solve() {
    int n, q;
    scanf("%d%d", &n, &q);
    int m = 1 << n;
    build(1, 1, m, 1);
    while(q--) {
        int op; scanf("%d", &op);
        if(op == 1) {
            int x, num; scanf("%d%d", &x, &num);
            update(1, 1, m, x, num);
        }
        else if (op == 2) {
            int k; scanf("%d", &k);
            for(int i = n - k + 1; i <= n; i++) {
                a[i]++;
            }
        }
        else if (op == 3) {
            int k; scanf("%d", &k);
            a[n - k]++;
        }
        else {
            int l, r; scanf("%d%d", &l, &r);
            printf("%lld\n", query(1, 1, m, l, r));
        }
    }
}

int main() {
//    freopen("in.txt", "r", stdin);
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int>lg((1<<18)+1);
struct SeT{
#define ls (rev[lg[R-L]]==0?p*2+1:p*2+2)
#define rs (rev[lg[R-L]]==0?p*2+2:p*2+1)
#define m (L+R)/2
  vector<int64_t>dat;
  vector<int>rev;
  SeT(){}
  void build(int p,int L,int R,vector<int> &a){
    if(R-L==1)
      return dat[p]=a[L],void();
    build(ls,L,m,a);
    build(rs,m,R,a);
    dat[p]=dat[rs]+dat[ls];
  }
  void init(int n,vector<int> &a){
    dat.resize(4*(1<<n));
    rev.resize(n+2);
    build(0,0,1<<n,a);
  }
  void Swap(int k){
    rev[k+1]^=1;
  }
  void Reverse(int k){
    for(int i=1;i<=k;++i) rev[i]^=1;
  }
  void Replace(int p,int L,int R,int x,int k){
    if(R-L==1){
      dat[p]=k;
      return;
    }
    if(x<m) Replace(ls,L,m,x,k);
    if(x>=m) Replace(rs,m,R,x,k);
    dat[p]=dat[ls]+dat[rs];
  }
  int64_t Sum(int p,int L,int R,int l,int r){
    if(l<=L&&R<=r)
      return dat[p];
    int64_t res=0;
    if(l<m) res+=Sum(ls,L,m,l,r);
    if(r>m) res+=Sum(rs,m,R,l,r);
    return res;
  }
};
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  for(int i=0;i<=1<<18;++i) lg[i]=log2(i);
  int n,q;
  cin>>n>>q;
  vector<int>a(1<<n);
  for(int i=0;i<1<<n;++i)
    cin>>a[i];
  SeT tree;
  tree.init(n,a);
  while(q--){
    int op;
    cin>>op;
    if(op==1){
      int x,v;
      cin>>x>>v;
      x--;
      tree.Replace(0,0,1<<n,x,v);
    }
    else if(op==2){
      int k;
      cin>>k;
      tree.Reverse(k);
    }
    else if(op==3){
      int k;
      cin>>k;
      tree.Swap(k);
    }
    else if(op==4){
      int l,r;
      cin>>l>>r;
      l--,r--;
      cout<<tree.Sum(0,0,1<<n,l,r+1)<<endl;
    }
  }
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int>lg(1<<18);
struct SeT{
#define ls (rev[lg[R-L]]==0?p*2+1:p*2+2)
#define rs (rev[lg[R-L]]==0?p*2+2:p*2+1)
#define m (L+R)/2
  vector<int64_t>dat;
  vector<int>rev;
  SeT(){}
  void build(int p,int L,int R,vector<int> &a){
    if(R-L==1)
      return dat[p]=a[L],void();
    build(ls,L,m,a);
    build(rs,m,R,a);
    dat[p]=dat[rs]+dat[ls];
  }
  void init(int n,vector<int> &a){
    dat.resize(4*(1<<n));
    rev.resize(n+2);
    build(0,0,1<<n,a);
  }
  void Swap(int k){
    rev[k+1]^=1;
  }
  void Reverse(int k){
    for(int i=1;i<=k;++i) rev[i]^=1;
  }
  void Replace(int p,int L,int R,int x,int k){
    if(R-L==1){
      dat[p]=k;
      return;
    }
    if(x<m) Replace(ls,L,m,x,k);
    if(x>=m) Replace(rs,m,R,x,k);
    dat[p]=dat[ls]+dat[rs];
  }
  int64_t Sum(int p,int L,int R,int l,int r){
    if(l<=L&&R<=r)
      return dat[p];
    int64_t res=0;
    if(l<m) res+=Sum(ls,L,m,l,r);
    if(r>m) res+=Sum(rs,m,R,l,r);
    return res;
  }
};
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  for(int i=0;i<1<<18;++i) lg[i]=log2(i);
  int n,q;
  cin>>n>>q;
  vector<int>a(1<<n);
  for(int i=0;i<1<<n;++i)
    cin>>a[i];
  SeT tree;
  tree.init(n,a);
  while(q--){
    int op;
    cin>>op;
    if(op==1){
      int x,v;
      cin>>x>>v;
      x--;
      tree.Replace(0,0,1<<n,x,v);
    }
    else if(op==2){
      int k;
      cin>>k;
      tree.Reverse(k);
    }
    else if(op==3){
      int k;
      cin>>k;
      tree.Swap(k);
    }
    else if(op==4){
      int l,r;
      cin>>l>>r;
      l--,r--;
      cout<<tree.Sum(0,0,1<<n,l,r+1)<<endl;
    }
  }
  return 0;
}


#include <bits/stdc++.h>
#define lowbit(x) (x & -x)
using namespace std;
const int N = 1 << 20;
int tag = 0;
struct BIT {
    long long s[N] = {}, len;
    void add(int x, int val) {
        for (int i = x; i <= len; i += lowbit(i))
            s[i] += val;
    }
    long long sum(int x) {
        long long ret = 0;
        for (int i = x; i; i -= lowbit(i))
            ret += s[i];
        return ret;
    }
} bit;
long long query(int ql, int qr, int l, int r, int d) {
    if (ql == l && qr == r) {
        l ^= (tag & -(1 << d)), r ^= (tag & -(1 << d));
        if (l > r) swap(l, r);
        return bit.sum(++r) - bit.sum(l);
    }
    int mid = (l + r) >> 1;
    if (qr <= mid) return query(ql, qr, l, mid, d - 1);
    else if (mid + 1 <= ql) return query(ql, qr, mid + 1, r, d - 1);
    else return query(ql, mid, l, mid, d - 1) + query(mid + 1, qr, mid + 1, r, d - 1);
}
int main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n, m, x;
    cin >> n >> m;
    bit.len = 1 << n;
    for (int i = 1; i <= (1 << n); i++)
        cin >> x, bit.add(i, x);
    int opt, l, r, k, pos;
    while (m--) {
        cin >> opt;
        if (opt == 1) {
            cin >> pos >> x;
            pos = ((pos - 1) ^ tag) + 1;
            bit.add(pos, x - bit.sum(pos) + bit.sum(pos - 1));
        }
        if (opt == 2) {
            cin >> k;
            tag ^= ((1 << k) - 1);
        }
        if (opt == 3) {
            cin >> k;
            tag ^= (1 << k);
        }
        if (opt == 4) {
            cin >> l >> r;
            cout << query(--l, --r, 0, (1 << n) - 1, n) << '\n';
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define lowbit(x) (x & -x)
using namespace std;
const int N = 1 << 20;
int tag = 0;
struct BIT {
    long long s[N] = {}, len;
    void add(int x, int val) {
        for (int i = x; i <= len; i += lowbit(i))
            s[i] += val;
    }
    long long sum(int x) {
        long long ret = 0;
        for (int i = x; i; i -= lowbit(i))
            ret += s[i];
        return ret;
    }
} bit;
long long query(int ql, int qr, int l, int r, int d) {
    if (ql == l && qr == r) return bit.sum((r ^ (tag & -(1 << d))) + 1) - bit.sum(l ^ (tag & -(1 << d)));
    int mid = (l + r) >> 1;
    if (qr <= mid) return query(ql, qr, l, mid, d - 1);
    else if (mid + 1 <= ql) return query(ql, qr, mid + 1, r, d - 1);
    else return query(ql, mid, l, mid, d - 1) + query(mid + 1, qr, mid + 1, r, d - 1);
}
int main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n, m, x;
    cin >> n >> m;
    bit.len = 1 << n;
    for (int i = 1; i <= (1 << n); i++)
        cin >> x, bit.add(i, x);
    int opt, l, r, k, pos;
    while (m--) {
        cin >> opt;
        if (opt == 1) {
            cin >> pos >> x;
            pos = ((pos - 1) ^ tag) + 1;
            bit.add(pos, x - bit.sum(pos) + bit.sum(pos - 1));
        }
        if (opt == 2) {
            cin >> k;
            tag ^= ((1 << k) - 1);
        }
        if (opt == 3) {
            cin >> k;
            tag ^= (1 << k);
        }
        if (opt == 4) {
            cin >> l >> r;
            cout << query(--l, --r, 0, (1 << n) - 1, n) << '\n';
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define lowbit(x) (x & -x)
using namespace std;
const int N = 1 << 20;
int tag = 0;
struct BIT {
    long long s[N] = {}, len;
    void init(int x) {
        len = x;
    }
    void add(int x, int val) {
        while (x <= len) {
            s[x] += val;
            x += lowbit(x);
        }
    }
    long long sum(int x) {
        long long ret = 0;
        while (x) {
            ret += s[x];
            x -= lowbit(x);
        }
        return ret;
    }
    long long que(int l, int r) {
        return sum(r) - sum(l - 1);
    }
} bit;
long long query(int ql, int qr, int l, int r, int d) {
    if (ql == l && qr == r) {
        l ^= (tag & -(1 << d)), r ^= (tag & -(1 << d));
        if (l > r) swap(l, r);
        return bit.que(++l, ++r);
    }
    int mid = (l + r) >> 1;
    if (qr <= mid) return query(ql, qr, l, mid, d - 1);
    else if (mid + 1 <= ql) return query(ql, qr, mid + 1, r, d - 1);
    else return query(ql, mid, l, mid, d - 1) + query(mid + 1, qr, mid + 1, r, d - 1);
}
int main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n, m, x;
    cin >> n >> m;
    bit.init(1 << n);
    for (int i = 1; i <= (1 << n); i++) {
        cin >> x;
        bit.add(i, x);
    }
    int opt, l, r, k, pos;
    while (m--) {
        cin >> opt;
        if (opt == 1) {
            cin >> pos >> x;
            pos = ((pos - 1) ^ tag) + 1;
            bit.add(pos, x - bit.que(pos, pos));
        }
        if (opt == 2) {
            cin >> k;
            tag ^= ((1 << k) - 1);
        }
        if (opt == 3) {
            cin >> k;
            tag ^= (1 << k);
        }
        if (opt == 4) {
            cin >> l >> r;
            l--, r--;
            cout << query(l, r, 0, (1 << n) - 1, n) << '\n';
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,a[(1 << 18) + 5];
struct Segment_Tree
{
	int sum[(1 << 20) + 5],lazy[25];
	void pushup(int now)
	{
		sum[now] = sum[now << 1] + sum[now << 1 | 1];
	}
	void build(int now,int level,int l,int r)
	{
		if (l == r)
		{
			sum[now] = a[l];
			return ;
		}
		int mid = (l + r) >> 1;
		build(now << 1 | lazy[level],level - 1,l,mid);
		build(now << 1 | (lazy[level] ^ 1),level - 1,mid + 1,r);
		pushup(now);
	}
	void update(int now,int level,int l,int r,int x,int k)
	{
		if (l == r && l == x)
		{
			sum[now] = k;
			return ;
		}
		int mid = (l + r) >> 1;
		if (x <= mid) update(now << 1 | lazy[level],level - 1,l,mid,x,k);
		else if (x > mid) update(now << 1 | (lazy[level] ^ 1),level - 1,mid + 1,r,x,k);
		pushup(now);
	}
	int query(int now,int level,int l,int r,int ll,int rr)
	{
		if (ll <= l && rr >= r)
		{
			return sum[now];
		}
		int mid = (l + r) >> 1,ans = 0;
		if (ll <= mid) ans += query(now << 1 | lazy[level],level - 1,l,mid,ll,rr);
		if (rr > mid) ans += query(now << 1 | (lazy[level] ^ 1),level - 1,mid + 1,r,ll,rr);
		return ans;
	}
}T;

signed main()
{
	int q;
	scanf("%lld%lld",&n,&q);
	for (int i = 1; i <= (1 << n); i++)
	{
		scanf("%lld",&a[i]);
	}
	T.build(1,n,1,(1 << n));
	while (q--)
	{
		int opt;
		scanf("%lld",&opt);
		if (opt == 1)
		{
			int x,k;
			scanf("%lld%lld",&x,&k);
			T.update(1,n,1,(1 << n),x,k);
		}
		if (opt == 2)
		{
			int k;
			scanf("%lld",&k);
			for (int i = 0; i <= k; i++)
			{
				T.lazy[i] ^= 1;
			}
		}
		if (opt == 3)
		{
			int k;
			scanf("%lld",&k);
			T.lazy[k + 1] ^= 1;
		}
		if (opt == 4)
		{
			int l,r;
			scanf("%lld%lld",&l,&r);
			if (l > r) swap(l,r);
			int ans = T.query(1,n,1,(1 << n),l,r);
			printf("%lld\n",ans);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,a[1 << 18 + 5];
struct Segment_Tree
{
	int sum[1 << 20 + 5],lazy[25];
	void pushup(int now)
	{
		sum[now] = sum[now << 1] + sum[now << 1 | 1];
	}
	void build(int now,int level,int l,int r)
	{
		if (l == r)
		{
			sum[now] = a[l];
			return ;
		}
		int mid = (l + r) >> 1;
		build(now << 1 | lazy[level],level - 1,l,mid);
		build(now << 1 | (lazy[level] ^ 1),level - 1,mid + 1,r);
		pushup(now);
	}
	void update(int now,int level,int l,int r,int x,int k)
	{
		if (l == r && l == x)
		{
			sum[now] = k;
			return ;
		}
		int mid = (l + r) >> 1;
		if (x <= mid) update(now << 1 | lazy[level],level - 1,l,mid,x,k);
		else if (x > mid) update(now << 1 | (lazy[level] ^ 1),level - 1,mid + 1,r,x,k);
		pushup(now);
	}
	int query(int now,int level,int l,int r,int ll,int rr)
	{
		if (ll <= l && rr >= r)
		{
			return sum[now];
		}
		int mid = (l + r) >> 1,ans = 0;
		if (ll <= mid) ans += query(now << 1 | lazy[level],level - 1,l,mid,ll,rr);
		if (rr > mid) ans += query(now << 1 | (lazy[level] ^ 1),level - 1,mid + 1,r,ll,rr);
		return ans;
	}
}T;

signed main()
{
	int q;
	scanf("%lld%lld",&n,&q);
	for (int i = 1; i <= (1 << n); i++)
	{
		scanf("%lld",&a[i]);
	}
	T.build(1,n,1,(1 << n));
	while (q--)
	{
		int opt;
		scanf("%lld",&opt);
		if (opt == 1)
		{
			int x,k;
			scanf("%lld%lld",&x,&k);
			T.update(1,n,1,(1 << n),x,k);
		}
		if (opt == 2)
		{
			int k;
			scanf("%lld",&k);
			for (int i = 0; i <= k; i++)
			{
				T.lazy[i] ^= 1;
			}
		}
		if (opt == 3)
		{
			int k;
			scanf("%lld",&k);
			T.lazy[k + 1] ^= 1;
		}
		if (opt == 4)
		{
			int l,r;
			scanf("%lld%lld",&l,&r);
			if (l > r) swap(l,r);
			int ans = T.query(1,n,1,(1 << n),l,r);
			printf("%lld\n",ans);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,q,s;
const int N = (1<<18)+10;
int flag[22];
typedef long long ll;
ll t[N<<2];
void pushup(int id){
	t[id]=t[id<<1]+t[id<<1|1];
}
void update(int id,int l,int r,int pos,int val,int d){
	if(r<pos||l>pos) return;
	if(l==r){
		t[id]=val;
		return;
	}
	int mid=l+r>>1;
	if(flag[d]) update(id<<1,mid+1,r,pos,val,d-1),update(id<<1|1,l,mid,pos,val,d-1);
	else update(id<<1,l,mid,pos,val,d-1),update(id<<1|1,mid+1,r,pos,val,d-1);
	pushup(id);
}
ll query(int id,int l,int r,int L,int R,int d){
	if(r<L||l>R) return 0;
	if(L<=l&&R>=r) return t[id];
	int mid=l+r>>1;
	ll ans=0;
	if(flag[d]) ans+=query(id<<1,mid+1,r,L,R,d-1)+query(id<<1|1,l,mid,L,R,d-1);
	else ans+=query(id<<1,l,mid,L,R,d-1)+query(id<<1|1,mid+1,r,L,R,d-1);
	return ans;
}
int main(){
	scanf("%d%d",&n,&q);
	s=(1<<n);
	for(int i = 1; i <= s; i++){
		int x;
		scanf("%d",&x);
		update(1,1,s,i,x,n);
	}
	while(q--){
		int op,x,y;
		scanf("%d%d",&op,&x);
		if(op==1||op==4){
			scanf("%d",&y);
		}
		if(op==1) update(1,1,s,x,y,n);
		else if(op==2) for(int i = 0; i <= x; i++) flag[i]^=1;
		else if(op==3) flag[x+1]^=1;
		else printf("%lld\n",query(1,1,s,x,y,n));
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,q,s;
const int N = (1<<18)+10;
int t[N<<2],flag[22];
typedef long long ll;
void pushup(int id){
	t[id]=t[id<<1]+t[id<<1|1];
}
void update(int id,int l,int r,int pos,int val,int d){
	if(r<pos||l>pos) return;
	if(l==r){
		t[id]=val;
		return;
	}
	int mid=l+r>>1;
	if(flag[d]) update(id<<1,mid+1,r,pos,val,d-1),update(id<<1|1,l,mid,pos,val,d-1);
	else update(id<<1,l,mid,pos,val,d-1),update(id<<1|1,mid+1,r,pos,val,d-1);
	pushup(id);
}
ll query(int id,int l,int r,int L,int R,int d){
	if(r<L||l>R) return 0;
	if(L<=l&&R>=r) return t[id];
	int mid=l+r>>1;
	ll ans=0;
	if(flag[d]) ans+=query(id<<1,mid+1,r,L,R,d-1)+query(id<<1|1,l,mid,L,R,d-1);
	else ans+=query(id<<1,l,mid,L,R,d-1)+query(id<<1|1,mid+1,r,L,R,d-1);
	return ans;
}
int main(){
	scanf("%d%d",&n,&q);
	s=(1<<n);
	for(int i = 1; i <= s; i++){
		int x;
		scanf("%d",&x);
		update(1,1,s,i,x,n);
	}
	while(q--){
		int op,x,y;
		scanf("%d%d",&op,&x);
		if(op==1||op==4){
			scanf("%d",&y);
		}
		if(op==1) update(1,1,s,x,y,n);
		else if(op==2) for(int i = 0; i <= x; i++) flag[i]^=1;
		else if(op==3) flag[x+1]^=1;
		else printf("%lld\n",query(1,1,s,x,y,n));
	}
	return 0;
}


#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ub              upper_bound
#define lb              lower_bound
#define isrt            insert
#define clr             clear
#define rsz             resize
#define ff              first
#define ss              second
#define lli             long long int
#define pb              push_back
#define pf              push_front
#define mkp              make_pair
#define pii             pair<lli,lli>
#define vi              vector<int>
#define mii             map<lli,lli>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zrobits(x)      __builtin_ctzll(x)
#define mod             1000000007
#define INF             1e9
#define ps(x,y)         fixed<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)            int x; cin>>x; while(x--)
#define all(v)          v.begin(),v.end()
#define endl            "\n"
const double PI = acos(-1);

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

lli maxm(lli a, lli b)
{
    return (a >= b ? a : b);
}

lli minm(lli a, lli b)
{
    return (a <= b ? a : b);
}

lli power(lli x, lli y, lli p)
{
    lli res = 1;

    x = x % p;
    if (x == 0)
        return 0;

    while (y > 0)
    {

        if (y & 1)
            res = (res * x) % p;

        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}

lli nCrmodp(lli n, lli r, lli p)
{
    if (r == 0)
        return 1;
    if (r == 1)
        return n;

    lli pro = 1, k = n;
    while (k > r)
    {
        pro *= k;
        pro %= p;
        --k;
    }

    k = 2;
    while (k <= (n - r))
    {
        pro *= power(k, (p - 2), p);
        pro %= p;
        ++k;
    }

    return pro;
}

lli first_big(lli n, lli k, vector<lli> arr)
{
    lli l, r, ans = n;
    l = 0;
    r = n - 1;

    while (l <= r) {
        lli m = l + (r - l) / 2;

        if (arr[m] > k) {
            ans = m;
            r = m - 1;
        }

        else
            l = m + 1;
    }

    return ans;
}

lli last_small(lli n, lli k, vector<lli> arr)
{
    lli l, r, ans = -1;
    l = 0;
    r = n - 1;

    while (l <= r)
    {
        lli mid = (l + r) / 2;

        if (arr[mid] <= k)
        {
            ans = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }

    return ans;
}

void c_p_c()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
}

struct cmp {

    bool operator()(pair<pii, int> a, pair<pii, int> b)
    {
        if (a.ff.ff != b.ff.ff)
            return a.ff.ff < b.ff.ff;
        else
          {
               if (a.ff.ss != b.ff.ss)
                return a.ff.ss < b.ff.ss;
            else
                return a.ss < b.ss;
          }
    }

};

int main()
{
    c_p_c();

    vector<pair<pii, int>> v;
    int n, k;

    cin >> n >> k;
    int l, r;

    for (int i = 0; i < n; ++i)
    {
        cin >> l >> r;
        pii pr = make_pair(l, r);
        v.pb(make_pair(pr, i + 1));
    }

    sort(all(v), cmp());
    vector<int>cnt(201);
    vector<int>ans1;
    vector<int>ans2;
    int c1 = 0, c2 = 0;

    for (int i = 0; i < n; ++i)
    {
        l = v[i].ff.ff;
        r = v[i].ff.ss;

        bool status = 0;

        for (int j = l; j <= r; ++j)
        {
            if (cnt[j] == k)
                status = 1;
        }

        if (status)
        {
            ++c1;
            ans1.pb(v[i].ss);
        }
        else
        {
            for (int j = l; j <= r; ++j)
                cnt[j] += 1;

        }
    }

    cnt.clr();
    cnt.rsz(201);

    for (int i = n - 1; i >= 0; i--)
    {
        l = v[i].ff.ff;
        r = v[i].ff.ss;

        bool status = 0;

        for (int j = l; j <= r; ++j)
        {
            if (cnt[j] == k)
                status = 1;
        }

        if (status)
        {
            ++c2;
            ans2.pb(v[i].ss);
        }
        else
        {
            for (int j = l; j <= r; ++j)
                cnt[j] += 1;

        }
    }

    if (c1 <= c2)
    {
        cout << c1 << endl;
        for (int i = 0; i < c1; ++i)
            cout << ans1[i] << " ";

        cout << endl;
    }
    else
    {
        cout << c2 << endl;
        for (int i = 0; i < c2; ++i)
            cout << ans2[i] << " ";
        cout << endl;
    }

    return 0;
}


#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ub              upper_bound
#define lb              lower_bound
#define isrt            insert
#define clr             clear
#define rsz             resize
#define ff              first
#define ss              second
#define lli             long long int
#define pb              push_back
#define pf              push_front
#define mkp              make_pair
#define pii             pair<lli,lli>
#define vi              vector<int>
#define mii             map<lli,lli>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zrobits(x)      __builtin_ctzll(x)
#define mod             1000000007
#define INF             1e9
#define ps(x,y)         fixed<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)            int x; cin>>x; while(x--)
#define all(v)          v.begin(),v.end()
#define endl            "\n"
const double PI = acos(-1);

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

lli maxm(lli a, lli b)
{
    return (a >= b ? a : b);
}

lli minm(lli a, lli b)
{
    return (a <= b ? a : b);
}

void c_p_c()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
}

struct cmp {

    bool operator()(pair<pii, int> a, pair<pii, int> b)
    {
        if (a.ff.ss != b.ff.ss)
            return a.ff.ss > b.ff.ss;
        else
            return a.ff.ff > b.ff.ff;
    }

};

int main()
{
    c_p_c();

    vector<pair<pii, int>> v;
    int n, k;

    cin >> n >> k;
    int l, r;

    for (int i = 0; i < n; ++i)
    {
        cin >> l >> r;
        pii pr = make_pair(l, r);
        v.pb(make_pair(pr, i + 1));
    }

    sort(all(v), cmp());
    vector<int>cnt(201);
    vector<int>ans;
    int c = 0;

    for (int i = 0; i < n; ++i)
    {
        l = v[i].ff.ff;
        r = v[i].ff.ss;

        bool status = 0;

        for (int j = l; j <= r; ++j)
        {
            if (cnt[j] == k)
                status = 1;
        }

        if (status)
        {
            ++c;
            ans.pb(v[i].ss);
        }
        else
        {
            for (int j = l; j <= r; ++j)
                cnt[j] += 1;

        }
    }

    cout << c << endl;
    for (auto it : ans)
        cout << it << " ";
    cout << endl;

    return 0;
}


#include <bits/stdc++.h>
#include<random>
using namespace std; typedef unsigned long long _ulong; typedef long long int lint; typedef pair<lint, lint> plint; typedef pair<double long, double long> pld;
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((lint)(x).size())
#define FOR(i, begin, end) for(lint i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(lint i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
#define endk '\n'
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
const lint MOD = 1e9 + 7, INF = 1e18;
lint dx[8] = { 0, -1, 1, 0, 1, -1, 1, -1 }, dy[8] = { 1, 0, 0, -1, -1, -1, 1, 1 };
typedef pair<double, lint> Pa;
typedef pair<plint, lint> tlint;
struct edge {
	lint cost;
	lint u, v;
};

const lint MAX_SEG = 2e5;
lint N, K, a, b;
vector<plint> seg[MAX_SEG];
int main() {
	cin >> N >> K;
	REP(i, N) {
		cin >> a >> b; a--; b--;
		seg[a].push_back({ b, i });
	}
	vector<lint> ans;
	set<plint> st;
	REP(i, MAX_SEG) {
		for (auto itr : seg[i]) {
			st.insert(itr);
		}
		while (SZ(st) > K) {
			auto itr = st.rbegin();
			ans.push_back((*itr).second);
			st.erase(*itr);
		}
		while (SZ(st) != 0) {
			auto itr = st.begin();
			if ((*itr).first != i) break;
			st.erase(*itr);
		}
	}
	cout << SZ(ans) << endk;
	REP(i, SZ(ans)) {
		cout << ans[i] + 1 << " ";
	}
	cout << endk;
}


#include <bits/stdc++.h>
#include<random>
using namespace std; typedef unsigned long long _ulong; typedef long long int lint; typedef pair<lint, lint> plint; typedef pair<double long, double long> pld;
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((lint)(x).size())
#define FOR(i, begin, end) for(lint i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(lint i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
#define endk '\n'
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
const lint MOD = 1e9 + 7, INF = 1e18;
lint dx[8] = { 0, -1, 1, 0, 1, -1, 1, -1 }, dy[8] = { 1, 0, 0, -1, -1, -1, 1, 1 };
typedef pair<double, lint> Pa;
typedef pair<plint, lint> tlint;
struct edge {
	lint cost;
	lint u, v;
};

lint N, K, a, b;
tlint arr[200000];
bool erased[200000];
int main() {
	cin >> N >> K;
	REP(i, N) {
		cin >> a >> b;
		arr[i] = { {b, a}, i };
		erased[i] = false;
	}
	sort(arr, arr + N);
	vector<lint> ans;
	REP(i, N) {
		if (erased[i]) continue;
		lint curr = arr[i].first.first, st_idx = i;
		while (i + 1 < N && curr >= arr[i + 1].first.second) i++;
		REP(j, i - st_idx + 1 - K) {
			if (!erased[i - j])ans.push_back(arr[i - j].second + 1);
			erased[i - j] = true;
		}
		i = st_idx;
	}
	cout << SZ(ans) << endk;
	REP(i, SZ(ans)) {
		cout << ans[i] << " ";
	}
	cout << endk;
}


#include <bits/stdc++.h>
#include<random>
using namespace std; typedef unsigned long long _ulong; typedef long long int lint; typedef pair<lint, lint> plint; typedef pair<double long, double long> pld;
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((lint)(x).size())
#define FOR(i, begin, end) for(lint i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(lint i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
#define endk '\n'
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
const lint MOD = 1e9 + 7, INF = 1e18;
lint dx[8] = { 0, -1, 1, 0, 1, -1, 1, -1 }, dy[8] = { 1, 0, 0, -1, -1, -1, 1, 1 };
typedef pair<double, lint> Pa;
typedef pair<plint, lint> tlint;
struct edge {
	lint cost;
	lint u, v;
};

lint N, K, a, b;
tlint arr[200000];
int main() {
	cin >> N >> K;
	REP(i, N) {
		cin >> a >> b;
		arr[i] = { {b, a}, i };
	}
	sort(arr, arr + N);
	vector<lint> ans;
	REP(i, N) {
		lint curr = arr[i].first.first, st_idx = i;
		while (i + 1 < N && curr >= arr[i + 1].first.second) i++;
		REP(j, i - st_idx + 1 - K) {
			ans.push_back(arr[i - j].second + 1);
		}
	}
	cout << SZ(ans) << endk;
	REP(i, SZ(ans)) {
		cout << ans[i] << " ";
	}
	cout << endk;
}


#include <bits/stdc++.h>
#include<random>
using namespace std; typedef unsigned long long _ulong; typedef long long int lint; typedef pair<lint, lint> plint; typedef pair<double long, double long> pld;
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((lint)(x).size())
#define FOR(i, begin, end) for(lint i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(lint i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
#define endk '\n'
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
const lint MOD = 1e9 + 7, INF = 1e18;
lint dx[8] = { 0, -1, 1, 0, 1, -1, 1, -1 }, dy[8] = { 1, 0, 0, -1, -1, -1, 1, 1 };
typedef pair<double, lint> Pa;
typedef pair<plint, lint> tlint;
struct edge {
	lint cost;
	lint u, v;
};

lint N, K, a, b;
tlint arr[200000];
int main() {
	cin >> N >> K;
	REP(i, N) {
		cin >> a >> b; a--; b--;
		arr[i] = { {b, a}, i };
	}
	sort(arr, arr + N);
	vector<lint> ans;
	REP(i, N) {
		lint curr = arr[i].first.first, st_idx = i;
		while (i + 1 < N && curr >= arr[i + 1].first.second) i++;
		REP(j, i - st_idx + 1 - K) {
			ans.push_back(arr[i-j].second + 1);
		}
	}
	cout << SZ(ans) << endk;
	REP(i, SZ(ans)) {
		cout << ans[i] << " ";
	}
	cout << endk;
}


//                              jai shree ram 3-i _/\_
#include<bits/stdc++.h>

#define mod 1000000007
#define pb push_back
#define lli long long int
#define ll long long
#define mk make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define plli pair<lli,lli>
#define mii map<int,int>
#define mlli map<lli,lli>
#define test lli chu;cin>>chu;while(chu--)
#define loop(i,n) for(lli i=0;i<n;i++)
#define lop(i,n) for(lli i=1;i<=n;i++)
#define pp  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define PI 3.141592653589793238462643383279502884197169399375105820974944592307816406286
#define S(z) z.size()
#define tom set<lli>
#define fill(a,b) memset(a, b, sizeof(a))
#define all(x) (x).begin(), (x).end()

#define en cout<<"\n"
#define YES cout<<"YES"
#define NO  cout<<"NO"
#define Yes cout<<"Yes"
#define No  cout<<"No"
#define er  cout<<"-1"

#define tks(s) string s; cin>>s
#define tk1(n) lli n; cin>>n
#define tk2(n,k) tk1(n);tk1(k)
#define tk3(a,b,c) tk2(a,b);tk1(c)
#define tk4(a,b,c,d) tk3(a,b,c);tk1(d)
#define tttt vector<lli>

#define trace(x) cout<<#x<<": "<<x<<" "<<endl
#define trace2(x,y) cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x,y,z) cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a,b,c,d) cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl

using namespace std;
const long long INF64 = 1e18;
lli pow2(lli a,lli n,lli p)
{
    if(a == 0)
    return 0;
    if(n == 0)
    return 1;
    if(n%2 == 0)
    return (pow2(((a%p)*(a%p))%p,n/2,p)%p);
    else
    return ((pow2(((a%p)*(a%p))%p,n/2,p)%p)*(a%p))%p;
}

int main()
{
pp;
tk2(n,k);
plli p[n];
lli cnt[202],i,j;
fill(cnt,0);
vector<lli> v;
	for(i=0;i<n;i++)
	{
		cin>> p[i].fi >> p[i].se;
		cnt[p[i].fi]++;
		cnt[p[i].se+1]--;
	}

		for(i=1;i<=201;i++)
		{
			cnt[i] += cnt[i-1];
		}
		lli ans[n];
		fill(ans,0);
		lli pos = -1;
		for(i=1;i<=200;i++)
		{
			pos = -1;
			while(cnt[i]>k)
			{
				pos=-1;
				for(j=0;j<n;j++)
				{
					if(ans[j]==1) continue;
					if(i>= p[j].fi && i<=p[j].se && (pos==-1 || p[j].se>p[pos].se))
					{
						pos = j;
					}
				}
				if(pos == -1) continue;
				for(j=p[pos].fi;j<=p[pos].se;j++)
				{
					cnt[j]--;
				}
				ans[pos] =1;
				v.pb(pos);
			}
		}
		sort(all(v));
		cout<<S(v);
		en;
		loop(i,S(v)) cout<<v[i]+1<<" ";

return 0;
}


//                              jai shree ram 3-i _/\_
#include<bits/stdc++.h>

#define mod 1000000007
#define pb push_back
#define lli long long int
#define ll long long
#define mk make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define plli pair<lli,lli>
#define mii map<int,int>
#define mlli map<lli,lli>
#define test lli chu;cin>>chu;while(chu--)
#define loop(i,n) for(lli i=0;i<n;i++)
#define lop(i,n) for(lli i=1;i<=n;i++)
#define pp  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define PI 3.141592653589793238462643383279502884197169399375105820974944592307816406286
#define S(z) z.size()
#define tom set<lli>
#define fill(a,b) memset(a, b, sizeof(a))
#define all(x) (x).begin(), (x).end()

#define en cout<<"\n"
#define YES cout<<"YES"
#define NO  cout<<"NO"
#define Yes cout<<"Yes"
#define No  cout<<"No"
#define er  cout<<"-1"

#define tks(s) string s; cin>>s
#define tk1(n) lli n; cin>>n
#define tk2(n,k) tk1(n);tk1(k)
#define tk3(a,b,c) tk2(a,b);tk1(c)
#define tk4(a,b,c,d) tk3(a,b,c);tk1(d)
#define tttt vector<lli>

#define trace(x) cout<<#x<<": "<<x<<" "<<endl
#define trace2(x,y) cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x,y,z) cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a,b,c,d) cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl

using namespace std;
const long long INF64 = 1e18;
lli pow2(lli a,lli n,lli p)
{
    if(a == 0)
    return 0;
    if(n == 0)
    return 1;
    if(n%2 == 0)
    return (pow2(((a%p)*(a%p))%p,n/2,p)%p);
    else
    return ((pow2(((a%p)*(a%p))%p,n/2,p)%p)*(a%p))%p;
}

int main()
{
pp;
tk2(n,k);
plli p[n];
lli cnt[202],i,j;
fill(cnt,0);
vector<lli> v;
	for(i=0;i<n;i++)
	{
		cin>> p[i].fi >> p[i].se;
		cnt[p[i].fi]++;
		cnt[p[i].se+1]--;
	}

		for(i=1;i<=201;i++)
		{
			cnt[i] += cnt[i-1];
		}
		lli ans[n];
		lli pos = -1;
		for(i=1;i<=201;i++)
		{
			pos = -1;
			while(cnt[i]>k)
			{
				pos=-1;
				for(j=0;j<n;j++)
				{
					if(ans[j]==1) continue;
					if(i>= p[j].fi && i<=p[j].se && (pos==-1 || p[j].se>p[pos].se))
					{
						pos = j;
					}
				}
				if(pos == -1) continue;
				for(j=p[pos].fi;j<=p[pos].se;j++)
				{
					cnt[j]--;
				}
				ans[pos] =1;
				v.pb(pos);
			}
		}
		sort(all(v));
		cout<<S(v);
		en;
		loop(i,S(v)) cout<<v[i]+1<<" ";

return 0;
}