#include <bits/stdc++.h>
using namespace std;
struct Dinic {
struct Edge {
int to, flow, next;
};
vector <Edge> edges;
vector <int> head, act, h;
int S, D;
void AddEdge(int from, int to, int f) {
edges.push_back({ to, f, (int)edges.size() });
swap(edges.back().next, head[from]);
edges.push_back({ from, 0, (int)edges.size() });
swap(edges.back().next, head[to]);
}
bool bfs() {
fill(h.begin(), h.end(), -1);
h[S] = 0;
vector <int> q = { S };
for (int it = 0; it < q.size() && h[D] == -1; it++) {
int nod = q[it];
for (int i = head[nod]; i != -1; i = edges[i].next)
if (edges[i].flow && h[edges[i].to] == -1)
h[edges[i].to] = 1 + h[nod], q.push_back(edges[i].to);
}
return h[D] != -1;
}
int dfs(int nod, int flow) {
if (flow == 0 || nod == D)
return flow;
while (act[nod] != -1) {
Edge& e = edges[act[nod]];
int d;
if (e.flow && h[e.to] == 1 + h[nod] && (d = dfs(e.to, min(flow, e.flow))) != 0) {
e.flow -= d;
edges[act[nod] ^ 1].flow += d;
return d;
}
act[nod] = edges[act[nod]].next;
}
return 0;
}
int GetFlow() {
int f = 0;
while (bfs()) {
act = head;
int d;
while ((d = dfs(S, 1e9)) != 0)
f += d;
}
return f;
}
Dinic(int dim = 0, int s = 0, int d = 0) : head(dim + 1, -1), h(dim + 1), S(s), D(d) { }
} flow;
int main()
{
FILE* in = fopen("cuplaj.in", "r");
FILE* out = fopen("cuplaj.out", "w");
int n, m, e;
fscanf(in, "%d%d%d", &n, &m, &e);
flow = Dinic(n + m + 1, 0, n + m + 1);
for (int i = 1; i <= n; i++)
flow.AddEdge(0, i, 1);
for (int i = 1; i <= m; i++)
flow.AddEdge(n + i, n + m + 1, 1);
while (e--) {
int a, b;
fscanf(in, "%d%d", &a, &b);
b += n;
flow.AddEdge(a, b, 1);
}
int ans = flow.GetFlow();
fprintf(out, "%d\n", ans);
for (int nod = 1; nod <= n; nod++)
for (int i = flow.head[nod]; i != -1; i = flow.edges[i].next)
if (flow.edges[i].to > n && flow.edges[i].flow == 0)
fprintf(out, "%d %d\n", nod, flow.edges[i].to - n);
return 0;
}