#include using namespace std; #define rep(i,a,b) for(int i=a;i=b;i--) #define fore(i,a) for(auto& i:a) #define ff first #define ss second #define all(a) begin(a),end(a) #define allr(a) rbegin(a),rend(a) #define pb push_back using ll =long long; using pii=pair; using pll=pair; using vi=vector; using vll=vector; template inline bool chmin(T& a,T b){return a>b?a=b,1:0;} template inline bool chmax(T& a,T b){return a::max()/2; const ll INFL=numeric_limits::max()/2; void solve(){ } template< typename T > struct BinaryIndexedTree { private: int n; vector< T > data; public: BinaryIndexedTree() = default; explicit BinaryIndexedTree(int n) : n(n) { data.assign(n + 1, T()); } explicit BinaryIndexedTree(const vector< T > &v) : BinaryIndexedTree((int) v.size()) { build(v); } void build(const vector< T > &v) { assert(n == (int) v.size()); for(int i = 1; i <= n; i++) data[i] = v[i - 1]; for(int i = 1; i <= n; i++) { int j = i + (i & -i); if(j <= n) data[j] += data[i]; } } void apply(int k, const T &x) { for(++k; k <= n; k += k & -k) data[k] += x; } T prod(int r) const { T ret = T(); for(; r > 0; r -= r & -r) ret += data[r]; return ret; } T prod(int l, int r) const { return prod(r) - prod(l); } int lower_bound(T x) const { int i = 0; for(int k = 1 << (__lg(n) + 1); k > 0; k >>= 1) { if(i + k <= n && data[i + k] < x) { x -= data[i + k]; i += k; } } return i; } int upper_bound(T x) const { int i = 0; for(int k = 1 << (__lg(n) + 1); k > 0; k >>= 1) { if(i + k <= n && data[i + k] <= x) { x -= data[i + k]; i += k; } } return i; } }; int main(){ cin.tie(0)->sync_with_stdio(0); int n;cin>>n;vi a(n); rep(i,0,n)cin>>a[i],a[i]--; int q;cin>>q; vector query; vi par(n+q,-1); rep(i,1,n){ par[a[i]]=a[i-1]; } queue qa,qb; rep(i,0,n)qa.push(a[i]); rep(i,0,q)qb.push(n+i); int back=a[n-1]; rep(i,0,q){ int t; cin>>t; if(t==1){ int a;cin>>a;a--; int b=qb.front();qb.pop(); query.pb({1,b}); if(a==-1){ par[b]=back; back=b; }else{ par[b]=par[a]; par[a]=b; } }else if(t==2){ query.pb({2,-1}); }else{ int k;cin>>k;query.pb({3,k}); } } map mp,inv; int cur=back; rrep(i,n+q-1,0){ mp[cur]=i; inv[i]=cur; cur=par[cur]; if(cur==-1)break; } BinaryIndexedTree seg(n+q); rep(i,0,n){ seg.apply(mp[a[i]],1); } rep(i,0,q){ int t=query[i].ff; if(t==1){ seg.apply(mp[query[i].ss],1); }else if(t==2){ seg.apply(seg.lower_bound(1),-1); }else{ cout<