// Acest cod este scris deoarece doresc sa testez un algoritm greedy pe
// care nu il pot demonstra si caruia nu ii pot gasi un contraexecmplu.
// Nu intentionez sa obtin 100 de puncte cu el.
// Ilie Dumitru
#include<cstdio>
#include<vector>
#include<bitset>
#include<queue>
const int NMAX=10005;
struct edge
{
int node, pos;
};
struct el
{
int node, deg;
friend bool operator<(el a, el b)
{
return a.deg>b.deg;
}
};
int N, M;
std::vector<edge> G[NMAX*2];
std::bitset<NMAX*2> matched;
std::vector<int> ans;
void addEdge(int a, int b)
{
G[a].push_back({b, (int)G[b].size()});
G[b].push_back({a, (int)G[a].size()-1});
}
void remove_edge(int a, int idx)
{
int b=G[a][idx].node, bidx=G[a][idx].pos;
int la=(int)G[a].size(), lb=(int)G[b].size();
// G[a][idx]={b, bidx};
// G[b][bidx]={a, idx};
if(la-1!=idx)
{
G[G[a][la-1].node][G[a][la-1].pos].pos=idx;
}
if(lb-1!=bidx)
{
G[G[b][lb-1].node][G[b][lb-1].pos].pos=bidx;
}
std::swap(G[a][idx], G[a][la-1]);
std::swap(G[b][bidx], G[b][lb-1]);
G[a].resize(la-1);
G[b].resize(lb-1);
}
void cuplajGreedy()
{
std::priority_queue<el> pq;
int i, a, b, min, minPos, x;
for(i=0;i<N+M;++i)
if(!G[i].empty())
pq.push({i, (int)G[i].size()});
while(!pq.empty())
{
a=pq.top().node;
pq.pop();
if(!matched[a] && (int)G[a].size())
{
minPos=0;
min=(int)G[G[a][0].node].size();
for(i=1;i<(int)G[a].size();++i)
{
if(min>(int)G[G[a][i].node].size())
{
minPos=i;
min=(int)G[G[a][i].node].size();
}
}
b=G[a][minPos].node;
matched[a]=matched[b]=1;
ans.push_back(a);
ans.push_back(b);
remove_edge(a, minPos);
while((int)G[a].size())
{
x=G[a][(int)G[a].size()-1].node;
remove_edge(a, (int)G[a].size()-1);
pq.push({x, (int)G[x].size()});
}
while((int)G[b].size())
{
x=G[b][(int)G[b].size()-1].node;
remove_edge(b, (int)G[b].size()-1);
pq.push({x, (int)G[x].size()});
}
}
}
}
int main()
{
FILE* f=fopen("cuplaj.in", "r"), *g=fopen("cuplaj.out", "w");
int i, a, b, E;
fscanf(f, "%d%d%d", &N, &M, &E);
for(i=0;i<E;++i)
{
fscanf(f, "%d%d", &a, &b);
--a;
--b;
b+=N;
addEdge(a, b);
}
cuplajGreedy();
fprintf(g, "%d\n", (int)ans.size()/2);
for(i=0;i<(int)ans.size();i+=2)
{
a=ans[i];
b=ans[i+1];
if(a<N)
b-=N;
else
{
std::swap(a, b);
b-=N;
}
fprintf(g, "%d %d\n", a+1, b+1);
}
fclose(f);
fclose(g);
return 0;
}