structMaxMatch { int n, m, dis; vector<vector<int>> E; vector<int> nx, ny, dx, dy, vis;
MaxMatch(int n, int m) : n(n), m(m), dis(0), E(n), nx(n, -1), ny(m, -1), dx(n), dy(m), vis(m) {}
voidadd(int u, int v){ E[u].push_back(v); }
boolbfs(){ dis = inf; fill(dx.begin(), dx.end(), -1); fill(dy.begin(), dy.end(), -1); queue<int> Q; for (int i = 0; i < n; ++i) { if (nx[i] == -1) Q.push(i), dx[i] = 0; } while (!Q.empty()) { int u = Q.front(); Q.pop(); if (dx[u] > dis) break; for (auto v : E[u]) { if (dy[v] == -1) { dy[v] = dx[u] + 1; if (ny[v] == -1) dis = dy[v]; else dx[ny[v]] = dy[v] + 1, Q.push(ny[v]); } } } return dis != inf; }
booldfs(int u){ for (auto v : E[u]) { if (!vis[v] && dy[v] == dx[u] + 1) { vis[v] = true; if (ny[v] != -1 && dy[v] == dis) continue; if (ny[v] == -1 || dfs(ny[v])) { ny[v] = u; nx[u] = v; returntrue; } } } returnfalse; }
intwork(){ int res = 0; while (bfs()) { fill(vis.begin(), vis.end(), false); for (int i = 0; i < n; ++i) { if (nx[i] == -1 && dfs(i)) ++res; } } return res; } };
intmain(){ int n, m, e; cin >> n >> m >> e; MaxMatch G(n, m); while (e--) { int u, v; cin >> u >> v; u--, v--; G.add(u, v); } cout << G.work() << "\n"; return0; }