#include<bits/stdc++.h>
using namespace std;
struct sequence{
private:
struct node{int s,c,v,p,l,r;}tr[signed(3e5)<<7];
int root[1000001],cnt;mt19937 rng;
int newnode(register int v){
tr[++cnt].v=v;tr[cnt].s=1;
tr[cnt].p=rng();tr[cnt].l=tr[cnt].r=0;
tr[cnt].c=v;
return cnt;
}int clone(register int p){tr[++cnt]=tr[p];return cnt;}
void update(register int p){
tr[p].s=tr[tr[p].l].s+tr[tr[p].r].s+1;
tr[p].c=tr[tr[p].l].c+tr[tr[p].r].c+tr[p].v;
}inline void split(register int p,register int k,register int&l,register int&r){
if(!p)return void(l=r=0);
if(tr[tr[p].l].s+1<=k)l=clone(p),split(tr[l].r,k-tr[tr[p].l].s-1,tr[l].r,r),update(l);
else r=clone(p),split(tr[r].l,k,l,tr[r].l),update(r);
}inline int merge(register int l,register int r){
if(!l||!r)return l?l:r;
if(tr[l].p<tr[r].p)return tr[l].r=merge(tr[l].r,r),update(l),l;
return tr[r].l=merge(l,tr[r].l),update(r),r;
}void _print(register int p){
if(!p)return;
_print(tr[p].l);
cout<<tr[p].v<<' ';
_print(tr[p].r);
}
public:
sequence():cnt(0),rng((int)time(0)){}
void push_back(register int v,register int newver=0,register int ver=0){
root[newver]=merge(root[ver],newnode(v));
}int&at(register int p,register int newver=0,register int ver=0){
root[newver]=clone(root[ver]);
register int l,r,k,t;split(root[newver],p,l,r);
split(l,p-1,l,k);t=k;
root[newver]=merge(l,merge(t,r));
return tr[k].v;
}void print(register int newver=0,register int ver=0){root[newver]=clone(root[ver]);_print(root[newver]);}
}t;int n,m,v,opt,p,x;
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(register int i=1;i<=n;i++)cin>>x,t.push_back(x);
for(register int i=1;i<=m;i++){
cin>>v>>opt>>p;
if(opt==1)cin>>x,t.at(p,i,v)=x;
else if(opt==2)cout<<t.at(p,i,v)<<'\n';
else t.print(i,v);
}
}