#include<bits/stdc++.h>
#define forUp(i,a,b) for(int i=(a);i<=(b);++i)
#define forUP(i,a,b) for(int i=(a);i<(b);++i)
#define forDown(i,a,b) for(int i=(a);i>=(b);--i)
#define forG(u,v) for(int __i=head[u],v=to[__i];__i;__i=nxt[__i],v=to[__i])
#define forWG(u,v,c) for(int __i=head[u],v=to[__i],c=w[__i];__i;__i=nxt[__i],v=to[__i],c=w[__i])
#define pushb push_back
#define popb pop_back
#define pushf push_front
#define popf pop_front
#define popc __builtin_popcount
#define popc64 __builtin_popcountll
#define seteps(n) fixed<<setprecision(n)
bool __mst;using uint=unsigned int;using int64=long long;using uint64=unsigned long long;using int128=__int128;using uint128=unsigned __int128;using float64=double;using float80=long double;
constexpr int INF=0x3f3f3f3f,MINF=0xcfcfcfcf;constexpr int64 INF64=0x3f3f3f3f3f3f3f3f,MINF64=0xcfcfcfcfcfcfcfcf;constexpr float64 INFDB=1e50,eps=1e-6;
template<class _Tp>inline void chkMax(_Tp &x,const _Tp &y){if(x<y)x=y;}template<class _Tp>inline void chkMin(_Tp &x,const _Tp &y){if(x>y)x=y;}
inline int addMod(const int &x,const int &y,const int mod){int ans=x+y;return ans>=mod?ans-mod:ans;}inline int subMod(const int &x,const int &y,const int mod){int ans=x-y;return ans<0?ans+mod:ans;}
constexpr int N=1e5+10,B=1000;int __test_num=1,__task_id,__tst;using namespace std;void __init();
int n,q,A[N];array<int,2> lsh[N];
int ecnt,head[N],to[N],nxt[N];
void addEdge(int u,int v){++ecnt,to[ecnt]=v,nxt[ecnt]=head[u],head[u]=ecnt;}
int fa[N],sz[N];
void init(){forUp(i,1,n)sz[fa[i]=i]=1;}
int find(int x){return x==fa[x]?x:find(fa[x]);}
int op[N],x[N],y[N],ans[N];
void dfs(int rt){
if(op[rt]==1){
x[rt]=find(x[rt]),y[rt]=find(y[rt]);
if(x[rt]!=y[rt]){
if(sz[x[rt]]<sz[y[rt]])swap(x[rt],y[rt]);
sz[x[rt]]+=sz[y[rt]],fa[y[rt]]=x[rt];
}
}
else if(op[rt]==3)x[rt]=find(x[rt]),ans[rt]=-1;
forG(rt,son)dfs(son);
if(op[rt]==1&&x[rt]!=y[rt])fa[y[rt]]=y[rt],sz[x[rt]]-=sz[y[rt]];
}
int L,R;
void solve(int rt){
if(op[rt]==1){if(x[rt]!=y[rt])sz[x[rt]]+=sz[y[rt]],fa[y[rt]]=x[rt];}
else if(op[rt]==3){
if(sz[x[rt]]<y[rt])y[rt]-=sz[x[rt]];
else if(ans[rt]==-1){
int cnt=0;
forUp(i,L,R)if(find(lsh[i][1])==x[rt]){
++cnt;
if(cnt==y[rt]){
ans[rt]=lsh[i][0];
break;
}
}
}
}
forG(rt,son)solve(son);
if(op[rt]==1&&x[rt]!=y[rt])fa[y[rt]]=y[rt],sz[x[rt]]-=sz[y[rt]];
}
bool __med;void __solve(int __test_id){
cin>>n>>q;
forUp(i,1,n)cin>>A[i],lsh[i]={A[i],i};sort(lsh+1,lsh+n+1);
forUp(i,1,q){
cin>>op[i]>>x[i];if(op[i]!=2)cin>>y[i];
if(op[i]==2)addEdge(x[i],i);
else addEdge(i-1,i);
}
init();dfs(0);forUp(i,1,n)sz[i]=0;
L=1-B;for(;R<n;){
L+=B,R+=B;if(R>n)R=n;
forUp(i,L,R)sz[lsh[i][1]]=1;
solve(0);
forUp(i,L,R)sz[lsh[i][1]]=0;
}
forUp(i,1,q)if(op[i]==3)cout<<ans[i]<<'\n';
}
signed main(){
__init();
forUp(i,1,__test_num)__solve(i);
cerr<<1000.0*(clock()-__tst)/CLOCKS_PER_SEC<<"ms "<<((&__mst)-(&__med))/1024.0/1024.0<<"MB"<<'\n';
return 0;
}
void __init(){
__tst=clock();
#ifndef use_file
//#define use_file
#endif
#ifdef use_file
const string __file_name="test";freopen((__file_name+".in").c_str(),"r",stdin);freopen((__file_name+".out").c_str(),"w",stdout);
#endif
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//scanf("%d",&__test_num);
//cin>>__test_num;
}