#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
void pre() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#define DEBUG(A) cout << A << endl
#else
#define DEBUG(A)
#endif
}
#define N 6000
struct edge {
int nxt;
int v;
int flow;
};
edge g[600100];
int tot;
int head[N];
inline void adde(int u, int v, int fl) {
g[tot] = { head[u], v, fl };
head[u] = tot++;
}
int dep[N];
bool bfs(int s, int t) {
memset(dep, 0, sizeof(dep));
queue<int> q;
q.push(s);
dep[s] = 1;
while (q.size()) {
int u = q.front();
q.pop();
for (int i = head[u]; i != -1; i = g[i].nxt) {
int v = g[i].v;
int fl = g[i].flow;
if ((fl != 0) && (dep[v] == 0)) {
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[t] != 0;
}
int dfs(int u, int in, int t) {
if (u == t) {
return in;
}
int out = 0;
for (int i = head[u]; i != -1 && in != 0; i = g[i].nxt) {
int v = g[i].v;
int& fl = g[i].flow;
if (fl != 0 && dep[v] == dep[u] + 1) {
int res = dfs(v, min(fl, in), t);
in -= res;
out += res;
fl -= res;
g[i ^ 1].flow += res;
}
}
if (out == 0) {
dep[u] = 0;
}
return out;
}
int dinic(int s, int t) {
int ret = 0;
while (bfs(s, t)) {
ret += dfs(s, 0x7f7f7f7f, t);
}
return ret;
}
int n1, m1, e1;
signed main() {
pre();
memset(head, -1, sizeof(head));
cin >> n1 >> m1 >> e1;
int n = n1 + m1 + 2;
for (int i = 1; i <= n1; i++) {
adde(1, i + 1, 1);
adde(i + 1, 1, 1);
}
for (int i = 1; i <= e1; i++) {
int u, v;
cin >> u >> v;
if (u > n1 || v > m1) {
continue;
}
if (u <= n1 && v <= m1) {
adde(u + 1, v + n1 + 1, 1);
adde(v + n1 + 1, u + 1, 1);
}
}
for (int i = 1; i <= m1; i++) {
adde(i + n1 + 1, n, 1);
adde(n, i + n1 + 1, 1);
}
DEBUG("ok");
cout << dinic(1, n);
return 0;
}