输入k组匹配, n1为左部点集的数量,n2为右部点集的数量
a为左部点集,b为右部点集
const int MAXN = 5000;
int n1, n2;
vector<int> g[MAXN+10];
int mx[MAXN+10], my[MAXN+10];
queue<int> que;
int dx[MAXN+10], dy[MAXN+10];
bool vis[MAXN+10];
bool find ( int u ){
for ( int i = 0; i < g[u].size(); i ++ ){
if ( ! vis[g[u][i]] && dy[g[u][i]] == dx[u] + 1 ){
vis[g[u][i]] = true;
if ( ! my[g[u][i]] || find( my[g[u][i]] ) ){
mx[u] = g[u][i];
my[g[u][i]] = u;
return true;
}
}
}
return false;
}
int matching(){
memset ( mx, 0, sizeof ( mx ) );
memset ( my, 0, sizeof ( my ) );
int ans = 0;
while ( true ){
bool flag = 0;
while ( ! que.empty() ) que.pop();
memset ( dx, 0, sizeof ( dx ) );
memset ( dy, 0, sizeof ( dy ) );
for ( int i = 1; i <= n1; i ++ ){
if ( ! mx[i] ) que.push(i);
}
while ( ! que.empty() ){
int u = que.front();
que.pop();
for ( int i = 0; i < g[u].size(); i ++ ){
if ( ! dy[g[u][i]] ){
dy[g[u][i]] = dx[u] + 1;
if ( my[g[u][i]] ){
dx[my[g[u][i]]] = dy[g[u][i]] + 1;
que.push( my[g[u][i]] );
}else{
flag = true;
}
}
}
}
if ( ! flag )break;
memset ( vis, 0, sizeof ( vis ) );
for ( int i = 1; i <= n1; i ++ ){
if ( ! mx[i] && find(i) ) ans ++;
}
}
return ans;
}
int main()
{
ios::sync_with_stdio( false );
int k;
while ( cin >> k && k ){
for ( int i = 0; i < MAXN; i ++ ) g[i].clear();
cin >> n1 >> n2;
int a, b;
for ( int i = 0; i < k; i ++ ){
cin >> a >> b;
g[a].push_back ( b );
}
cout << matching() <<endl;
}
return 0;
}