#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
const int dim=1<<17;
char next_ch()
{
static int bp=dim;
static char buff[dim];
if(bp==dim)
{
fread(buff,1,dim,stdin);
bp=0;
}
return buff[bp++];
}
void get(int &a)
{
a=0;
char ch;
do
{
ch=next_ch();
}
while(ch<'0'||'9'<ch);
do
{
a=a*10+ch-'0';
ch=next_ch();
}
while('0'<=ch&&ch<='9');
}
using T=int;
struct Dinic
{
struct Edge
{
int a,b,ult;
T flow,cap;
};
vector <Edge> es;
vector <int> last,dist,coada;
Dinic(int n)
{
last.assign(n+1,-1);
}
void AddEdge(int a,int b,T c)
{
es.push_back({a,b,last[a],0,c});
last[a]=es.size()-1;
es.push_back({b,a,last[b],0,0});
last[b]=es.size()-1;
}
bool bfs(int s,int t)
{
coada.clear();
dist.assign(last.size(),-1);
dist[s]=0;
coada.push_back(s);
for(int i=0; i<(int)coada.size(); i++)
{
int it=coada[i];
for(int x=last[it]; x!=-1; x=es[x].ult)
{
if(dist[es[x].b]==-1&&es[x].cap>es[x].flow)
{
dist[es[x].b]=dist[it]+1;
coada.push_back(es[x].b);
}
}
}
//for(int i=1; i<last.size(); i++)
//out<<dist[i]<<" ";
//out<<'\n';
return (dist[t]!=-1);
}
T dfs(int s,int t,T pas)
{
T tot=0;
if(s==t||pas==0)
return pas;
for(int x=last[s]; x!=-1; x=es[x].ult)
{
if(dist[es[x].b]==dist[s]+1&&es[x].cap>es[x].flow)
{
T cat=dfs(es[x].b,t,min(pas,es[x].cap-es[x].flow));
if(cat)
{
es[x].flow+=cat;
es[x^1].flow-=cat;
tot+=cat;
pas-=cat;
}
}
if(!pas)
break;
}
return tot;
}
T Compute(int s,int t)
{
T rez=0;
while(bfs(s,t))
rez+=dfs(s,t,numeric_limits<T>::max());
return rez;
}
};
int main()
{
freopen("cuplaj.in","r",stdin);
freopen("cuplaj.out","w",stdout);
int n,m,i,a,b,p;
get(n);
get(p);
get(m);
Dinic d(2+n+p);
for(i=2; i<=n+1; i++)
d.AddEdge(1,i,1);
for(i=1; i<=m; i++)
{
get(a);
get(b);
d.AddEdge(1+a,n+1+b,1);
}
for(i=1; i<=p; i++)
d.AddEdge(n+1+i,n+p+2,1);
cout<<d.Compute(1,n+p+2)<<'\n';
for(auto it:d.es)
if(it.cap==it.flow&&it.a>=2&&it.a<=n+1&&it.b>=n+2&&it.b<=n+p+1)
cout<<it.a-1<<" "<<it.b-n-1<<'\n';
return 0;
}