const int MAXN=2e5+5,MAXB=30;
int a[MAXN];
int lef[MAXN<<2],rig[MAXN<<2],minv[MAXN<<2],minc[MAXN<<2],secv[MAXN<<2],lazy[MAXN<<2];
struct Node{
int bitnum[MAXB];
Node(int v=0){
_for(i,0,MAXB)
bitnum[i]=(v>>i)&1;
}
Node operator + (const Node &b)const{
Node c;
_for(i,0,MAXB)
c.bitnum[i]=bitnum[i]+b.bitnum[i];
return c;
}
Node operator += (const Node &b){
_for(i,0,MAXB)
bitnum[i]+=b.bitnum[i];
return *this;
}
}sum[MAXN<<2];
void push_up(int k){
sum[k]=sum[k<<1]+sum[k<<1|1];
if(minv[k<<1]==minv[k<<1|1]){
minv[k]=minv[k<<1];
minc[k]=minc[k<<1]+minc[k<<1|1];
secv[k]=min(secv[k<<1],secv[k<<1|1]);
}
else if(minv[k<<1]<minv[k<<1|1]){
minv[k]=minv[k<<1];
minc[k]=minc[k<<1];
secv[k]=min(secv[k<<1],minv[k<<1|1]);
}
else{
minv[k]=minv[k<<1|1];
minc[k]=minc[k<<1|1];
secv[k]=min(minv[k<<1],secv[k<<1|1]);
}
}
void push_tag(int k,int v){
if(v<=minv[k])return;
_for(i,0,MAXB){
if((minv[k]>>i)&1)
sum[k].bitnum[i]-=minc[k];
if((v>>i)&1)
sum[k].bitnum[i]+=minc[k];
}
minv[k]=lazy[k]=v;
}
void push_down(int k){
if(~lazy[k]){
push_tag(k<<1,lazy[k]);
push_tag(k<<1|1,lazy[k]);
lazy[k]=-1;
}
}
void build(int k,int L,int R){
lef[k]=L,rig[k]=R,lazy[k]=-1;
int M=L+R>>1;
if(L==R){
sum[k]=Node(a[M]);
minv[k]=a[M];
secv[k]=1<<MAXB;
minc[k]=1;
return;
}
build(k<<1,L,M);
build(k<<1|1,M+1,R);
push_up(k);
}
void update(int k,int L,int R,int v){
if(minv[k]>=v)return;
if(L<=lef[k]&&rig[k]<=R&&secv[k]>v)
return push_tag(k,v);
push_down(k);
int mid=lef[k]+rig[k]>>1;
if(mid>=L)update(k<<1,L,R,v);
if(mid<R)update(k<<1|1,L,R,v);
push_up(k);
}
Node query_sum(int k,int L,int R){
if(L<=lef[k]&&rig[k]<=R)return sum[k];
push_down(k);
int mid=lef[k]+rig[k]>>1;
Node s=Node();
if(mid>=L)s+=query_sum(k<<1,L,R);
if(mid<R)s+=query_sum(k<<1|1,L,R);
return s;
}
int main()
{
int n=read_int(),q=read_int();
_rep(i,1,n)a[i]=read_int();
build(1,1,n);
while(q--){
int op=read_int(),l=read_int(),r=read_int(),x=read_int();
if(op==1)
update(1,l,r,x);
else{
Node temp=query_sum(1,l,r)+Node(x);
int maxb=-1;
for(int i=MAXB-1;i>=0;i--){
if(temp.bitnum[i]&1){
maxb=i;
break;
}
}
if(maxb==-1)
enter(0);
else
enter(temp.bitnum[maxb]);
}
}
return 0;
}