WA on #13,16,19,20
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+100,M=4e7+100;
int n,q,h[N*2],tail[N*2],rt[N*2];
struct data{int ne,la,val;}s[N*2]; int cnt;
struct tree{int ls,rs,mx_num,num,pos;}t[M]; int num;
void push_up(int p){
int ls=t[p].ls,rs=t[p].rs;
if(t[ls].mx_num>=t[rs].mx_num) t[p].mx_num=t[ls].mx_num,t[p].pos=t[ls].pos;
else t[p].mx_num=t[rs].mx_num,t[p].pos=t[rs].pos;
t[p].num=t[ls].num+t[rs].num;
return;
}
void update(int &p,int l,int r,int pos,int add){
if(!p) p=++num;
if(l==r){
t[p].num+=add;
t[p].mx_num+=add;
t[p].pos=pos;
return;
}
int mid=(l+r)>>1;
if(pos<=mid) update(t[p].ls,l,mid,pos,add);
else if(pos>mid) update(t[p].rs,mid+1,r,pos,add);
push_up(p);
return;
}
int query(int p,int l,int r,int pos){
if(l==r) return t[p].mx_num;
int mid=(l+r)>>1;
if(pos<=mid) return query(t[p].ls,l,mid,pos);
else return query(t[p].rs,mid+1,r,pos);
}
int merge(int p,int q,int l,int r){
if(!p or !q) return p+q;
if(l==r){
t[p].num+=t[q].num;
t[p].mx_num+=t[q].mx_num;
return p;
}
int mid=(l+r)>>1;
t[p].ls=merge(t[p].ls,t[q].ls,l,mid);
t[p].rs=merge(t[p].rs,t[q].rs,mid+1,r);
push_up(p);
return p;
}
int bx[N];
signed main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
int l; scanf("%lld",&l);
for(int k=1;k<=l;k++){
int x;
scanf("%lld",&x);
update(rt[i],0,1e6,x,1);
s[++cnt].val=x;
if(k==1){
h[i]=cnt;
s[cnt].la=0;
}
else{
s[cnt].la=cnt-1;
s[cnt-1].ne=cnt;
}
tail[i]=cnt;
}
}
while(q--){
int opt; scanf("%lld",&opt);
if(opt==1){
int x,y; scanf("%lld%lld",&x,&y);
update(rt[x],0,1e6,y,1);
s[++cnt].val=y;
if(!h[x]){
h[x]=cnt;
s[cnt].la=0;
}
else{
s[cnt].la=tail[x];
s[tail[x]].ne=0;
}
tail[x]=cnt;
}
else if(opt==2){
int x; scanf("%lld",&x);
update(rt[x],0,1e6,s[tail[x]].val,-1);
tail[x]=s[tail[x]].la;
s[tail[x]].ne=0;
if(tail[x]==0) h[x]=0;
}
else if(opt==3){
int m; scanf("%lld",&m);
int v=0,ti=0,all=0;
for(int i=1;i<=m;i++){
scanf("%d",&bx[i]);
int x=bx[i];
all+=t[rt[x]].num;
if(t[rt[x]].mx_num*2<=t[rt[x]].num) continue;
int res=t[rt[x]].mx_num-(t[rt[x]].num-t[rt[x]].mx_num);
if(t[rt[x]].pos==v) ti+=res;
else{
if(res==ti) v=ti=0;
else if(res>ti) ti=res-ti,v=t[rt[x]].pos;
else if(res<ti) ti-=res;
}
}
if(!v){
puts("-1");
continue;
}
int ball=0;
for(int i=1;i<=m;i++) ball+=query(rt[bx[i]],0,1e6,v);
if(ball*2>all) cout<<v<<endl;
else puts("-1");
}
else{
int x1,x2,x3;
scanf("%lld%lld%lld",&x1,&x2,&x3);
h[x3]=h[x1],tail[x3]=tail[x2];
s[tail[x1]].ne=h[x2],s[h[x2]].la=tail[x1];
rt[x3]=merge(rt[x1],rt[x2],0,1e6);
rt[x1]=rt[x2]=0;
}
}
return 0;
}