#include < cstdio >
#include < iostream >
#include < cstring >
#include < queue >
#include < vector >
#include < algorithm >
using namespace std ;
const int maxn = 1 e 6 + 7 ;
const int inf = 0x 3f3f3f3f ;
template < class T > inline void read(T & res )
{
char c ;T flag = 1 ;
while((c = getchar()) < ' 0 ' ||c > ' 9 ' )if(c == ' - ' )flag =- 1 ;res =c - ' 0 ' ;
while((c = getchar()) >= ' 0 ' &&c <= ' 9 ' )res =res * 10 +c - ' 0 ' ;res *=flag ;
}
struct edge { int from ,to ,cap ,flow ;};
struct isap
{
int n ,s ,t , p [maxn ], d [maxn ], cur [maxn ], num [maxn ];
bool vis [maxn ];
vector <int> g [maxn ];
vector <edge >edges ;
void init( int n , int s , int t ) {
this -> n = n ;
this -> s = s ;
this -> t = t ;
for( int i = 1 ;i <= n ;i ++ ) g [i ].clear();
edges .clear();
}
void addegde( int from , int to , int cap ) {
edges .push_back((edge ){from , to , cap , 0} );
edges .push_back((edge ){to , from , 0 , 0} );
int m = edges .size();
g [from ].push_back(m - 2 );
g [to ].push_back(m - 1 );
}
int augment() { ///找增广路
int x = t ,a = inf ;
while(x !=s ) {
a = min(a , edges [ p [x ]]. cap - edges [ p [x ]]. flow );
x = edges [ p [x ]]. from ;
}
x =t ;
while(x != s ) {
edges [ p [x ]]. flow += a ;
edges [ p [x ] ^ 1 ]. flow = -a ;
x = edges [ p [x ]]. from ;
}
return a ;
}
int maxflow() { ///更新最大流
int flow = 0 ;
memset(num , 0 , sizeof (num ));
memset(cur , 0 , sizeof (cur ));
for( int i = 1 ; i <= n ; i ++ ) num [ d [i ]] ++ ;
int x = s ;
while( d [s ] < n ) { ///最长的一条链上,最大的下标是nv-1,如果大于等于nv说明已断层
if(x == t ) {
flow += augment();
x = s ; //回退
}
bool ok = 0 ;
for( int i = cur [x ]; i < g [x ].size(); i ++ ) {
edge &e = edges [ g [x ][i ]];
if( d [x ] == d [ e . to ] + 1 && e . cap > e . flow ) {
p [ e . to ] = g [x ][i ];
cur [x ] = i ;x = e . to ;
ok = 1 ;
break;
}
}
if( !ok ) {
int m = n - 1 ;
for( int i = 0 ; i < g [x ].size();i ++ ) {
edge &e = edges [ g [x ][i ]];
if( e . cap > e . flow ) m = min(m , d [ e . to ]);
}
num [ d [x ]] -- ;
if( ! num [ d [x ]]) break;
d [x ] = m + 1 ;
num [ d [x ]] ++ ;
cur [x ] = 0 ;
if(x != s ) x = edges [ p [x ]]. from ;
}
}
return flow ;
}
}ISAP ;
int n , p , q ;
int s , t ;
int main()
{
read(n ), read(p ), read(q );
s = 2 *n +q +p + 1 ;
t = s + 1 ;
ISAP .init( 2 * n + p + q + 7 , s , t );
int m2 ;
read(m2 );
for ( int i = 1 ; i <= m2 ; ++i ) {
int u , v ;
read(u );
read(v );
ISAP .addegde(v , u + p , 1 );
}
read(m2 );
for ( int i = 1 ; i <= m2 ; ++i ) {
int u , v ;
read(u );read(v );
ISAP .addegde(n + p + u , v + p + 2 * n , 1 );
}
for ( int i = 1 ; i <= n ; ++i ) {
ISAP .addegde(p + i , n + p + i , 1 );
}
for ( int i = 1 ; i <= q ; ++i ) {
ISAP .addegde(s , i , 1 );
}
for ( int i = 1 ; i <= p ; ++i ) {
ISAP .addegde(n * 2 + p + i , t , 1 );
}
// while(bfs()) {
// Dinic();
// }
printf( " %d \n " , ISAP .maxflow());
return 0 ;
}