#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 209
#define M 40009
struct edge{int to,flow,nxt;}dir[M];
int n,m,x,y,cnt,ans,dep[N],head[N],opt[N];
bool vis[N];
queue<int>q;
bool bfs()
{
memset(dep,0x3f,sizeof(dep));
memset(vis,0,sizeof(vis));
while(!q.empty()) q.pop();
vis[0]=1,dep[0]=1,q.push(0);
while(!q.empty())
{
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=dir[i].nxt)
{
int v=dir[i].to;
if(dep[v]>dep[u]+1&&dir[i].flow)
{
dep[v]=dep[u]+1;
if(!vis[v]) vis[v]=1,q.push(v);
}
}
}
return dep[n+1]!=INF;
}
int dfs(int id,int flow)
{
if(id==n+1) return flow;
int pos,used=0;
for(int i=head[id];i!=-1;i=dir[i].nxt)
{
int to=dir[i].to;
if(dep[to]==dep[id]+1&&dir[i].flow)
{
pos=dfs(to,min(flow-used,dir[i].flow));
if(pos!=0)
{
dir[i].flow-=pos;
dir[i^1].flow+=pos;
used+=pos;
if(id!=0&&to!=n+1) opt[id]=to,opt[to]=id;
if(used==flow) return used;
}
}
}
if(!used) dep[x]=INF;
return used;
}
int main()
{
scanf("%d%d",&m,&n),ans=0;
memset(head,-1,sizeof(head));
while(scanf("%d%d",&x,&y)!=EOF)
{
if(x==-1&&y==-1) break;
dir[++cnt]={y,1,head[x]},head[x]=cnt;
dir[++cnt]={x,0,head[y]},head[y]=cnt;
}
for(int i=1;i<=m;i++)
{
dir[++cnt]={i,1,head[0]},head[0]=cnt;
dir[++cnt]={0,0,head[i]},head[i]=cnt;
}
for(int i=m+1;i<=n;i++)
{
dir[++cnt]={n+1,1,head[i]},head[i]=cnt;
dir[++cnt]={i,0,head[n+1]},head[n+1]=cnt;
}
while(bfs()) ans+=dfs(0,INF);
printf("%d\n",ans);
for(int i=1;i<=m;i++)
{
if(i==opt[opt[i]]) printf("%d %d\n",i,opt[i]);
else if(i==opt[opt[i]]) printf("%d %d\n",i,opt[i]);
}
return 0;
}
WA on #6 #7 #10 #11 63pts Dinic