#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510, M = 100010;
int h[N], e[M], ne[M], idx; //邻接表存储
int match[N]; //match[j]=a,表示女孩j的现有配对男友是a
bool st[N]; //st[]数组我称为临时预定数组,st[j]=a表示一轮模拟匹配中,女孩j被男孩a预定了。
int n1, n2, m;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
bool find(int x) //这个函数的作用是用来判断,如果加入x来参与模拟配对,会不会使匹配数增多
{
for ( int i = h[x]; i != -1; i = ne[i] ) //遍历自己喜欢的女孩
{
int j = e[i];
if ( !st[j] ) //如果在这一轮模拟匹配中,这个女孩尚未被预定
{
st[j] = true; //那x就预定这个女孩了
//如果女孩j没有男朋友,或者她原来的男朋友能够预定其它喜欢的女孩。配对成功,更新match
if ( match[j] == 0 || find(match[j]) )
{
match[j] = x;
return true;
}
}
}
return false; //自己中意的全部都被预定了。配对失败。
}
int main()
{
memset(h, -1, sizeof h);
scanf("%d%d%d", &n1, &n2, &m);
while ( m -- )
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b); //存边只存一边就行了,虽然是无向图。
}
int res = 0;
for ( int i = 1; i <= n1; i ++ )
{
memset(st, false, sizeof st); //因为每次模拟匹配的预定情况都是不一样的所以每轮模拟都要初始化
if ( find(i) ) res ++;
}
printf("%d\n", res);
return 0;
}