#include <bits/stdc++.h>
using namespace std;
// Source: e-maxx.ru
// Tested with: VOJ - NKFLOW, VOJ - MCQUERY (Gomory Hu)
// Usage:
// MaxFlow flow(n)
// For each edge: flow.addEdge(u, v, c, edge_id)
// flow.getMaxFlow(s, t)
// flow.trace()
// Index from 0
// Tested:
// - https://open.kattis.com/problems/maxflow
const int INF = 2e9;
struct Edge {
int a, b, cap, flow, id;
};
struct MaxFlow {
int n, s, t;
vector<int> d, ptr, q;
vector< Edge > e;
vector< vector<int> > g;
MaxFlow(int n) : n(n), d(n), ptr(n), q(n), g(n) {}
void addEdge(int a, int b, int cap, int id) {
Edge e1 = { a, b, cap, 0, id };
Edge e2 = { b, a, 0, 0, -1 };
g[a].push_back( (int) e.size() );
e.push_back(e1);
g[b].push_back( (int) e.size() );
e.push_back(e2);
}
int getMaxFlow(int _s, int _t) {
s = _s; t = _t;
int flow = 0;
for (;;) {
if (!bfs()) break;
for (int i = 0; i < n; ++i) ptr[i] = 0;
while (int pushed = dfs(s, INF))
flow += pushed;
}
return flow;
}
vector<int> trace() {
bfs();
vector<int> res;
for(auto edge : e) {
if (edge.flow == edge.cap) {
res.push_back(edge.id);
}
}
return res;
}
private:
bool bfs() {
int qh = 0, qt = 0;
q[qt++] = s;
fill(d.begin(), d.end(), -1);
d[s] = 0;
while (qh < qt && d[t] == -1) {
int v = q[qh++];
for (int i = 0; i < (int)g[v].size(); ++i) {
int id = g[v][i], to = e[id].b;
if (d[to] == -1 && e[id].flow < e[id].cap) {
q[qt++] = to;
d[to] = d[v] + 1;
}
}
}
return d[t] != -1;
}
int dfs (int v, int flow) {
if (!flow) return 0;
if (v == t) return flow;
for (; ptr[v] < (int)g[v].size(); ++ptr[v]) {
int id = g[v][ptr[v]],
to = e[id].b;
if (d[to] != d[v] + 1) continue;
int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
if (pushed) {
e[id].flow += pushed;
e[id^1].flow -= pushed;
return pushed;
}
}
return 0;
}
};
int main() {
freopen("cuplaj.in", "r", stdin);
freopen("cuplaj.out", "w", stdout);
ios_base::sync_with_stdio(false);
int n, m, e; cin >> n >> m >> e;
MaxFlow flow(n + m + 2);
int s = n + m, d = n + m + 1;
vector<int> To(e), From(e);
for (int i = 0; i < e; ++i) {
cin >> From[i] >> To[i];
--From[i]; --To[i];
flow.addEdge(From[i], To[i] + n, 1, i);
}
for (int i = 0; i < n; ++i)
flow.addEdge(s, i, 1, -1);
for (int i = 0; i < m; ++i)
flow.addEdge(i + n, d, 1, -1);
int maxFlow = flow.getMaxFlow(s, d);
cout << maxFlow << endl;
vector<int> ids = flow.trace();
cerr << ids.size() << " edges " << endl;
for (auto x : ids) {
if (x != -1) {
cout << From[x] + 1 << " " << To[x] + 1 << '\n';
}
}
return 0;
}