#include
#include
#include<string>
#define int long long
#define WR WinterRain
#define Combo void//RIP
using namespace std;
const int WR=10010000,INF=2147483647;
int n,m;
int a[WR];
struct Treap_Tree{
struct BalanceTree{
int val,sze,rnk,ch[2],cnt;
}tree[WR];
int tot=0,root=1;
Combo pushup(int k){
tree[k].sze=tree[tree[k].ch[0]].sze+tree[tree[k].ch[1]].sze+tree[k].cnt;
}
int add_point(int v){
tree[++tot].val=v;
tree[tot].rnk=rand();
tree[tot].sze=tree[tot].cnt=1;
tree[tot].ch[0]=tree[tot].ch[1]=0;
return tot;
}
Combo rotat(int &id,int dir){
int tmp=tree[id].ch[dir^1];
tree[id].ch[dir^1]=tree[tmp].ch[dir];
tree[tmp].ch[dir]=id;
id=tmp;
pushup(tree[id].ch[dir]),pushup(id);
}
Combo insrt(int &id,int v){
if(!id){
id=add_point(v);
return;
}
if(v==tree[id].val) tree[id].cnt++;
else{
int dir;
if(v0;
else dir=1;
insrt(tree[id].ch[dir],v);
if(tree[id].rnk1);
}
pushup(id);
}
Combo remov(int &id,int v){
if(!id) return;
if(v==tree[id].val){
if(tree[id].cnt>1){
tree[id].cnt--;
pushup(id);
return;
}
if(tree[id].ch[0]||tree[id].ch[1]){
if(!tree[id].ch[1]||tree[tree[id].ch[0]].rnk>tree[tree[id].ch[1]].rnk){
rotat(id,1);remov(tree[id].ch[1],v);
}else{
rotat(id,0);remov(tree[id].ch[0],v);
}
pushup(id);
return;
}
id=0;return;
}
if(v0],v);
else remov(tree[id].ch[1],v);
pushup(id);
}
int get_rank(int id,int v){
if(!id) return 0;
//printf("%d %d\n",id,v);
if(v==tree[id].val) return tree[tree[id].ch[0]].sze;
if(vreturn get_rank(tree[id].ch[0],v);
else return get_rank(tree[id].ch[1],v)+tree[id].cnt+tree[tree[id].ch[0]].sze;
}
int get_val(int id,int rk){
if(!id) return INF;
if(rk<=tree[tree[id].ch[0]].sze) return get_val(tree[id].ch[0],rk);
else if(rk<=tree[id].cnt+tree[tree[id].ch[0]].sze) return tree[id].val;
else return get_val(tree[id].ch[1],rk-tree[tree[id].ch[0]].sze-tree[id].cnt);
}
int get_pre(int id,int v){
int pre=-INF;
while(id){
if(tree[id].val1];
else id=tree[id].ch[0];
}
return pre;
}
int get_nxt(int id,int v){
int nxt=INF;
while(id){
if(tree[id].val>v) nxt=tree[id].val,id=tree[id].ch[0];
else id=tree[id].ch[1];
}
//printf("%d\n\n",nxt);
return nxt;
}
}treap;
struct Segment_Tree{
struct SegmentTree{
int l,r,root;
}tree[WR];
Combo build(int k,int l,int r){
tree[k].l=l,tree[k].r=r;
for(int i=l;i<=r;i++) treap.insrt(tree[k].root,a[i]);
if(l==r) return;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
Combo modify(int k,int pos,int v){
treap.remov(tree[k].root,a[pos]);
treap.insrt(tree[k].root,v);
if(tree[k].l==tree[k].r) return;
int mid=(tree[k].l+tree[k].r)>>1;
if(pos<=mid) modify(k<<1,pos,v);
else modify(k<<1|1,pos,v);
}
int get_rank(int k,int l,int r,int v){
//printf("%d %d %d %d %d %d\n",k,tree[k].l,tree[k].r,l,r,tree[k].root);
if(tree[k].l>r||tree[k].rreturn 0;
if(tree[k].l>=l&&tree[k].r<=r) return treap.get_rank(tree[k].root,v);
else return get_rank(k<<1,l,r,v)+get_rank(k<<1|1,l,r,v);
}
int get_num(int st,int ed,int v){
int l=0,r=1e8;
while(l<r){
int mid=(l+r+1)>>1;
//printf("%d\n",get_rank(1,st,ed,mid));
if(get_rank(1,st,ed,mid)mid;
else r=mid-1;
}
return r;
}
int get_pre(int k,int l,int r,int v){
if(tree[k].l>r||tree[k].rreturn -INF;
if(tree[k].l>=l&&tree[k].r<=r) return treap.get_pre(tree[k].root,v);
else return max(get_pre(k<<1,l,r,v),get_pre(k<<1|1,l,r,v));
}
int get_nxt(int k,int l,int r,int v){
//printf("%d %d %d %d\n",k,tree[k].l,tree[k].r,v);
if(tree[k].l>r||tree[k].rreturn INF;
if(tree[k].l>=l&&tree[k].r<=r) return treap.get_nxt(tree[k].root,v);
else return min(get_nxt(k<<1,l,r,v),get_nxt(k<<1|1,l,r,v));
}
}segment;
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<1)+(s<<3)+ch-48;
ch=getchar();
}
return s*w;
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
segment.build(1,1,n);
for(int i=1;i<=m;i++){
int opt=read();
if(opt==1){
int l=read(),r=read(),v=read();
printf("%lld\n",segment.get_rank(1,l,r,v)+1);
}
if(opt==2){
int l=read(),r=read(),v=read();
printf("%lld\n",segment.get_num(l,r,v));
}
if(opt==3){
int pos=read(),x=read();
segment.modify(1,pos,x);
a[pos]=x;
}
if(opt==4){
int l=read(),r=read(),v=read();
printf("%lld\n",segment.get_pre(1,l,r,v));
}
if(opt==5){
int l=read(),r=read(),v=read();
printf("%lld\n",segment.get_nxt(1,l,r,v));
}
}
return 0;
}