#include<bits/stdc++.h>
#define N 2000010
using namespace std;
template<int lim>
struct kthtrie{
template<short lm>
struct Trie{
int ch[4000005][2],d[4000005],v[4000005],sum[4000005],s[4000005],tot=1,rt[4000005];
int New(int p,int dep){
sum[++tot]=p;d[tot]=dep;return tot;
}
int g(int x,int i){return (x>>i)&1;}
int rev(int x){
int ans=0;
for(int i=0;i<lm;++i)ans+=g(x,i)<<(lm-i-1);
return ans;
}
void add(int x,int val,int t){int v1=x;x=rev(x);int p=(rt[t])? rt[t]:rt[t]=++tot,k=0,lt=0;
for(int i=0;i<lm;++i){k++;int c1=g(x,i);
while(i>d[p]){if(!ch[p][c1]){ch[p][c1]=New(x>>i,lm);
v[tot]=v1;
s[ch[p][c1]]=val;
return;}
lt=p;k=i-d[p];p=ch[p][c1];
s[lt]+=val;}
int c2=g(sum[p],k-1);
if(c1!=c2){int u=New(sum[p],i-1);s[u]=s[p]+val;
ch[u][c2]=p;ch[u][c1]=New(x>>i,lm);
ch[lt][g(sum[p],0)]=u;
sum[p]>>=(k-1);
lt=u;p=ch[u][c1];k=1;s[p]+=val;v[p]=v1;
return;}}
s[p]+=val;}
void insert(int x,int t){add(x,1,t);}
void erase(int x,int t){add(x,-1,t);}
int rank(int x,int t){add(x,0,t);
x=rev(x);
int p=(rt[t])? rt[t]:rt[t]=++tot,ans=0;
for(int i=0;i<lm;++i){int c1=g(x,i);
while(i>d[p])
{if(c1==1)ans+=s[ch[p][0]];
p=ch[p][c1];}}
return ans;}
int kth(int x,int t){int p=(rt[t])? rt[t]:rt[t]=++tot,k=x;
while(ch[p][0]||ch[p][1])if(k<=s[ch[p][0]]) p=ch[p][0];else k-=s[ch[p][0]],p=ch[p][1];
return v[p];}
int pre(int x,int t){return kth(rank(x,t),t);}
int nt(int x,int t){return kth(rank(x+1,t)+1,t);}
};
Trie<20> st;
long long lf[N],ch[2][N],tot,v[N],fa[N],val[N];
inline int New(){tot++;return tot;}
long long rev(long long x){
long long ans=0;
for(int i=0;i<lim;++i) ans+=((x>>i)&1)<<(lim-i-1);
return ans;
}
inline void insert(long long x,int t){
int temp=0;
v[t]=x;
x=rev(x);
int p=1;
for(int i=1;i<=lim;i++){
if(!ch[x&1][p]){
ch[x&1][p]=New();fa[ch[x&1][p]]=p;}
p=ch[x&1][p];
st.insert(t,p);
x>>=1;
}
lf[t]=p;
val[p]=v[t];
}
inline int getway(int p){
return p==ch[1][fa[p]];
}
inline void del(int t){
int p=lf[t];
while(p!=1){
st.erase(t,p);
p=fa[p];
}
}
inline void change(int t,int val){
del(t);
insert(val,t);
}
inline int getsize(int p,int l,int r){
return st.rank(r+1,p)-st.rank(l,p);
}
inline int getrank(int l,int r,int x){
x=rev(x);
int ans=0;
int p=1;
while(ch[1][p] || ch[0][p]){
if(x&1)
{
ans+=getsize(ch[0][p],l,r);
}
p=ch[x&1][p];
x>>=1;
}
return ans+1;
}
int kth(int l,int r,int k){
int p=1;
while(ch[1][p] || ch[0][p])
{
int temp=getsize(ch[0][p],l,r);
if(temp<k){
p=ch[1][p];k-=temp;
}else p=ch[0][p];
}
return v[st.kth(1,p)];
}
};
kthtrie<28> tr;
int t=0;
int main(){
tr.New();
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
tr.insert(x,i);
}
for(int i=1;i<=m;i++){
int l,r,k,op;
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",tr.getrank(l,r,k));
}
if(op==2){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",tr.kth(l,r,k));
}
if(op==3){
scanf("%d%d",&l,&k);
tr.change(l,k);
}
if(op==4){
scanf("%d%d%d",&l,&r,&k);
int temp=tr.getrank(l,r,k);
temp=(temp!=1) ? tr.kth(l,r,temp-1) : -2147483647;
printf("%d\n",temp);
}
if(op==5){
scanf("%d%d%d",&l,&r,&k);
int temp=tr.getrank(l,r,k)-1;
temp=(temp!=r-l+1) ? tr.kth(l,r,temp+1) : 2147483647;
printf("%d\n",temp);
}
}
}