#include <cstdio>
#include <vector>
#include <queue>
#include <climits>
const int INF = INT_MAX;
struct Edge{
int x, y, cap_flow;
Edge(int x = 0, int y = 0, int cap_flow = 0): x(x), y(y), cap_flow(cap_flow) {}
};
class MaxFlow{
private:
int n, s, d;
std::vector<Edge> edges;
std::vector<std::vector<int>> G;
std::vector<int> t;
public:
MaxFlow(int, int, int, std::vector<std::pair <int, std::pair<int, int>>>&);
int bfs();
int update_flow();
int max_flow();
std::vector<std::pair<int, int>> matching(int);
};
MaxFlow::MaxFlow(int n, int s, int d, std::vector<std::pair <int, std::pair<int, int>>>& _edges): n(n), s(s), d(d){
int i = 0;
G = std::vector<std::vector<int>>(n);
for(const auto& edge: _edges){
G[edge.first].push_back(i ++);
G[edge.second.first].push_back(i ++);
edges.push_back({edge.first, edge.second.first, edge.second.second});
edges.push_back({edge.second.first, edge.first, edge.second.second});
}
}
int MaxFlow::bfs(){
std::queue<int> q;
t = std::vector<int> (n, -1);
t[s] = -2;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
if(u == d)
continue;
for(const auto& edge_id: G[u]){
int v = edges[edge_id].y;
if(t[v] == -1 && edges[edge_id].cap_flow > 0){
t[v] = edge_id;
q.push(v);
}
}
}
return t[d] != -1;
}
int MaxFlow::update_flow(){
int node, flow;
flow = INF;
for(node = d; t[node] != -2; node = edges[t[node]].x)
flow = std::min(flow, edges[t[node]].cap_flow);
for(node = d; t[node] != -2; node = edges[t[node]].x){
edges[t[node]].cap_flow -= flow;
edges[t[node] ^ 1].cap_flow += flow;
}
return flow;
}
int MaxFlow::max_flow(){
int flow = 0;
while(bfs()){
for(const auto& edge_id: G[d]){
int node = edges[edge_id].y;
int cap_flow = edges[edge_id ^ 1].cap_flow;
if(cap_flow == 0 || t[node] == -1)
continue;
t[d] = edge_id ^ 1;
flow += update_flow();
}
}
return flow;
}
std::vector<std::pair<int, int>> MaxFlow::matching(int l){
std::vector<std::pair<int, int>> matching_edges;
for(int u = 1; u <= l; u ++)
for(const auto& edge_id: G[u])
if(edges[edge_id].cap_flow == 0 && edges[edge_id].y > l)
matching_edges.push_back({u, edges[edge_id].y});
return matching_edges;
}
int main(){
freopen("cuplaj.in", "r", stdin);
freopen("cuplaj.out", "w", stdout);
int n, m, e, x, y;
std::vector<std::pair <int, std::pair<int, int>>> edges;
scanf("%d%d%d", &n, &m, &e);
for(int i = 0; i < e; i ++){
scanf("%d%d", &x, &y);
edges.push_back({x, {y + n, 1}});
}
for(int i = 1; i <= n; i ++)
edges.push_back({0, {i, 1}});
for(int i = n + 1; i <= n + m; i ++)
edges.push_back({i, {n + m + 1, 1}});
MaxFlow maxflow(n + m + 2, 0, n + m + 1, edges);
int max_flow = maxflow.max_flow();
std::vector<std::pair<int, int>> matching_edges = maxflow.matching(n);
printf("%d\n", max_flow);
for(const auto& edge: matching_edges)
printf("%d %d\n", edge.first, edge.second - n);
return 0;
}