#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
using namespace std;
int n, m, cnt, a[50005], rot[200005], opt, ans, uu, vv, ww;
struct Node{
int l, r, siz, hav, val, rnd;
}nd[4000005];
void upd(int k){
nd[k].siz = nd[nd[k].l].siz + nd[nd[k].r].siz + nd[k].hav;
}
void lRotate(int &k){
int t=nd[k].r; nd[k].r = nd[t].l; nd[t].l = k;
nd[t].siz = nd[k].siz; upd(k); k = t;
}
void rRotate(int &k){
int t=nd[k].l; nd[k].l = nd[t].r; nd[t].r = k;
nd[t].siz = nd[k].siz; upd(k); k = t;
}
void treapInsert(int &k, int x){
if(!k){
k = ++cnt; nd[k].siz = nd[k].hav = 1;
nd[k].val = x; nd[k].rnd = rand();
return ;
}
nd[k].siz++;
if(nd[k].val==x) nd[k].hav++;
else if(nd[k].val>x){
treapInsert(nd[k].l, x);
if(nd[nd[k].l].rnd<nd[k].rnd) rRotate(k);
}
else{
treapInsert(nd[k].r, x);
if(nd[nd[k].r].rnd<nd[k].rnd) lRotate(k);
}
}
void treapDelete(int &k, int x){
if(!k) return ;
if(nd[k].val==x){
if(nd[k].hav>1){
nd[k].hav--; nd[k].siz--;
return ;
}
else if(nd[k].l*nd[k].r==0) k = nd[k].l + nd[k].r;
else if(nd[nd[k].l].rnd<nd[nd[k].r].rnd)
rRotate(k), treapDelete(k, x);
else
lRotate(k), treapDelete(k, x);
}
else if(nd[k].val<x) nd[k].siz--, treapDelete(nd[k].r, x);
else nd[k].siz--, treapDelete(nd[k].l, x);
}
int treapQueryRank(int k, int x){
if(!k) return 0;
if(nd[k].val>x) return treapQueryRank(nd[k].l, x);
else if(nd[k].val<x) return treapQueryRank(nd[k].r, x)+nd[nd[k].l].siz+nd[k].hav;
else return nd[nd[k].l].siz;
}
void treapQueryPre(int k, int x){
if(!k) return ;
if(nd[k].val<x) ans = max(ans, nd[k].val), treapQueryPre(nd[k].r, x);
else treapQueryPre(nd[k].l, x);
}
void treapQueryNxt(int k, int x){
if(!k) return ;
if(nd[k].val>x) ans = min(ans, nd[k].val), treapQueryNxt(nd[k].l, x);
else treapQueryNxt(nd[k].r, x);
}
void sgtInsert(int o, int l, int r, int x, int k){
treapInsert(rot[o], k);
if(l==r) ;
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(x<=mid) sgtInsert(lson, l, mid, x, k);
if(mid<x) sgtInsert(rson, mid+1, r, x, k);
}
}
void sgtDelete(int o, int l, int r, int x, int k){
treapDelete(rot[o], k);
if(l==r) ;
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(x<=mid) sgtDelete(lson, l, mid, x, k);
if(mid<x) sgtDelete(rson, mid+1, r, x, k);
}
}
int sgtQueryRank(int o, int l, int r, int x, int y, int k){
if(l>=x && r<=y) return treapQueryRank(rot[o], k);
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
int re=0;
if(x<=mid) re += sgtQueryRank(lson, l, mid, x, y, k);
if(mid<y) re += sgtQueryRank(rson, mid+1, r, x, y, k);
return re;
}
}
void sgtQueryPre(int o, int l, int r, int x, int y, int k){
if(l>=x && r<=y) treapQueryPre(rot[o], k);
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(x<=mid) sgtQueryPre(lson, l, mid, x, y, k);
if(mid<y) sgtQueryPre(rson, mid+1, r, x, y, k);
}
}
void sgtQueryNxt(int o, int l, int r, int x, int y, int k){
if(l>=x && r<=y) treapQueryNxt(rot[o], k);
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(x<=mid) sgtQueryNxt(lson, l, mid, x, y, k);
if(mid<y) sgtQueryNxt(rson, mid+1, r, x, y, k);
}
}
int queryKth(int uu, int vv, int ww){
int l=0, r=100000000, mid, re;
while(l<=r){
mid = (l + r) >> 1;
if(sgtQueryRank(1, 1, n, uu, vv, mid)+1<=ww) re = mid, l = mid + 1;
else r = mid - 1;
}
return re;
}
int main(){
srand(time(NULL));
cin>>n>>m;
for(int i=1; i<=n; i++){
scanf("%d", &a[i]);
sgtInsert(1, 1, n, i, a[i]);
}
while(m--){
scanf("%d", &opt);
if(opt==1){
scanf("%d %d %d", &uu, &vv, &ww);
printf("%d\n", sgtQueryRank(1, 1, n, uu, vv, ww)+1);
}
if(opt==2){
scanf("%d %d %d", &uu, &vv, &ww);
printf("%d\n", queryKth(uu, vv, ww));
}
if(opt==3){
scanf("%d %d", &uu, &vv);
sgtDelete(1, 1, n, uu, a[uu]);
a[uu] = vv;
sgtInsert(1, 1, n, uu, vv);
}
if(opt==4){
scanf("%d %d %d", &uu, &vv, &ww);
ans = -2147483647;
sgtQueryPre(1, 1, n, uu, vv, ww);
printf("%d\n", ans);
}
if(opt==5){
scanf("%d %d %d", &uu, &vv, &ww);
ans = 2147483647;
sgtQueryNxt(1, 1, n, uu, vv, ww);
printf("%d\n", ans);
}
}
return 0;
}