#include<cstdio>
using namespace std;
typedef long long ll;
inline ll read(){
ll f=1,x=0;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return f*x;
}
inline void write(ll x){
if(x<0)x=-x,putchar('-');
if(x>9)write(x/10);
putchar(x%10+'0');
}
inline void swap(int &a,int &b){
int tmp=a;
a=b;
b=tmp;
return;
}
const int N=2e5+10;
const int N_TREE=N*10;
int n,m,opt,x,y,z;
int set_index;
int ls[N_TREE],rs[N_TREE]/,root[N],tot,cnt,trash[N_TREE];
ll tree_num[N_TREE];
inline int new_point(){
if(cnt==0){
tot++;
return tot;
}
cnt--;
return trash[cnt+1];
}
inline void del(int p){
cnt++;
trash[cnt]=p;
ls[p]=rs[p]=0;
tree_num[p]=0;
return;
}
inline void update(int &p,int l,int r,int pos,int v){
if(p==0)
p=new_point();
tree_num[p]+=v;
if(l==r)
return;
int mid=(l+r)>>1;
if(pos<=mid)
update(ls[p],l,mid,pos,v);
else
update(rs[p],mid+1,r,pos,v);
return;
}
inline int merge(int x,int y){
if(x==0||y==0)
return x+y;
tree_num[x]+=tree_num[y];
ls[x]=merge(ls[x],ls[y]);
rs[x]=merge(rs[x],rs[y]);
del(y);
return x;
}
inline void split(int x,int &y,ll k){
if(x==0)
return;
y=new_point();
ll v=tree_num[ls[x]];
if(k>v)
split(rs[x],rs[y],k-v);
else
swap(rs[x],rs[y]);
if(k<v)
split(ls[x],ls[y],k);
tree_num[y]=tree_num[x]-k;
tree_num[x]=k;
return;
}
inline ll query_num(int p,int l,int r,int x,int y){
if(r<x||y<l)
return 0;
if(x<=l&&r<=y)
return tree_num[p];
int mid=(l+r)>>1;
return query_num(ls[p],l,mid,x,y)+query_num(rs[p],mid+1,r,x,y);
}
inline int query_kth(int p,int l,int r,int k){
if(l==r)
return l;
int mid=(l+r)>>1;
if(k<=tree_num[ls[p]])
return query_kth(ls[p],l,mid,k);
else
return query_kth(rs[p],mid+1,r,k-tree_num[ls[p]]);
}
int main(){
n=read();
m=read();
for(int i=1,x;i<=n;i++){
x=read();
update(root[1],1,n,i,x);
}
while(m--){
opt=read();
if(opt==0){
x=read();
y=read();
z=read();
ll k1=query_num(root[x],1,n,1,z);
ll k2=query_num(root[x],1,n,y,z);
int tmp=0;
split(root[x],root[++set_index],k1-k2);
split(root[set_index],tmp,k2);
root[x]=merge(root[x],tmp);
}
else if(opt==1){
x=read();
y=read();
root[x]=merge(root[x],root[y]);
}
else if(opt==2){
x=read();
y=read();
z=read();
update(root[x],1,n,z,y);
}
else if(opt==3){
x=read();
y=read();
z=read();
write(query_num(root[x],1,n,y,z));
putchar('\n');
}
else if(opt==4){
x=read();
y=read();
if(tree_num[root[x]]<y){
write(-1);
putchar('\n');
continue;
}
write(query_kth(root[x],1,n,y));
putchar('\n');
}
}
return 0;
}