const int MAXN=2e5+5,MAXK=7e5+5;
vector<pair<int,int> >a[MAXN<<2];
int lef[MAXN<<2],rig[MAXN<<2];
void build(int k,int L,int R){
lef[k]=L,rig[k]=R;
if(L==R)return;
int M=L+R>>1;
build(k<<1,L,M);build(k<<1|1,M+1,R);
}
void add(int k,int L,int R,pair<int,int> edge){
if(L<=lef[k]&&rig[k]<=R)
return a[k].push_back(edge),void();
int mid=lef[k]+rig[k]>>1;
if(mid>=L)add(k<<1,L,R,edge);
if(mid<R)add(k<<1|1,L,R,edge);
}
int m,fa[MAXN<<1],sz[MAXN<<1],top,Stack[MAXK],block_cnt,Iosn,Iosm;
int Find(int x){return x==fa[x]?x:Find(fa[x]);}
void Union(int u,int v){
int x=Find(u),y=Find(v);
if(x==y)return;
block_cnt--;
if(sz[x]==1){
if(x>m)Iosn--;
else Iosm--;
}
if(sz[y]==1){
if(y>m)Iosn--;
else Iosm--;
}
if(sz[x]>sz[y])swap(x,y);
Stack[++top]=x;
fa[x]=y,sz[y]+=sz[x];
}
void Inv_union(int x,int y){
block_cnt++;
sz[y]-=sz[x];
fa[x]=x;
if(sz[x]==1){
if(x>m)Iosn++;
else Iosm++;
}
if(sz[y]==1){
if(y>m)Iosn++;
else Iosm++;
}
top--;
}
void solve(int k){
int cur=top;
_for(i,0,a[k].size()){
pair<int,int> temp=a[k][i];
Union(temp.first,temp.second);
}
if(lef[k]==rig[k]){
if(Iosm)
puts("-1");
else
enter(block_cnt-Iosn);
}
else
solve(k<<1),solve(k<<1|1);
while(top>cur)Inv_union(Stack[top],fa[Stack[top]]);
}
map<pair<int,int>,int> st;
int main()
{
int n=read_int(),m=read_int(),q=read_int(),u,v;
pair<int,int> temp;
::m=m;
_rep(i,1,n+m)fa[i]=i,sz[i]=1;
block_cnt=n+m,Iosn=n,Iosm=m;
build(1,1,q);
_rep(i,1,n){
int k=read_int();
while(k--)
st[make_pair(read_int(),i+m)]=1;
}
_rep(i,1,q){
u=read_int(),v=read_int()+m;
temp=make_pair(u,v);
if(st.count(temp)){
int l=st[temp];
if(l!=i)add(1,l,i-1,temp);
st.erase(temp);
}
else
st[temp]=i;
}
for(auto it=st.begin();it!=st.end();++it)
add(1,it->second,q,it->first);
solve(1);
return 0;
}