#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
;
}