#include<bits/stdc++.h>
#define N 5005
#define M N*N*2
using namespace std;
int n,m,s,t;
int tot=1,head[N],w[M],nxt[M],to[M];
void addedge(int u,int v,int ww){
to[++tot]=v;w[tot]=ww;nxt[tot]=head[u];head[u]=tot;
to[++tot]=u;w[tot]=ww;nxt[tot]=head[v];head[v]=tot;
}
int now[N],d[N];
int col[N];
void dfs(int u,int c){
col[u]=c;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(!col[v]){
dfs(v,3-c);
}
}
}
void build(){
s=n+1,t=n+2;
for(int i=1;i<=n;i++){
if(col[i]==1){
for(int j=head[i];j;j=nxt[j]){
w[j^1]=0;
}
addedge(s,i,1);
w[tot]=0;
}
else{
for(int j=head[i];j;j=nxt[j]){
w[j]=0;
}
addedge(i,t,1);
w[tot]=0;
}
}
}
queue<int> Q;
bool bfs(){
memset(d,0,sizeof(d));
while(!Q.empty())Q.pop();
Q.push(s);d[s]=1;now[s]=head[s];
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(d[v]||w[i]==0)continue;
d[v]=d[u]+1;
now[v]=head[v];
Q.push(v);
if(v==t)return 1;
}
}
return 0;
}
int dinic(int u,int flow){
if(u==t){
return flow;
}
int rest=flow,k,i;
for(int i=head[u];i&&rest;i=nxt[i]){
int v=to[i];
if(w[i]&&d[v]==d[u]+1){
k=dinic(v,min(rest,w[i]));
if(!k)d[v]=0;
rest-=k;
w[i]-=k;
w[i^1]+=k;
}
}
now[u]=i;
return flow-rest;
}
int dfn[N],num=0,low[N],stk[N],cnt=0,top=0,scc[N];
void tarjan(int u){
low[u]=dfn[u]=++num;
stk[++top]=u;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(w[i]==0)continue;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else{
if(!scc[v]){
low[u]=min(low[u],dfn[v]);
}
}
}
if(low[u]==dfn[u]){
++cnt;
while(1){
int p=stk[top];
scc[p]=cnt;
top--;
if(p==u)break;
}
}
return;
}
struct ele{
int x,y;
}tmp[N];
int size=0;
bool cmp(ele a,ele b){
if(a.x!=b.x){
return a.x<b.x;
}
else{
return a.y<b.y;
}
}
void solve(){
for(int i=2;i<=tot;i++){
if(w[i]==1&&col[to[i]]==1){
if(to[i]!=s&&to[i]!=t&&to[i^1]!=s&&to[i^1]!=t){
if(scc[to[i]]!=scc[to[i^1]]){
tmp[++size].x=to[i];
tmp[size].y=to[i^1];
if(tmp[size].x>tmp[size].y){
swap(tmp[size].x,tmp[size].y);
}
}
}
}
}
sort(tmp+1,tmp+size+1,cmp);
printf("%d\n",size);
for(int i=1;i<=size;i++){
printf("%d %d\n",tmp[i].x,tmp[i].y);
}
return;
}
queue<int> q;
bool visit[N];
void printfgraph(int s){
q.push(s);
memset(visit,0,sizeof(visit));
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=nxt[i]){
cout<<"Edge from"<<u<<"to"<<to[i]<<",c="<<w[i]<<endl;
if(visit[to[i]])continue;
visit[to[i]]=1;
q.push(to[i]);
}
}
}
void printe(){
for(int i=2;i<=tot;i++){
if(w[i])
printf("from%dto%d,c=%d,colto=%d\n",to[i^1],to[i],w[i],col[to[i]]);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v,ww=1;
scanf("%d%d",&u,&v);
addedge(u,v,ww);
}
for(int i=1;i<=n;i++){
if(!col[i])dfs(i,1);
}
build();
while(bfs()){
while(dinic(s,(1<<30)));
}
for(int i=n+2;i>=1;i--){
if(!dfn[i])tarjan(i);
}
solve();
return 0;
}