RT,萌新根本调不出来qwq
void Aier();
#include<bits/stdc++.h>
#define AC return 0;
#define int long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
const int maxn = 3e6+10;
#pragma region //_READ_
char getc()
{
static char _buf[maxn<<2],*_s,*_t;
return (_s==_t)&&(_t=(_s=_buf)+fread(_buf,1,maxn<<2,stdin)),_s==_t?EOF:*_s++;
}
void read(int &x)
{
bool b=0;char ch=getc();x=0;
while(ch<'0'||ch>'9') {if(ch=='-') b=1;ch=getc();}
while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getc();}
b?x=-x:0;
}
int read()
{
bool b=0;char ch=getc();int x=0;
while(ch<'0'||ch>'9') {if(ch=='-') b=1;ch=getc();}
while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getc();}
return b?x=-x:x;
}
void read(int &x,int &y){read(x),read(y);}
void read(int &x,int &y,int &z){read(x),read(y),read(z);}
#pragma endregion
int n,m;
mt19937 mt('A'+'i'+'e'+'r');
struct node_
{
bool val;
int len;
}a[maxn];
struct ODT
{
struct node
{
int son[2],sum,pri,tag,min_len_0,min_len_1,siz,len,cnt_1,cnt_0;
bool val;
node():sum(0),pri(0),tag(0),min_len_0(0),min_len_1(0),siz(0),len(0){son[0]=son[1]=0;}
node(bool val,int len):val(val),len(len),sum(val*len),pri(mt()),siz(len),min_len_0(val?INF:len),min_len_1(val?len:INF),tag(0),cnt_0(!val),cnt_1(val) {son[0]=son[1]=0;}
}t[maxn];
#define min_len_0(u) t[u].min_len_0
#define min_len_1(u) t[u].min_len_1
#define cnt_1(u) t[u].cnt_1
#define cnt_0(u) t[u].cnt_0
#define ls(u) t[u].son[0]
#define rs(u) t[u].son[1]
#define sum(u) t[u].sum
#define pri(u) t[u].pri
#define tag(u) t[u].tag
#define siz(u) t[u].siz
#define len(u) t[u].len
#define val(u) t[u].val
int cnt,rt,st[maxn],top;
int new_node(bool val,int len){
if(top){
int u=st[top--];
if(!u) return t[++cnt]=node(val,len),cnt;
if(ls(u)) st[++top]=ls(u);
if(rs(u)) st[++top]=rs(u);
t[u]=node(val,len);
return u;
}
return t[++cnt]=node(val,len),cnt;
}
void addtag(int &u,int k){
if(!u) return;
len(u)+=k*(val(u)?1:-1);
tag(u)+=k;
if(len(u)<=0) {
push_down(u);
int l=ls(u),r=rs(u);
ls(u)=rs(u)=0;
st[++top]=u;
u=merge(l,r);
return;
}
sum(u)+=cnt_1(u)*k;
min_len_0(u)-=k,min_len_1(u)+=k;
if(((min_len_0(u)<=0)&&cnt_0(u))||((min_len_1(u)<=0)&&cnt_1(u))){
push_down(u);
int l=ls(u),r=rs(u);
ls(u)=rs(u)=0;
u=merge(l,merge(u,r));
push_up(u);
}
}
void push_down(int u){
if(tag(u)){
addtag(ls(u),tag(u));
addtag(rs(u),tag(u));
tag(u)=0;
push_up(u);
}
}
void push_up(int u){
if(!u) return;
siz(u)=siz(ls(u))+siz(rs(u))+len(u);
cnt_0(u)=cnt_0(ls(u))+cnt_0(rs(u))+!val(u);
cnt_1(u)=cnt_1(ls(u))+cnt_1(rs(u))+val(u);
sum(u)=sum(ls(u))+sum(rs(u))+len(u)*val(u);
if(val(u)){
min_len_0(u)=min(min_len_0(ls(u)),min_len_0(rs(u)));
min_len_1(u)=min(len(u),min(min_len_1(ls(u)),min_len_1(rs(u))));
}
else{
min_len_1(u)=min(min_len_1(ls(u)),min_len_1(rs(u)));
min_len_0(u)=min(len(u),min(min_len_0(ls(u)),min_len_0(rs(u))));
}
}
int _merge(int l,int r){
if(!l||!r) return l|r;
if(pri(l)<pri(r)){
push_down(l);
rs(l)=_merge(rs(l),r);
push_up(l);
return l;
}
else{
push_down(r);
ls(r)=_merge(l,ls(r));
push_up(r);
return r;
}
}
int find_l_node(int u){
if(ls(u)) return find_l_node(ls(u));
return u;
}
int find_r_node(int u){
if(rs(u)) return find_r_node(rs(u));
return u;
}
void split_l_node(int &u){
if(ls(u)) return split_l_node(ls(u)),push_up(u);
int tmp=u;
u=rs(u);
rs(tmp)=0;
push_up(tmp);
}
void split_r_node(int &u){
if(rs(u)) return split_r_node(rs(u)),push_up(u);
int tmp=u;
u=ls(u);
ls(tmp)=0;
push_up(tmp);
}
void merge_node(int &u,int v){
if(!u||!v) return;
if(rs(u)) return merge_node(rs(u),v),push_up(u);
if(val(u)==val(v)){
len(v)+=len(u);
push_up(v);
st[++top]=u;
int tmp=ls(u);
ls(u)=0;
u=tmp;
}
}
int merge(int l,int r) {
if(!l||!r) return l|r;
merge_node(l,find_l_node(r));
return _merge(l,r);
}
int split_node(int u,int siz){
int v=new_node(val(u),len(u)-siz);
len(u)=siz;
rs(v)=rs(u);
rs(u)=0;
push_up(u),push_up(v);
return v;
}
int split(int u,int x,int &l,int &r,bool sp_no){
if(!u) return l=r=0;
int tmp=0;
push_down(u);
if(siz(ls(u))>x)
r=u,tmp=split(ls(u),x,l,ls(u),sp_no);
else if(siz(ls(u))+len(u)<x)
l=u,tmp=split(rs(u),x-siz(ls(u))-len(u),rs(u),r,sp_no);
else{
if(siz(ls(u))==x)
r=u,l=ls(u),ls(u)=0;
else if(siz(ls(u))+len(u)==x)
l=u,r=rs(u),rs(u)=0;
else {
if(sp_no)
l=u,r=split_node(u,x-siz(ls(u)));
else
l=ls(u),r=rs(u),ls(u)=rs(u)=0,tmp=u;
}
}
push_up(u);
return tmp;
}
int build(int l,int r){
if(l>r) return 0;
int mid=(l+r)>>1,u=new_node(a[mid].val,a[mid].len);
ls(u)=build(l,mid-1);
rs(u)=build(mid+1,r);
push_up(u);
return u;
}
void init(){min_len_0(0)=min_len_1(0)=INF;rt=build(1,n);}
void assign(int l,int r,bool k){
int _l,_r,p,u,v;
split(rt,l-1,_l,p,1);
split(p,r-l+1,p,_r,1);
st[++top]=p;
rt=merge(_l,merge(new_node(k,r-l+1),_r));
}
int query(int l,int r){
int _l,_r,p;
split(rt,l-1,_l,p,1);
split(p,r-l+1,p,_r,1);
int ans=sum(p);
rt=merge(_l,merge(p,_r));
return ans;
}
void change(int l,int r,int opt){
int _l,_r,p,u,v;
u=split(rt,l-1,_l,p,0);
v=split(p,r-l+1,p,_r,0);
if(!u) u=find_l_node(p),split_l_node(p);
if(!v) v=find_r_node(p),split_r_node(p);
if(opt==1||opt==4){
if(val(u)) _l=merge(_l,u);
else p=merge(u,p);
if(val(v)) p=merge(p,v);
else _r=merge(v,_r);
}
else{
if(val(u)) p=merge(u,p);
else _l=merge(_l,u);
if(val(v)) _r=merge(v,_r);
else p=merge(p,v);
}
addtag(p,opt<=2?1:-1);
rt=merge(_l,merge(p,_r));
}
}t;
void solve()
{
int opt,l,r,last_ans=0;
while(m--)
{
read(opt,l,r);
l^=last_ans,r^=last_ans;
if(opt==7) printf("%d\n",last_ans=t.query(l,r));
else if(opt==1||opt==2) t.assign(l,r,opt-1);
else t.change(l,r,opt-2);
}
}
void init()
{
read(n,m);
int last=-1,u,cnt=0;
while(n--)
{
u=read();
if(u==last) ++a[cnt].len;
else a[++cnt].val=last=u,a[cnt].len=1;
}
n=cnt;
t.init();
}
#pragma region //_MAIN_
signed main()
{
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
int T=1;
// read(T);
while(T--)
Aier();
AC
}
void Aier()
{
init();
solve();
}
#pragma endregion