#include<bits/stdc++.h>
using namespace std;

struct node{
	node *succ[2];
	bool flag;
	int id[2],head;
	int val[2];
} vett[1000005];
node* cont=vett;

node* getnode(int x){
	node *tmp=cont;
	tmp->flag=false;
	tmp->id[0]=tmp->id[1]=-1;
	tmp->head=x;
	tmp->val[0]=tmp->val[1]=0;
	tmp->succ[0]=tmp->succ[1]=NULL;
	cont++;
	return tmp;
}

int n1,n2,m,contm,pot[400005],ans,q,deg[400005],red[400005],mod=998244353;
bool col[400005];
node* v[400005];
vector<int> archi[400005];

void clean(int i){
	bool curr=false;
	int dir;
	if(v[i]->succ[0]==NULL)dir=1;
	else dir=0;
	
	//cout<<"vado da "<<i<<" a "<<v[i]->head<<"\n";
	
	curr^=v[i]->flag;
	v[i]->flag=false;
	node *pos=v[i];
	int last=-1,tmpsum=0,tmp2sum=0;
	
	while(true){
		
		if(pos->id[dir]==last){
			dir^=1;	
		}
		
		if(pos->id[dir]==-1)break;
		if(curr){
			col[pos->id[dir]]^=true;
		}
		
		if(col[pos->id[dir]]){
			tmpsum+=pot[pos->id[dir]];
			tmpsum%=mod;
		}
		else{
			tmp2sum+=pot[pos->id[dir]];
			tmp2sum%=mod;
		}
		//cout<<"percorro "<<pos->id[dir]<<"\n";
		last=pos->id[dir];
		pos=pos->succ[dir];
		curr^=pos->flag;
		pos->flag=false;
	}
	
	v[i]->val[0]=v[v[i]->head]->val[0]=tmpsum;
	v[i]->val[1]=v[v[i]->head]->val[1]=tmp2sum;
}

void unite(int x,int y,bool mode){
	
	//cout<<"unisco "<<x<<" "<<y<<" con colore "<<mode<<" (arco "<<contm<<")"" aa\n";
	
	if(mode==true){
		red[x]++;
		red[y]++;
		ans+=pot[contm];
		ans%=mod;
	}
	col[contm]=mode;
	
	int a=v[x]->head,b=v[y]->head;
	
	if(x==b){
		clean(x);
		v[x]=v[y]=NULL;
		return;
	}
	
	if(v[x]->succ[0]==NULL)v[x]->succ[0]=v[y],v[x]->id[0]=contm;
	else v[x]->succ[1]=v[y],v[x]->id[1]=contm;
	
	if(v[y]->succ[0]==NULL)v[y]->succ[0]=v[x],v[y]->id[0]=contm;
	else v[y]->succ[1]=v[x],v[y]->id[1]=contm;
	
	v[a]->head=b;
	v[b]->head=a;
	
	int tmp=(v[a]->val[0]+v[b]->val[0])%mod;
	if(mode)tmp=(tmp+pot[contm])%mod;
	
	v[a]->val[0]=v[b]->val[0]=tmp;
	
	tmp=(v[a]->val[1]+v[b]->val[1])%mod;
	if(!mode)tmp=(tmp+pot[contm])%mod;
	
	v[a]->val[1]=v[b]->val[1]=tmp;
	
	
	if(x!=a)v[x]=NULL;
	if(y!=b)v[y]=NULL;
}

void reverse(int x){
	
	int y=v[x]->head;
	v[x]->flag^=1;
	v[y]->flag^=1;
	
	//cout<<"reversa da "<<x<<" a "<<y<<"\n";
	
	ans+=(v[x]->val[1]-v[x]->val[0])%mod;
	ans%=mod;
	swap(v[x]->val[1],v[x]->val[0]);
	swap(v[y]->val[1],v[y]->val[0]);
	
	if(red[x]>deg[x]/2)red[x]--;
	else red[x]++;
	
	if(red[y]>deg[y]/2)red[y]--;
	else red[y]++;
}

void add(int x,int y){
	y+=n1;
	contm++;
	
	archi[x].push_back(contm);
	archi[y].push_back(contm);
	
	if(deg[x]%2==0 && deg[y]%2==0){
		v[x]=getnode(x);
		v[y]=getnode(y);
		
		unite(x,y,true);
	}else if(deg[x]%2==1 && deg[y]%2==1){
		
		if(red[x]>deg[x]/2 == red[y]>deg[y]/2){
			unite(x,y,!(red[x]>deg[x]/2));
		}else{
			assert(v[x]->head != y);
			reverse(x);
			unite(x,y,!(red[x]>deg[x]/2));
		}
		
	}else{
		if(deg[y]%2==1)swap(x,y);
		v[y]=getnode(y);
		
		unite(x,y,!(red[x]>deg[x]/2));
	}
	
	deg[x]++;
	deg[y]++;
	
	//assert(abs(red[x]-(deg[x]-red[x]))<=1);
	//assert(abs(red[y]-(deg[y]-red[y]))<=1);
}

void calc(){
	for(int i=1;i<=n1+n2;i++){
		if(v[i]==NULL)continue;
		clean(i);
	}
	
	vector<int> sol;
	int tmpsum=0;
	for(int i=1;i<=contm;i++)if(col[i]){
		sol.push_back(i);
		tmpsum+=pot[i];
		tmpsum%=mod;
	}
	
	for(int i=1;i<=n1+n2;i++){
		int tm=0;
		for(auto j : archi[i]){
			if(col[j])tm++;
		}
		
		assert(abs(tm)==red[i]);
	}
	
	//assert(tmpsum==ans);
	cout<<sol.size()<<" ";
	for(auto i : sol)cout<<i<<" ";
	cout<<endl;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	pot[0]=1;
	for(int i=1;i<400005;i++)pot[i]=(pot[i-1]*2ll)%mod;
	
	cin>>n1>>n2>>m;
	
	for(int i=0;i<m;i++){
		int x,y;
		cin>>x>>y;
		
		add(x,y);
	}
	//cout<<ans<<"eccco \n";
	cin>>q;
	
	for(int i=0;i<q;i++){
		int t;
		cin>>t;
		if(t==1){
			int v1,v2;
			cin>>v1>>v2;
			add(v1,v2);
			cout<<(ans+mod)%mod<<endl;
		}else{
			calc();
		}
	}

	return 0;
}

