#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int inf=1<<30;
int n[5],m[3],s,t,head[41010],cnt=0;
struct node
{
int to,nex,val;
}a[1000010];
void add(int u,int v,int c)
{
a[++cnt].nex=head[u];
a[cnt].to=v;
a[cnt].val=c;
head[u]=cnt;
}
int dep[41000],gap[41000];
void bfs()
{
memset(dep,-1,sizeof(dep));
memset(gap,0,sizeof(gap));
dep[t]=0;
gap[0]=1;
queue<int>q;
q.push(t);
while(!q.empty())
{
int u=q.front();
q.pop();
for(register int i=head[u];i;i=a[i].nex)
{
int v=a[i].to;
if(dep[v]!=-1)continue;
q.push(v);
dep[v]=dep[u]+1;
gap[dep[v]]++;
}
}
return;
}
int maxflow;
int dfs(int u,int flow)
{
if(u==t)
{
maxflow+=flow;
cout<<flow<<endl;
return flow;
}
int used=0;
for(register int i=head[u];i;i=a[i].nex)
{
int d=a[i].to;
if(a[i].val>0 && dep[d]+1==dep[u])
{
int mi=dfs(d,min(a[i].val,flow-used));
if(mi)
{
a[i].val-=mi;
if(i&1)a[i-1].val+=mi;
else a[i+1].val+=mi;
used+=mi;
}
if(used==flow)return used;
}
}
--gap[dep[u]];
if(gap[dep[u]]==0)dep[s]=n[0]+1;
dep[u]++;
gap[dep[u]]++;
return used;
}
int ISAP()
{
maxflow=0;
bfs();
while(dep[s]<n[0])dfs(s,inf);//若最大深度未大于n则继续
return maxflow;//返回最大流
}
int main()
{
int u,v;
scanf("%d%d%d",&n[2],&n[1],&n[3]);
n[4]=n[2];
n[0]=n[1]+2*n[2]+n[3]+2;t=n[0]-1;s=n[0];
for(register int i=1;i<=n[1];i++)
{
// cout<<endl;
// cout<<"s="<<s<<' '<<"i="<<i<<endl;
add(s,i,1);
add(i,s,0);
}
int uu,vv;
scanf("%d",&m[1]);
for(register int i=1;i<=m[1];i++)
{
scanf("%d%d",&v,&u);
vv=v+n[1];
// cout<<endl;
// cout<<"vv="<<vv<<' '<<"u="<<u<<endl;
add(u,vv,1);
add(vv,u,0);
}
//importance
for(register int i=1;i<=n[2];i++)
{
uu=i+n[1],vv=i+n[1]+n[2];
// cout<<endl;
// cout<<"vv="<<vv<<' '<<"uu="<<uu<<endl;
add(uu,vv,1);
add(vv,uu,0);
}
scanf("%d",&m[2]);
for(register int i=1;i<=m[2];i++)
{
scanf("%d%d",&u,&v);
uu=u+n[1]+n[2];vv=v+n[1]+n[2]*2;
// cout<<endl;
// cout<<"uu="<<uu<<' '<<"vv="<<vv<<endl;
add(uu,vv,1);
add(vv,uu,0);
}
for(register int i=n[1]+2*n[2]+1;i<t;i++)
{
add(i,t,1);
add(t,i,0);
}
printf("%d\n",ISAP());
return 0;
}