#include<bits/stdc++.h>
#include<cmath>
#define ll long long
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Rof(i,a,b) for(int i=a;i>=b;i--)
#define N 2000010
#define pb push_back
#define ls x<<1
#define rs x<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define SP fixed<<setprecision(12)
#define mk make_pair
#define pque priority_queue
#undef ls
#undef rs
#undef lson
#undef rson
using namespace std;
int sum[N<<5],mx[N<<5],mw[N<<5],ls[N<<5],rs[N<<5],cnt=0;
int rt[N];
int n,q;
int val[N],to[N],len[N],head[N],tail[N],tot=0;
int p;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void upd(int x){
sum[x]=sum[ls[x]]+sum[rs[x]];
if(mx[ls[x]]>=mx[rs[x]]){
mx[x]=mx[ls[x]];
mw[x]=mw[ls[x]];
}else{
mx[x]=mx[rs[x]];
mw[x]=mw[rs[x]];
}
}
int add(int x,int l,int r,int u,int v){
if(!x) x=++cnt;
if(l==r){
sum[x]+=v;
mx[x]+=v;
mw[x]=u;
return x;
}
int mid=(l+r)>>1;
if(u<=mid) ls[x]=add(ls[x],l,mid,u,v);
else rs[x]=add(rs[x],mid+1,r,u,v);
upd(x);
return x;
}
int merge(int a,int b,int l,int r){
if(!a) return b;
if(!b) return a;
if(l==r){
sum[a]+=sum[b];
mx[a]+=mx[b];
mw[a]=l;
return a;
}
int mid=(l+r)>>1;
ls[a]=merge(ls[a],ls[b],l,mid);
rs[a]=merge(rs[a],rs[b],mid+1,r);
upd(a);
return a;
}
int main()
{
//freopen("bubble.in","r",stdin);
//freopen("bubble.out","w",stdout);
n=read(),q=read();
p=n+q+1;
For(i,1,n){
len[i]=read();
For(j,1,len[i]){
int x=read();
++tot;
val[tot]=x;
if(j==1) head[i]=tail[i]=tot;
else{
to[tot]=tail[i];
tail[i]=tot;
}
rt[i]=add(rt[i],1,n+q,x,1);
}
}
For(E,1,q){
int op=read();
if(op==1){
int x=read(),y=read();
len[x]++;
++tot;
val[tot]=y;
if(len[x]==1) head[x]=tail[x]=tot;
else{
to[tot]=tail[x];
tail[x]=tot;
}
rt[x]=add(rt[x],1,n+q,y,1);
}else if(op==2){
int x=read();
len[x]--;
int y=val[tail[x]];
//cout<<y<<endl;
if(!len[x]) head[x]=tail[x]=0;
else tail[x]=to[tail[x]];
rt[x]=add(rt[x],1,n+q,y,-1);
}else if(op==3){
int m=read();
For(i,1,m){
int x=read();
rt[p]=merge(rt[p],rt[x],1,n+q);
}
//cout<<mx[rt[p]]<<' '<<sum[rt[p]]<<' '<<mw[rt[p]]<<endl;
if(mx[rt[p]]*2>sum[rt[p]]) printf("%lld\n",mw[rt[p]]);
else printf("-1\n");
p++;
}else{
int x1=read(),x2=read(),x3=read();
if(!len[x1] && !len[x2]) continue;
else if(!len[x1]){
head[x3]=head[x2];
tail[x3]=tail[x2];
len[x3]=len[x2];
head[x2]=tail[x2]=len[x2]=0;
rt[x3]=merge(rt[x3],rt[x2],1,n+q);
}else if(!len[x2]){
head[x3]=head[x1];
tail[x3]=tail[x1];
len[x3]=len[x1];
head[x1]=tail[x1]=len[x1]=0;
rt[x3]=merge(rt[x3],rt[x1],1,n+q);
}else{
to[head[x2]]=tail[x1];
head[x3]=head[x1];
tail[x3]=tail[x2];
len[x3]=len[x1]+len[x2];
head[x1]=head[x2]=tail[x1]=tail[x2]=len[x1]=len[x2]=0;
rt[x3]=merge(rt[x3],rt[x1],1,n+q);
rt[x3]=merge(rt[x3],rt[x2],1,n+q);
}
}
/*
For(i,1,n+q){
cout<<len[i]<<endl;
int now=tail[i];
while(now) cout<<val[now]<<' ',now=to[now];
cout<<endl;
}
*/
}
return 0;
}
/*
gcx12012
start coding 2022/6/14 9:40
end coding 2022/6/14 10:39
end debuging
*/
rt