// Copyright: lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__)

ll read(){
	ll x=0,f=1;char c=getchar();
	while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}

const int maxn = 1000100;
int n, m;
vector<pii> G[maxn];
bool vis[maxn], flag[maxn], shit[maxn];
int deg[maxn], d[maxn];
vector<pii> ans;
set<pii> s;
int id[maxn];

inline void dfs(int u, bool f) {
	while (id[u] < G[u].size()) {
		int v = G[u][id[u]].fi; int ind = G[u][id[u]].se;
		id[u]++;
		if (vis[ind]) continue;
		vis[ind] = 1;
		if (f) {
			if (ind) {
                ans.pb(mp(min(u, v), max(u, v)));
                flag[ind] = 1;
            }
            shit[ind] = 1;
		}
		dfs(v, f ^ 1);
	}
}

void work() {
	n = read(), m = read();
	rep(i, 1, m) {
		int x = read(),  y = read();
		G[x].pb(mp(y, i)); G[y].pb(mp(x, i));
		deg[x]++; deg[y]++;
	}
	vector<int> vec;
	rep(i, 1, n) if (deg[i] & 1) vec.pb(i);
	for (int i = 0; i < vec.size(); i += 2) {
		int x = vec[i], y = vec[i + 1];
		G[x].pb(mp(y, 0)); G[y].pb(mp(x, 0)); deg[x]++; deg[y]++;
		s.insert(mp(min(x, y), max(x, y)));
	}
	rep(i, 1, n) {
		if (id[i] != G[i].size()) dfs(i, 1);
	}
	int cnt = 0;
	rep(i, 0, ans.size() - 1) {
		cnt++; d[ans[i].fi]++; d[ans[i].se]++;
	}
	rep(i, 1, n) {
		if (d[i] * 2 < deg[i]) {
            if (deg[i] - d[i] * 2 > 2) {
                cout<<i<<' '<<d[i]<<' '<<deg[i]<<endl;
                puts("shit");
                rep(j, 0, G[i].size() - 1) {
                    int ind = G[i][j].se;
                    cout<<shit[ind]<<' '<<ind<<' ';
                }
                while(1);
            }
			rep(j, 0, G[i].size() - 1) {
				int ind = G[i][j].se;
				int v = G[i][j].fi;
				if (ind == -1) continue;
				if (!flag[ind]) {
					flag[ind] = 1;
					d[i]++; d[v]++;
					ans.pb(mp(min(i, v), max(i, v)));
					cnt++; break;
				}
			}
		}
	}
	printf("%d\n", cnt);
	rep(i, 0, ans.size() - 1) {
		printf("%d %d\n", ans[i].fi, ans[i].se);
	}
}

int main(){
	#ifdef LZT
		freopen("in","r",stdin);
	#endif

	work();

	#ifdef LZT
		Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
	#endif
}


// Copyright: lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__)

ll read(){
	ll x=0,f=1;char c=getchar();
	while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}

const int maxn = 1000100;
int n, m;
vector<pii> G[maxn];
bool vis[maxn], flag[maxn], shit[maxn];
int deg[maxn], d[maxn];
vector<pii> ans;
set<pii> s;
int id[maxn];

inline void dfs(int u, bool f) {
	while (id[u] < G[u].size()) {
		int v = G[u][id[u]].fi; int ind = G[u][id[u]].se;
		id[u]++;
		if (vis[ind]) continue;
		vis[ind] = 1;
		if (f) {
			if (ind) {
                ans.pb(mp(min(u, v), max(u, v)));
                flag[ind] = 1;
            }
            shit[ind] = 1;
		}
		dfs(v, f ^ 1);
        break;
	}
}

void work() {
	n = read(), m = read();
	rep(i, 1, m) {
		int x = read(),  y = read();
		G[x].pb(mp(y, i)); G[y].pb(mp(x, i));
		deg[x]++; deg[y]++;
	}
	vector<int> vec;
	rep(i, 1, n) if (deg[i] & 1) vec.pb(i);
	for (int i = 0; i < vec.size(); i += 2) {
		int x = vec[i], y = vec[i + 1];
		G[x].pb(mp(y, 0)); G[y].pb(mp(x, 0)); deg[x]++; deg[y]++;
		s.insert(mp(min(x, y), max(x, y)));
	}
	rep(i, 1, n) {
		if (id[i] != G[i].size()) dfs(i, 1);
	}
	int cnt = 0;
	rep(i, 0, ans.size() - 1) {
		cnt++; d[ans[i].fi]++; d[ans[i].se]++;
	}
	rep(i, 1, n) {
		if (d[i] * 2 < deg[i]) {
            if (deg[i] - d[i] * 2 > 2) {
                cout<<i<<' '<<d[i]<<' '<<deg[i]<<endl;
                cout<<id[i]<<endl;
                rep(j, 0, G[i].size() - 1) {
                    int ind = G[i][j].se;
                    cout<<shit[ind]<<' '<<ind<<' ';
                }
                exit(0);
            }
			rep(j, 0, G[i].size() - 1) {
				int ind = G[i][j].se;
				int v = G[i][j].fi;
				if (ind == -1) continue;
				if (!flag[ind]) {
					flag[ind] = 1;
					d[i]++; d[v]++;
					ans.pb(mp(min(i, v), max(i, v)));
					cnt++; break;
				}
			}
		}
	}
	printf("%d\n", cnt);
	rep(i, 0, ans.size() - 1) {
		printf("%d %d\n", ans[i].fi, ans[i].se);
	}
}

int main(){
	#ifdef LZT
		freopen("in","r",stdin);
	#endif

	work();

	#ifdef LZT
		Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
	#endif
}


// Copyright: lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__)

ll read(){
	ll x=0,f=1;char c=getchar();
	while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}

const int maxn = 1000100;
int n, m;
vector<pii> G[maxn];
bool vis[maxn], flag[maxn], shit[maxn];
int deg[maxn], d[maxn];
vector<pii> ans;
pii ed[maxn];
int id[maxn], seq[maxn], num;

inline void dfs(int u) {
	for (int &i = id[u]; i < G[u].size(); i++) {
		int v = G[u][id[u]].fi; int ind = G[u][id[u]].se;
		if (vis[ind]) continue;
		vis[ind] = 1; seq[++num] = ind;
        dfs(v);
	}
}

void work() {
	n = read(), m = read();
	rep(i, 1, m) {
		int x = read(),  y = read();
		G[x].pb(mp(y, i)); G[y].pb(mp(x, i));
		deg[x]++; deg[y]++; ed[i] = mp(x, y);
	}
	vector<int> vec; vec.clear();
	rep(i, 1, n) if (deg[i] & 1) vec.pb(i);
	for (int i = 0; i < vec.size(); i += 2) {
		int x = vec[i], y = vec[i + 1];
		G[x].pb(mp(y, 0)); G[y].pb(mp(x, 0));
        deg[x]++; deg[y]++;
	}
	rep(i, 1, n) dfs(i);
    for (int i = 1; i <= num; i += 2) {
        if (seq[i] > 0) {
            ans.pb(ed[seq[i]]);
            flag[seq[i]] = 1;
        }
    }
	int cnt = 0;
	rep(i, 0, ans.size() - 1) {
		cnt++; d[ans[i].fi]++; d[ans[i].se]++;
	}
	rep(i, 1, n) {
		if (d[i] * 2 < deg[i]) {
            if (deg[i] - d[i] * 2 > 2) {
                cout<<i<<' '<<d[i]<<' '<<deg[i]<<endl;
                cout<<id[i]<<endl;
                rep(j, 0, G[i].size() - 1) {
                    int ind = G[i][j].se;
                    cout<<vis[ind]<<' '<<ind<<' ';
                }
                exit(0);
            }
			rep(j, 0, G[i].size() - 1) {
				int ind = G[i][j].se;
				int v = G[i][j].fi;
				if (ind == -1) continue;
				if (!flag[ind]) {
					flag[ind] = 1;
					d[i]++; d[v]++;
					ans.pb(mp(min(i, v), max(i, v)));
					cnt++; break;
				}
			}
		}
	}
	printf("%d\n", cnt);
	rep(i, 0, ans.size() - 1) {
		printf("%d %d\n", ans[i].fi, ans[i].se);
	}
}

int main(){
	#ifdef LZT
		freopen("in","r",stdin);
	#endif

	work();

	#ifdef LZT
		Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
	#endif
}


// Copyright: lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__)

ll read(){
	ll x=0,f=1;char c=getchar();
	while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}

const int maxn = 2000200;
int n, m;
vector<pii> G[maxn];
bool vis[maxn], flag[maxn], shit[maxn];
int deg[maxn], d[maxn];
vector<pii> ans;
pii ed[maxn];
int id[maxn], seq[maxn], num;

inline void dfs(int u) {
	for (int &i = id[u]; i < G[u].size(); i++) {
		int v = G[u][id[u]].fi; int ind = G[u][id[u]].se;
		if (vis[ind]) continue;
		vis[ind] = 1; seq[++num] = ind;
        if (n == 1000 && m == 1000) {
            if (u == 650 || v == 650) cout<<u<<' '<<v<<' '<<num<<"    ";
        }
        dfs(v);
	}
}

void work() {
	n = read(), m = read(); int tm = m;
	rep(i, 1, m) {
		int x = read(),  y = read();
		G[x].pb(mp(y, i)); G[y].pb(mp(x, i));
		deg[x]++; deg[y]++; ed[i] = mp(x, y);
	}
	vector<int> vec; vec.clear();
	rep(i, 1, n) if (deg[i] & 1) vec.pb(i);
	for (int i = 0; i < vec.size(); i += 2) {
		int x = vec[i], y = vec[i + 1];
		G[x].pb(mp(y, ++m)); G[y].pb(mp(x, m));
        deg[x]++; deg[y]++; ed[m] = mp(x, y);
	}
    m = tm;
	rep(i, 1, n) dfs(i);
    if (n == 1e6 && m == 1e6) puts("");
    for (int i = 1; i <= num; i += 2) {
        if (seq[i] <= m) {
            ans.pb(ed[seq[i]]);
            flag[seq[i]] = 1;
        }
    }
	int cnt = 0;
	rep(i, 0, ans.size() - 1) {
		cnt++; d[ans[i].fi]++; d[ans[i].se]++;
	}
	rep(i, 1, n) {
		if (d[i] * 2 < deg[i]) {
            if (deg[i] - d[i] * 2 > 2) {
                cout<<i<<' '<<d[i]<<' '<<deg[i]<<endl;
                cout<<id[i]<<endl;
                rep(j, 0, G[i].size() - 1) {
                    int ind = G[i][j].se;
                    cout<<vis[ind]<<' '<<ind<<' ';
                }
                exit(0);
            }
			rep(j, 0, G[i].size() - 1) {
				int ind = G[i][j].se;
				int v = G[i][j].fi;
				if (ind > m) continue;
				if (!flag[ind]) {
					flag[ind] = 1;
					d[i]++; d[v]++;
					ans.pb(mp(min(i, v), max(i, v)));
					cnt++; break;
				}
			}
		}
	}
	printf("%d\n", cnt);
	rep(i, 0, ans.size() - 1) {
		printf("%d %d\n", ans[i].fi, ans[i].se);
	}
}

int main(){
	#ifdef LZT
		freopen("in","r",stdin);
	#endif

	work();

	#ifdef LZT
		Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
	#endif
}


#include<cstdio>
#include<cctype>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define rep
#define gc (p1==p2&&(p2=(p1=fr)+fread(fr,1,1<<21,stdin))==p1?EOF:*p1++)
#define fl fwrite(fw,1,q-fw,stdout),q=fw
using namespace std;
const int L=(1<<21)+9;
char ch,fr[L],*p1=fr,*p2=fr,fw[L],*q=fw;
void rd(int&x)
{
	while(!isdigit(ch=gc));x=ch-48;
	while( isdigit(ch=gc)) x=ch-48+x*10;
}
void pc(char c) {*q++=c; if(q-fw==1<<21)fl;}
void pt(int x) {if(x>9)pt(x/10); pc(x%10+48);}
const int N=1e6+9,M=4*N;
int n,m,u,v,tot=1,to[M],ne[M],la[N],cur[N],s,top,st[N+M],ans,p[N][2];
bool d[N],vs[M],bz;
void lk(int x,int y)
{
	to[++tot]=y,ne[tot]=la[x],la[x]=tot;
	to[++tot]=x,ne[tot]=la[y],la[y]=tot;
}
void dg(int x) {for(int i=cur[x],y;y=to[i];i=cur[x]){cur[x]=ne[i]; if(!vs[i/2])vs[i/2]=1,dg(y);} st[++top]=x;}
int main()
{
	rd(n),rd(m);
	fo(i,1,m) rd(u),rd(v),lk(u,v),d[u]^=1,d[v]^=1;
	fo(i,1,n) if(d[i]) s++,u=i;
	if(s)
	{
		u=n+1;
		fo(i,1,n) if(d[i]) lk(u,i);
	}
	memcpy(cur,la,4*(n+2));
	dg(u); bz=0;
	for(;top>1;top--,bz^=1)
	{
		if(st[top]==n+1||st[top-1]==n+1) {bz=0; continue;}
		if(top==2||top>2&&st[top-2]==n+1) bz=1;
		if(bz) ans++,p[ans][0]=st[top],p[ans][1]=st[top-1];
	}
	pt(ans),pc('\n');
	fo(i,1,ans) pt(p[i][0]),pc(' '),pt(p[i][1]),pc('\n');
	fl;
}


#include<cstdio>
#include<cctype>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define rep
#define gc (p1==p2&&(p2=(p1=fr)+fread(fr,1,1<<21,stdin))==p1?EOF:*p1++)
#define fl fwrite(fw,1,q-fw,stdout),q=fw
using namespace std;
const int L=(1<<21)+9;
char ch,fr[L],*p1=fr,*p2=fr,fw[L],*q=fw;
void rd(int&x)
{
	while(!isdigit(ch=gc));x=ch-48;
	while( isdigit(ch=gc)) x=ch-48+x*10;
}
void pc(char c) {*q++=c; if(q-fw==1<<21)fl;}
void pt(int x) {if(x>9)pt(x/10); pc(x%10+48);}
const int N=1e6+9,M=4*N;
int n,m,u,v,tot=1,to[M],ne[M],la[N],cur[N],s,top,st[N+M],ans,p[N][2];
bool d[N],vs[M],bz;
void lk(int x,int y)
{
	to[++tot]=y,ne[tot]=la[x],la[x]=tot;
	to[++tot]=x,ne[tot]=la[y],la[y]=tot;
}
void dg(int x) {for(int i=cur[x],y;y=to[i];i=cur[x]){cur[x]=ne[i]; if(!vs[i/2])vs[i/2]=1,dg(y);} st[++top]=x;}
int main()
{
	rd(n),rd(m);
	fo(i,1,m) rd(u),rd(v),lk(u,v),d[u]^=1,d[v]^=1;
	fo(i,1,n) if(d[i]) s++;
	if(s)
	{
		u=n+1;
		fo(i,1,n) if(d[i]) lk(u,i);
	}
	memcpy(cur,la,4*(n+2));
	dg(u); int _=1;
	while(top)
	{
		bz=0;
		for(;top>1;top--,bz^=1)
		{
			if(st[top]==n+1||st[top-1]==n+1) {bz=0; continue;}
			if(top==2||top>2&&st[top-2]==n+1) bz=1;
			if(bz) ans++,p[ans][0]=st[top],p[ans][1]=st[top-1];
		}
		top=0;
		fo(i,_,n) if(la[i]&&cur[i]==la[i]) {dg(i); i=_+1; break;}
	}
	pt(ans),pc('\n');
	fo(i,1,ans) pt(p[i][0]),pc(' '),pt(p[i][1]),pc('\n');
	fl;
}


#include<cstdio>
#include<cctype>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define rep
#define gc (p1==p2&&(p2=(p1=fr)+fread(fr,1,1<<21,stdin))==p1?EOF:*p1++)
#define fl fwrite(fw,1,q-fw,stdout),q=fw
using namespace std;
const int L=(1<<21)+9;
char ch,fr[L],*p1=fr,*p2=fr,fw[L],*q=fw;
void rd(int&x)
{
	while(!isdigit(ch=gc));x=ch-48;
	while( isdigit(ch=gc)) x=ch-48+x*10;
}
void pc(char c) {*q++=c; if(q-fw==1<<21)fl;}
void pt(int x) {if(x>9)pt(x/10); pc(x%10+48);}
const int N=1e6+9,M=4*N;
int n,m,u,v,tot=1,to[M],ne[M],la[N],cur[N],s,top,st[N+M],ans,p[N][2];
bool d[N],vs[M],bz;
void lk(int x,int y)
{
	to[++tot]=y,ne[tot]=la[x],la[x]=tot;
	to[++tot]=x,ne[tot]=la[y],la[y]=tot;
}
void dg(int x) {for(int i=cur[x],y;y=to[i];i=cur[x]){cur[x]=ne[i]; if(!vs[i/2])vs[i/2]=1,dg(y);} st[++top]=x;}
int main()
{
	rd(n),rd(m);
	fo(i,1,m) rd(u),rd(v),lk(u,v),d[u]^=1,d[v]^=1;
	fo(i,1,n) if(d[i]) s++;
	if(s)
	{
		u=n+1;
		fo(i,1,n) if(d[i]) lk(u,i);
	}
	memcpy(cur,la,4*(n+2));
	dg(u);
	while(top)
	{
		bz=0;
		for(;top>1;top--,bz^=1)
		{
			if(st[top]==n+1||st[top-1]==n+1) {bz=0; continue;}
			if(top==2||top>2&&st[top-2]==n+1) bz=1;
			if(bz) ans++,p[ans][0]=st[top],p[ans][1]=st[top-1];
		}
		top=0;
		fo(i,1,n) if(la[i]&&cur[i]==la[i]) dg(i);
	}
	pt(ans),pc('\n');
	fo(i,1,ans) pt(p[i][0]),pc(' '),pt(p[i][1]),pc('\n');
	fl;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		if (x>y)
			swap(x,y);
		M[x][y]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[x][y],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--,r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(min(t,y),max(t,y)));
				}
				else
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--;
					S.insert((point) {y,d[y],r[y]});
				}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].first][E[i].second],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
			{
				y=(*it).second;
				r[t]--;
				E.push_back(make_pair(min(t,y),max(t,y)));
			}
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].first][E[i].second],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

inline void fastprintf(int x)
{
	char c[8];
	c[0]=0;
	for (;x>0;x=x/10)
		c[0]++,c[c[0]]=x%10;
	for (;c[0]>0;c[0]--)
		putchar(c[c[0]]+48);
	return;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--,r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(t,y));
				}
				else
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--;
					S.insert((point) {y,d[y],r[y]});
				}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	fastprintf(E.size()),puts("");
	for (Eit=E.begin();Eit!=E.end();Eit++)
		fastprintf((*Eit).first),putchar(' '),
		fastprintf((*Eit).second),puts("");
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--,r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(t,y));
				}
				else
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--;
					S.insert((point) {y,d[y],r[y]});
				}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

int main()
{
	srand((int) time(0));
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if (! b[(*it).second])
			{
				S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
				d[(*it).second]--;
				S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
				if ((r[t]) && (r[(*it).second]))
				{
					S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
					r[t]--,r[(*it).second]--;
					S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
					E.push_back(make_pair(t,(*it).second));
				}
			}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
			{
				S.erase(S.find((point) {y,d[y],r[y]}));
				d[y]--;
				S.insert((point) {y,d[y],r[y]});
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(t,y));
				}
			}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <set>
#include <vector>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < int > T[1200000];
set < int > :: iterator it;
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

int main()
{
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		T[x].insert(y);
		T[y].insert(x);
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if (! b[*it])
			{
				S.erase(S.find((point) {*it,d[*it],r[*it]}));
				d[*it]--;
				S.insert((point) {*it,d[*it],r[*it]});
				if ((r[t]) && (r[*it]))
				{
					S.erase(S.find((point) {*it,d[*it],r[*it]}));
					r[t]--,r[*it]--;
					S.insert((point) {*it,d[*it],r[*it]});
					E.push_back(make_pair(t,*it));
				}
			}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(E[i].second),
			T[E[i].second].erase(E[i].first);
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[*it]))
				r[t]--,E.push_back(make_pair(t,*it));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(E[i].second),
			T[E[i].second].erase(E[i].first);
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

char c[15000000];
int b[1200000],d[1200000],r[1200000];
int i,k,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	k++;
	while (! ((c[k]>47) && (c[k]<58)))
		k++;
	while ((c[k]>47) && (c[k]<58))
		t=t*10+c[k]-48,k++;
	return t;
}

int main()
{
	srand((int) time(0));
	fread(c+1,1,14999999,stdin);
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if (! b[(*it).second])
			{
				S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
				d[(*it).second]--;
				S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
				if ((r[t]) && (r[(*it).second]))
				{
					S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
					r[t]--,r[(*it).second]--;
					S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
					E.push_back(make_pair(t,(*it).second));
				}
			}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

inline void fastprintf(int x)
{
	if (! x)
		putchar('0');
	else
	{
		char c[8];
		c[0]=0;
		for (;x>0;x=x/10)
			c[0]++,c[c[0]]=x%10;
		for (;c[0]>0;c[0]--)
			putchar(c[c[0]]+48);
	}
	return;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--,r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(t,y));
				}
				else
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--;
					S.insert((point) {y,d[y],r[y]});
				}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();(r[t]) && (it!=T[t].end());it++)
			if (! r[(*it).second])
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	fastprintf(E.size()),puts("");
	for (Eit=E.begin();Eit!=E.end();Eit++)
		fastprintf((*Eit).first),putchar(' '),
		fastprintf((*Eit).second),puts("");
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

inline void fastprintf(int x)
{
	char c[8];
	c[0]=0;
	for (;x>0;x=x/10)
		c[0]++,c[c[0]]=x%10;
	for (;c[0]>0;c[0]--)
		putchar(c[c[0]]+48);
	return;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	if (! m)
		return puts("0"),0;
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
			{
				S.erase(S.find((point) {y,d[y]}));
				d[y]--;
				S.insert((point) {y,d[y]});
				if ((r[t]) && (r[y]))
				{
					r[t]--,r[y]--;
					E.push_back(make_pair(t,y));
				}
			}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();(r[t]) && (it!=T[t].end());it++)
			if (! r[(*it).second])
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	fastprintf(E.size()),puts("");
	for (Eit=E.begin();Eit!=E.end();Eit++)
		fastprintf((*Eit).first),putchar(' '),
		fastprintf((*Eit).second),puts("");
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < pair <int,int>,int > M;
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,k,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[make_pair(x,y)]=rand()<<15|rand();
		M[make_pair(y,x)]=rand()<<15|rand();
		T[x].insert(make_pair(M[make_pair(x,y)],y));
		T[y].insert(make_pair(M[make_pair(y,x)],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
			{
				S.erase(S.find((point) {y,d[y],r[y]}));
				d[y]--;
				S.insert((point) {y,d[y],r[y]});
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(t,y));
				}
			}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[make_pair(E[i].first,E[i].second)],E[i].second)),
			T[E[i].second].erase(make_pair(M[make_pair(E[i].second,E[i].first)],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[make_pair(E[i].first,E[i].second)],E[i].second)),
			T[E[i].second].erase(make_pair(M[make_pair(E[i].second,E[i].first)],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

inline void fastprintf(int x)
{
	char c[8];
	c[0]=0;
	for (;x>0;x=x/10)
		c[0]++,c[c[0]]=x%10;
	for (;c[0]>0;c[0]--)
		putchar(c[c[0]]+48);
	return;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--,r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(t,y));
				}
				else
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--;
					S.insert((point) {y,d[y],r[y]});
				}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();(r[t]) && (it!=T[t].end());it++)
			if (! r[(*it).second])
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	fastprintf(E.size()),puts("");
	for (Eit=E.begin();Eit!=E.end();Eit++)
		fastprintf((*Eit).first),putchar(' '),
		fastprintf((*Eit).second),puts("");
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

inline void fastprintf(int x)
{
	char c[8];
	c[0]=0;
	for (;x>0;x=x/10)
		c[0]++,c[c[0]]=x%10;
	for (;c[0]>0;c[0]--)
		putchar(c[c[0]]+48);
	return;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--,r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(t,y));
				}
				else
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--;
					S.insert((point) {y,d[y],r[y]});
				}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();(r[t]) && (it!=T[t].end());it++)
			if (! r[(*it).second])
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	fastprintf(E.size()),puts("");
	for (Eit=E.begin();Eit!=E.end();Eit++)
		fastprintf((*Eit).first),putchar(' '),
		fastprintf((*Eit).second),puts("");
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < pair <int,int>,int > M;
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

char c[15000000];
int b[1200000],d[1200000],r[1200000];
int i,k,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	k++;
	while (! ((c[k]>47) && (c[k]<58)))
		k++;
	while ((c[k]>47) && (c[k]<58))
		t=t*10+c[k]-48,k++;
	return t;
}

int main()
{
	srand((int) time(0));
	fread(c+1,1,14999999,stdin);
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[make_pair(x,y)]=rand()<<15|rand();
		M[make_pair(y,x)]=rand()<<15|rand();
		T[x].insert(make_pair(M[make_pair(x,y)],y));
		T[y].insert(make_pair(M[make_pair(y,x)],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if (! b[(*it).second])
			{
				S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
				d[(*it).second]--;
				S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
				if ((r[t]) && (r[(*it).second]))
				{
					S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
					r[t]--,r[(*it).second]--;
					S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
					E.push_back(make_pair(t,(*it).second));
				}
			}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[make_pair(E[i].first,E[i].second)],E[i].second)),
			T[E[i].second].erase(make_pair(M[make_pair(E[i].second,E[i].first)],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[make_pair(E[i].first,E[i].second)],E[i].second)),
			T[E[i].second].erase(make_pair(M[make_pair(E[i].second,E[i].first)],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if (! b[(*it).second])
			{
				S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
				d[(*it).second]--;
				S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
				if ((r[t]) && (r[(*it).second]))
				{
					S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
					r[t]--,r[(*it).second]--;
					S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
					E.push_back(make_pair(t,(*it).second));
				}
			}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000],v[1200000];
int i,m,n,t,x,y;

int main()
{
	srand((int) time(0));
	scanf("%d%d",&n,&m);
	for (i=1;i<=n;i++)
		v[i]=rand()<<15|rand();
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		T[x].insert(make_pair(v[y],y));
		T[y].insert(make_pair(v[x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if (! b[(*it).second])
			{
				S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
				d[(*it).second]--;
				S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
				if ((r[t]) && (r[(*it).second]))
				{
					S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
					r[t]--,r[(*it).second]--;
					S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
					E.push_back(make_pair(t,(*it).second));
				}
			}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(v[E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(v[E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(v[E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(v[E[i].first],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <set>
#include <vector>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r<t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < int > T[1200000];
set < int > :: iterator it;
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

int main()
{
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		T[x].insert(y);
		T[y].insert(x);
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if (! b[*it])
			{
				S.erase(S.find((point) {*it,d[*it],r[*it]}));
				d[*it]--;
				S.insert((point) {*it,d[*it],r[*it]});
				if ((r[t]) && (r[*it]))
				{
					S.erase(S.find((point) {*it,d[*it],r[*it]}));
					r[t]--,r[*it]--;
					S.insert((point) {*it,d[*it],r[*it]});
					E.push_back(make_pair(t,*it));
				}
			}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(E[i].second),
			T[E[i].second].erase(E[i].first);
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[*it]))
				r[t]--,E.push_back(make_pair(t,*it));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(E[i].second),
			T[E[i].second].erase(E[i].first);
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000],v[1200000];
int i,m,n,t,x,y;

int main()
{
	srand((int) time(0));
	for (i=1;i<=n;i++)
		v[i]=rand()<<15|rand();
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		T[x].insert(make_pair(v[y],y));
		T[y].insert(make_pair(v[x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if (! b[(*it).second])
			{
				S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
				d[(*it).second]--;
				S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
				if ((r[t]) && (r[(*it).second]))
				{
					S.erase(S.find((point) {(*it).second,d[(*it).second],r[(*it).second]}));
					r[t]--,r[(*it).second]--;
					S.insert((point) {(*it).second,d[(*it).second],r[(*it).second]});
					E.push_back(make_pair(t,(*it).second));
				}
			}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(v[E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(v[E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
			if ((r[t]) && (! r[(*it).second]))
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(v[E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(v[E[i].first],E[i].first));
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <cstdio>
#include <ctime>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			return i<t.i;
	}
};

set < point > S;
set < pair <int,int> > T[1200000];
set < pair <int,int> > :: iterator it;
map < int,int > M[1200000];
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;

int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

inline void fastprintf(int x)
{
	char c[8];
	c[0]=0;
	for (;x>0;x=x/10)
		c[0]++,c[c[0]]=x%10;
	for (;c[0]>0;c[0]--)
		putchar(c[c[0]]+48);
	return;
}

int main()
{
	srand((int) time(0));
	n=fastscanf(),m=fastscanf();
	if (! m)
		return puts("0"),0;
	for (i=1;i<=m;i++)
	{
		x=fastscanf(),y=fastscanf();
		M[x][y]=rand()<<15|rand();
		M[y][x]=rand()<<15|rand();
		T[x].insert(make_pair(M[x][y],y));
		T[y].insert(make_pair(M[y][x],x));
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		x=E.size();
		for (it=T[t].begin();it!=T[t].end();it++)
		{
			y=(*it).second;
			if (! b[y])
				if ((r[t]) && (r[y]))
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--,r[t]--,r[y]--;
					S.insert((point) {y,d[y],r[y]});
					E.push_back(make_pair(t,y));
				}
				else
				{
					S.erase(S.find((point) {y,d[y],r[y]}));
					d[y]--;
					S.insert((point) {y,d[y],r[y]});
				}
		}
		for (i=x;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
		y=E.size();
		for (it=T[t].begin();(r[t]) && (it!=T[t].end());it++)
			if (! r[(*it).second])
				r[t]--,E.push_back(make_pair(t,(*it).second));
		for (i=y;i<E.size();i++)
			T[E[i].first].erase(make_pair(M[E[i].first][E[i].second],E[i].second)),
			T[E[i].second].erase(make_pair(M[E[i].second][E[i].first],E[i].first));
	}
	fastprintf(E.size()),puts("");
	for (Eit=E.begin();Eit!=E.end();Eit++)
		fastprintf((*Eit).first),putchar(' '),
		fastprintf((*Eit).second),puts("");
	return 0;
}


#include <cstdio>
#include <set>
#include <vector>

using namespace std;

struct point
{
	int i,d,r;

	inline bool operator < (const point t) const
	{
		if (d!=t.d)
			return d<t.d;
		else
			if (r!=t.r)
				return r>t.r;
			else
				return i<t.i;
	}
};

set < point > S;
vector < int > V[1200000];
vector < int > :: iterator it;
vector < pair <int,int> > E;
vector < pair <int,int> > :: iterator Eit;
int b[1200000],d[1200000],r[1200000];
int i,m,n,t,x,y;

int main()
{
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		V[x].push_back(y);
		V[y].push_back(x);
		d[x]++,d[y]++;
	}
	for (i=1;i<=n;i++)
	{
		r[i]=(d[i]+1)/2;
		S.insert((point) {i,d[i],r[i]});
	}
	while (! S.empty())
	{
		t=(*S.begin()).i;
		S.erase(S.begin());
		b[t]=1;
		for (it=V[t].begin();it!=V[t].end();it++)
			if (! b[*it])
			{
				S.erase(S.find((point) {*it,d[*it],r[*it]}));
				d[*it]--;
				S.insert((point) {*it,d[*it],r[*it]});
				if (r[t])
				{
					S.erase(S.find((point) {*it,d[*it],r[*it]}));
					r[t]--,r[*it]--;
					S.insert((point) {*it,d[*it],r[*it]});
					E.push_back(make_pair(t,*it));
				}
			}
	}
	printf("%d\n",E.size());
	for (Eit=E.begin();Eit!=E.end();Eit++)
		printf("%d %d\n",(*Eit).first,(*Eit).second);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int sz=1e6+10;
multiset <int> sv[sz];
set <int> sv2[sz];
vector <int> sp;
int st[sz];
void dfs(int v)
{
    while(sv[v].size())
    {
        int ne=*sv[v].begin();
        sv[v].erase(sv[v].begin());
        sv[ne].erase(sv[ne].find(v));
        dfs(ne);
    }
    sp.push_back(v);
}
main()
{
    //freopen("input.txt", "r", stdin);
    int n, m;
    cin>>n>>m;
    for(int a=0; a<m; a++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        u--, v--;
        sv[u].insert(v), sv[v].insert(u);
        st[u]++, st[v]++;
        sv2[u].insert(v), sv2[v].insert(u);
    }
    int pr=-1;
    for(int a=0; a<n; a++)
    {
        if(st[a]&1)
        {
            if(pr==-1) pr=a;
            else
            {
                sv[a].insert(pr), sv[pr].insert(a);
                pr=-1;
            }
        }
    }
    vector <pair <int, int> > an;
    for(int a=0; a<n; a++)
    {
        if(sv[a].size())
        {
            dfs(a);
            for(int b=0; b+1<sp.size(); b++)
            {
                if(b&1)
                {
                    int u=sp[b], v=sp[b+1];
                    if(sv2[v].count(u))
                    {
                        sv2[u].erase(v), sv2[v].erase(u);
                        an.push_back({u, v});
                    }
                }
            }
            sp.clear();
        }
    }
    for(int a=0; a<n; a++)
    {
        if(sv2[a].size()*2>st[a])
        {
            int ne=*sv2[a].begin();
            sv2[a].erase(ne), sv2[ne].erase(a);
            an.push_back({a, ne});
        }
    }
    cout<<an.size()<<"\n";
    for(int a=0; a<an.size(); a++)
    {
        printf("%d %d\n", an[a].first+1, an[a].second+1);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int sz=1e6+10;
set <int> sv[sz], sv2[sz];
vector <int> sp;
int st[sz];
void dfs(int v)
{
    while(sv[v].size())
    {
        int ne=*sv[v].begin();
        sv[v].erase(sv[v].begin());
        sv[ne].erase(v);
        dfs(ne);
        sp.push_back(v);
    }
}
main()
{
    //freopen("input.txt", "r", stdin);
    int n, m;
    cin>>n>>m;
    for(int a=0; a<m; a++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        u--, v--;
        sv[u].insert(v), sv[v].insert(u);
        st[u]++, st[v]++;
        sv2[u].insert(v), sv2[v].insert(u);
    }
    int pr=-1;
    for(int a=0; a<n; a++)
    {
        if(st[a]&1)
        {
            if(pr==-1) pr=a;
            else
            {
                sv[a].insert(pr), sv[pr].insert(a);
                pr=-1;
            }
        }
    }
    vector <pair <int, int> > an;
    for(int a=0; a<n; a++)
    {
        if(sv[a].size())
        {
            dfs(a);
            for(int b=0; b+1<sp.size(); b++)
            {
                if(b&1)
                {
                    int u=sp[b], v=sp[b+1];
                    if(sv2[v].count(u))
                    {
                        sv2[u].erase(v), sv2[v].erase(u);
                        an.push_back({u, v});
                    }
                }
            }
            sp.clear();
        }
    }
    for(int a=0; a<n; a++)
    {
        if(sv2[a].size()*2>st[a])
        {
            int ne=*sv2[a].begin();
            sv2[a].erase(ne), sv2[ne].erase(a);
            an.push_back({a, ne});
        }
    }
    cout<<an.size()<<"\n";
    for(int a=0; a<an.size(); a++)
    {
        printf("%d %d\n", an[a].first+1, an[a].second+1);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int sz=1e6+10;
set <int> sv[sz], sv2[sz];
vector <int> sp;
int st[sz];
void dfs(int v)
{
    while(sv[v].size())
    {
        int ne=*sv[v].begin();
        sv[v].erase(sv[v].begin());
        sv[ne].erase(v);
        dfs(ne);
    }
    sp.push_back(v);
}
main()
{
    //freopen("input.txt", "r", stdin);
    int n, m;
    cin>>n>>m;
    for(int a=0; a<m; a++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        u--, v--;
        sv[u].insert(v), sv[v].insert(u);
        st[u]++, st[v]++;
        sv2[u].insert(v), sv2[v].insert(u);
    }
    int pr=-1;
    for(int a=0; a<n; a++)
    {
        if(st[a]&1)
        {
            if(pr==-1) pr=a;
            else
            {
                sv[a].insert(pr), sv[pr].insert(a);
                pr=-1;
            }
        }
    }
    vector <pair <int, int> > an;
    for(int a=0; a<n; a++)
    {
        if(sv[a].size())
        {
            dfs(a);
            for(int b=0; b+1<sp.size(); b++)
            {
                if(b&1)
                {
                    int u=sp[b], v=sp[b+1];
                    if(sv2[v].count(u))
                    {
                        sv2[u].erase(v), sv2[v].erase(u);
                        an.push_back({u, v});
                    }
                }
            }
            sp.clear();
        }
    }
    for(int a=0; a<n; a++)
    {
        if(sv2[a].size()*2>st[a])
        {
            int ne=*sv2[a].begin();
            sv2[a].erase(ne), sv2[ne].erase(a);
            an.push_back({a, ne});
        }
    }
    cout<<an.size()<<"\n";
    for(int a=0; a<an.size(); a++)
    {
        printf("%d %d\n", an[a].first+1, an[a].second+1);
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],v[maxn],vis2[maxm],st[maxm],re[maxm];
void euler( lint x ){
    lint top = 0;
    st[top++] = x;
    re[0] = 0;
    //v[x] = 1;
    while( top ){
        x = st[top-1];
        lint cure  = he[x];
        while( cure && vis[cure] ) cure = ne[cure];
        if( cure ){
            lint y = ver[cure];
            vis[cure] = vis[cure^1] = 1;
            st[top++] = y;
            re[top-1] = id[cure];
        }else{
            top--;
            if( re[top]  )ans.push_back( re[top] );
        }
    }
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    lint totm = m;
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,++totm );add( i,0,totm );
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        ans.clear();
        euler(i);
        for (int j = 1; j < ans.size(); j += 2) {
            int now = ans[j];
            if(now > m) vis2[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(tmp> m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == ans.size()) Next = 0;
                tmp = ans[Next];
                if(tmp > m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                vis2[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res );
    for( lint i = 1;i <= m;i++ ){
        if( vis2[i] ) continue;
        printf("%d %d\n", edge[i].first,edge[i].second );
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
struct edge {
    int u, v, flag;
};

int st[maxn * 2], ans[maxn * 2], re[maxn * 2];
edge a[maxn * 2];
int head[maxn], id[maxn * 4], Next[maxn * 4], ver[maxn * 4], tot, totm, tot_ans;
bool v[maxn * 4], vis[maxn * 4];
int deg[maxn];
int Top;
void add(int x, int y, int z) {
    ver[++tot] = y, id[tot] = z, Next[tot] = head[x], head[x] = tot;
}
void euler (int s) {
    tot_ans = 0;
    st[++Top] = s;
    while(Top > 0) {
        int x = st[Top], i = head[x];
        while(i && v[i]) i = Next[i];
        if(i) {
            st[++Top] = ver[i];
            re[Top] = id[i];
            v[i] = v[i ^ 1] = 1;
            head[x] = Next[i];
        } else {
            ans[++tot_ans] = re[Top];
            Top--;
        }
    }
}
int main() {
    int n, m, x, y;
    scanf("%d%d", &n, &m);
    tot = 1;
    for (int i = 1; i <= m; i++) {
        scanf("%d%d", &x, &y);
        totm++;
        a[totm] = (edge){x, y, 1};
        add(x, y, totm), add(y, x, totm);
        deg[x]++, deg[y]++;
    }
    for (int i = 1; i <= n; i++) {
        if(deg[i] & 1) {
            totm++;
            a[totm] = (edge){0, i, 0};
            add(0, i, totm), add(i, 0, totm);
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        euler(i);
        for (int j = 2; j <= tot_ans; j += 2) {
            int now = ans[j];
            if(a[now].flag == 0) vis[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(a[tmp].flag == 0 && vis[tmp] == 0) {
                    vis[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == tot_ans) Next = 1;
                tmp = ans[Next];
                if(a[tmp].flag == 0 && vis[tmp] == 0) {
                    vis[tmp] = 1;
                    continue;
                }
                vis[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res);
    for (int i = 1; i <= totm; i++) {
        if(vis[i] == 0) {
            if(a[i].flag == 1) {
                printf("%d %d\n", a[i].u, a[i].v);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],v[maxn],vis2[maxm],st[maxm],re[maxm],top;
void euler( lint x ){
    st[++top] = x;
    while( top>0 ){
        lint x = st[top];
        lint cure  = he[x];
        while( cure && vis[cure] ) cure = ne[cure];
        if( cure ){
            lint y = ver[cure];
            vis[cure] = vis[cure^1] = 1;
            st[++top] = y;
            re[top] = id[cure];
            he[x] = ne[cure];
        }else{
            if( top !=  1  )ans.push_back( re[top] );
            top--;
        }
    }
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    lint totm = m;
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,++totm );add( i,0,totm );
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        ans.clear();
        if(v[i]) continue;
        euler(i);
        for (int j = 1; j < ans.size(); j += 2) {
            int now = ans[j];
            if(now > m) vis2[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(tmp> m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == ans.size()) Next = 0;
                tmp = ans[Next];
                if(tmp > m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                vis2[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res );
    for( lint i = 1;i <= m;i++ ){
        if( vis2[i] ) continue;
        printf("%d %d\n", edge[i].first,edge[i].second );
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 1000001;
const lint maxm = 2000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm];
void euler( lint x,lint e ){
    for( lint cure = he[x];cure;cure = ne[cure] ){
        if( vis[cure] ) continue;
        vis[cure] = vis[cure^1] = 1;
        lint y = ver[cure];
        euler( y,cure );
    }
    if( e )
    ans.push_back( id[e] );
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,0 );add( i,0,0 );
        }
    }
    euler(1,0);
    memset( vis,0,sizeof(vis) );
    lint cnt = 0;
    for( lint i = 0;i < ans.size();i++ ){
        if( (i & 1)  && ans[i] ) {
            if( ans[i-1] == 0 && !vis[i-1] ){
                vis[i-1] = 1;
            }else if(  ans[(i+1)%ans.size()] == 0 && !vis[(i+1)%ans.size()] ){
                vis[(i+1)%ans.size()] = 1;
            }else{
                vis[i] = 1;
                cnt++;
            }
        }
    }
    printf("%d\n", m-cnt );
    for( lint i = 0;i < ans.size();i++ ){
        if( !vis[i] && ans[i] ){
            lint x = edge[ ans[i] ].first;
            lint y = edge[ans[i]].second;
            printf("%d %d\n",x,y);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
struct edge {
    int u, v, flag;
};

int st[maxn * 2], ans[maxn * 2], re[maxn * 2];
edge a[maxn * 2];
int head[maxn], id[maxn * 4], Next[maxn * 4], ver[maxn * 4], tot, totm, tot_ans;
bool v[maxn * 4], vis[maxn * 4];
int deg[maxn];
int Top;
void add(int x, int y, int z) {
    ver[++tot] = y, id[tot] = z, Next[tot] = head[x], head[x] = tot;
}
void euler (int s) {
    for( int cure = head[s];cure;cure = Next[cure] ){
        if(v[cure]) continue;
        v[cure] = v[cure^1] = 1;
        int y = ver[cure];
        euler(y);
        ans[++tot_ans] =  id[cure];
    }
}
int main() {
    int n, m, x, y;
    scanf("%d%d", &n, &m);
    tot = 1;
    for (int i = 1; i <= m; i++) {
        scanf("%d%d", &x, &y);
        totm++;
        a[totm] = (edge){x, y, 1};
        add(x, y, totm), add(y, x, totm);
        deg[x]++, deg[y]++;
    }
    for (int i = 1; i <= n; i++) {
        if(deg[i] & 1) {
            totm++;
            a[totm] = (edge){0, i, 0};
            add(0, i, totm), add(i, 0, totm);
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        tot_ans = 0;
        euler(i);
        for (int j = 2; j <= tot_ans; j += 2) {
            int now = ans[j];
            if(a[now].flag == 0) vis[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(a[tmp].flag == 0 && vis[tmp] == 0) {
                    vis[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == tot_ans) Next = 1;
                tmp = ans[Next];
                if(a[tmp].flag == 0 && vis[tmp] == 0) {
                    vis[tmp] = 1;
                    continue;
                }
                vis[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res);
    for (int i = 1; i <= totm; i++) {
        if(vis[i] == 0) {
            if(a[i].flag == 1) {
                printf("%d %d\n", a[i].u, a[i].v);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 1e6+1;
lint du[maxn];
struct node{
    lint x,y,id;
    lint dx,dy;
    node( lint xx,lint yy,lint ddx,lint ddy ){
        x = xx;
        y = yy;
        dx = ddx;
        dy = ddy;
    }
    bool operator <( const node& b )const{
        lint z1 = min( dx,dy );
        lint z2 = min( b.dx,b.dy );
        if( z1 == z2 ){
            return max( dx,dy ) < max( b.dx,b.dy );
        }
        return z1 < z2;
    }
};
priority_queue<node> que;
vector<pii> edge;
lint ans;
int main(){
    lint n,m,x,y;
    scanf("%d%d",&n,&m);
    for( lint i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        du[x]++;du[y]++;
        edge.push_back( pii(x,y) );
    }
    for( lint i = 1;i <= n;i++ ) du[i] /= 2;
    for( lint i = 0;i < edge.size();i++ ){
        lint x = edge[i].first;
        lint y = edge[i].second;
        que.push( node( x,y,du[x],du[y] ) );
    }
    lint cnt = m - (n+m+1)/2;
    while( que.size() ){
        node cur = que.top();
        que.pop();
        lint x = cur.x;lint y = cur.y;
        if( cur.dx != du[x] || cur.dy != du[y] ){
            que.push( node( x,y,du[x],du[y] ) );
            continue;
        }
        du[x]--;du[y]--;
        ans++;
        if( ans >= cnt ) break;
    }
    printf("%d\n", m - ans );
    while( que.size() ){
        node cur = que.top();que.pop();
        printf("%d %d\n",cur.x,cur.y);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 3000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm];
void euler( lint x){
    for( lint cure = he[x];cure;cure = ne[cure] ){
        if( vis[cure] ) continue;
        vis[cure] = vis[cure^1] = 1;
        lint y = ver[cure];
        euler( y );
        ans.push_back( id[cure] );
    }
}
vector<pii> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,0 );add( i,0,0 );
        }
    }
    lint used ,vis;
    for( lint i = 0;i <= n;i++ ){
        used = 0; ans.clear();vis = 0;
        euler(i);
        for( lint i = 0;i < ans.size();i++ ){
            if( i&1 && ans[i]  ) {
                if (!used && !ans[i - 1]) {
                    if (i - 1 == 0) vis = 1;
                    res.push_back( pii(edge[ans[i]].first, edge[ans[i]].second));
                } else if (i + 1 < ans.size() && ans[i + 1] == 0) {
                    used = 1;
                    res.push_back( pii(edge[ans[i]].first, edge[ans[i]].second));
                } else if (i + 1 == ans.size() && !vis && ans[0] == 0) {
                    res.push_back( pii(edge[ans[i]].first, edge[ans[i]].second));
                } else {
                    used = 0;
                }
            }else if( i%2 == 0 && ans[i] ){
                res.push_back( pii( edge[ans[i]].first, edge[ans[i]].second));
            }
        }
    }
    printf("%d\n",res.size());
    for( lint i =0;i < res.size();i++ ){
        printf("%d %d\n",res[i].first,res[i].second);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],v[maxn],vis2[maxm],st[maxm],re[maxm],top;
void euler (int s) {
    st[++top] = s;
    while(top > 0) {
        int x = st[top], i = he[x];
        while(i && v[i]) i = ne[i];
        if(i) {
            st[++top] = ver[i];
            re[top] = id[i];
            v[i] = v[i ^ 1] = 1;
            he[x] = ne[i];
        } else {
            ans.push_back(re[top]);
            top--;
        }
    }
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    lint totm = m;
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,++totm );add( i,0,totm );
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        ans.clear();
        euler(i);
        for (int j = 1; j < ans.size(); j += 2) {
            int now = ans[j];
            if(now > m) vis2[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(tmp> m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == ans.size()) Next = 0;
                tmp = ans[Next];
                if(tmp > m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                vis2[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res );
    for( lint i = 1;i <= m;i++ ){
        if( vis2[i] ) continue;
        printf("%d %d\n", edge[i].first,edge[i].second );
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 1e6+1;
lint du[maxn];
struct node{
    lint x,y,id;
    lint dx,dy;
    node( lint xx,lint yy,lint ddx,lint ddy ){
        x = xx;
        y = yy;
        dx = ddx;
        dy = ddy;
    }
    bool operator <( const node& b )const{
        lint z1 = min( dx,dy );
        lint z2 = min( b.dx,b.dy );
        if( z1 == z2 ){
            return max( dx,dy ) < max( b.dx,b.dy );
        }
        return z1 < z2;
    }
};
priority_queue<node> que;
vector<pii> edge;
lint ans;
int main(){
    lint n,m,x,y;
    scanf("%d%d",&n,&m);
    for( lint i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        du[x]++;du[y]++;
        edge.push_back( pii(x,y) );
    }
    for( lint i = 1;i <= n;i++ ) du[i] /= 2;
    for( lint i = 0;i < edge.size();i++ ){
        lint x = edge[i].first;
        lint y = edge[i].second;
        que.push( node( x,y,du[x],du[y] ) );
    }
    lint cnt = m - (n+m+1)/2;
    while( que.size() ){
        node cur = que.top();
        que.pop();
        lint x = cur.x;lint y = cur.y;
        if( cur.dx != du[x] || cur.dy != du[y] ){
            que.push( node( x,y,du[x],du[y] ) );
            continue;
        }
        du[x]--;du[y]--;
        ans++;
        if( ans >= cnt || du[x] < 0 || du[y] < 0 ) break;
    }
    printf("%d\n", m - ans );
    while( que.size() ){
        node cur = que.top();que.pop();
        printf("%d %d\n",cur.x,cur.y);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],vis2[maxn];
void euler( lint x){
    vis2[x] = 1;
    for( lint cure = he[x];cure;cure = ne[cure] ){
        if( vis[cure] ) continue;
        vis[cure] = vis[cure^1] = 1;
        lint y = ver[cure];
        euler( y );
        ans.push_back( id[cure] );
    }
}
vector<pii> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,0 );add( i,0,0 );
        }
    }
    lint used ,vis1;
    for( lint i = 0;i <= n;i++ ){
        if( vis2[i] ) continue;
        used = 0; ans.clear();vis1 = 0;
        euler(i);
        for( lint j = 0;j < ans.size();j++ ){
            if( (j&1) && ans[j]  ) {
                if (!used && !ans[j - 1]) {
                    if (j - 1 == 0) vis1 = 1;
                    res.push_back( pii(edge[ans[j]].first, edge[ans[j]].second));
                } else if (j + 1 < ans.size() && ans[j + 1] == 0) {
                    used = 1;
                    res.push_back( pii(edge[ans[j]].first, edge[ans[j]].second));
                } else if (j + 1 == ans.size() && !vis1 && ans[0] == 0) {
                    res.push_back( pii(edge[ans[j]].first, edge[ans[j]].second));
                } else {
                    used = 0;
                }
            }else if( i%2 == 0 && ans[j] ){
                res.push_back( pii( edge[ans[j]].first, edge[ans[j]].second));
            }
        }
    }
    printf("%d\n",res.size());
    for( lint i =0;i < res.size();i++ ){
        printf("%d %d\n",res[i].first,res[i].second);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 1000001;
const lint maxm = 2000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm];
void euler( lint x){
    for( lint cure = he[x];cure;cure = ne[cure] ){
        if( vis[cure] ) continue;
        vis[cure] = vis[cure^1] = 1;
        lint y = ver[cure];
        euler( y );
        ans.push_back( id[cure] );
    }
}
vector<pii> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,0 );add( i,0,0 );
        }
    }
    lint used ,vis;
    for( lint i = 0;i <= n;i++ ){
        used = 0; ans.clear();vis = 0;
        euler(i);
        for( lint i = 0;i < ans.size();i++ ){
            if( i&1 && ans[i]  ) {
                if (!used && !ans[i - 1]) {
                    if (i - 1 == 0) vis = 1;
                    res.push_back( pii(edge[ans[i]].first, edge[ans[i]].second));
                } else if (i + 1 < ans.size() && ans[i + 1] == 0) {
                    used = 1;
                    res.push_back( pii(edge[ans[i]].first, edge[ans[i]].second));
                } else if (i + 1 == ans.size() && !vis && ans[0] == 0) {
                    res.push_back( pii(edge[ans[i]].first, edge[ans[i]].second));
                } else {
                    used = 0;
                }
            }else if( i%2 == 0 && ans[i] ){
                res.push_back( pii( edge[ans[i]].first, edge[ans[i]].second));
            }
        }
    }
    printf("%d\n",res.size());
    for( lint i =0;i < res.size();i++ ){
        printf("%d %d\n",res[i].first,res[i].second);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],v[maxn],vis2[maxm],st[maxm],re[maxm];
void euler( lint x ){
    lint top = 0;
    st[top++] = x;
    re[0] = 0;
    //v[x] = 1;
    while( top>0 ){
        x = st[top-1];
        lint cure  = he[x];
        while( cure && vis[cure] ) cure = ne[cure];
        if( cure ){
            lint y = ver[cure];
            vis[cure] = vis[cure^1] = 1;
            st[top++] = y;
            re[top-1] = id[cure];
        }else{
            top--;
            if( top>0  )ans.push_back( re[top] );
        }
    }
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    lint totm = m;
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,++totm );add( i,0,totm );
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        ans.clear();
        euler(i);
        for (int j = 1; j < ans.size(); j += 2) {
            int now = ans[j];
            if(now > m) vis2[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(tmp> m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == ans.size()) Next = 0;
                tmp = ans[Next];
                if(tmp > m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                vis2[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res );
    for( lint i = 1;i <= m;i++ ){
        if( vis2[i] ) continue;
        printf("%d %d\n", edge[i].first,edge[i].second );
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 1000001;
const lint maxm = 2000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm];
void euler( lint x,lint e ){
    for( lint cure = he[x];cure;cure = ne[cure] ){
        if( vis[cure] ) continue;
        vis[cure] = vis[cure^1] = 1;
        lint y = ver[cure];
        euler( y,cure );
    }
    if( e )
        ans.push_back( id[e] );
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    lint totm = m;
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,++totm );add( i,0,++totm );
        }
    }
    lint cnt = 0;
    memset(vis, 0, sizeof(vis));
    for( lint i = 0;i <= n;i++ ) {
        euler(i, 0);
        lint cnt = 0;ans.clear();
        for (lint i = 0; i < ans.size(); i++) {
            if ((i & 1) && ans[i] <= m ) {
                if (ans[i - 1] > m && !vis[ans[i - 1] ]) {
                    vis[ans[i - 1] ] = 1;
                } else if (ans[(i + 1) % ans.size()] > m && !vis[ans[(i + 1) % ans.size()]]) {
                    vis[ans[(i + 1) % ans.size()]] = 1;
                } else {
                    vis[ ans[i] ] = 1;
                    cnt++;
                }
            }
        }
    }
    printf("%d\n", m-cnt );
    for( lint i = 1;i <= m;i++ ){
        if( vis[i] ) continue;
        printf("%d %d\n", edge[i].first,edge[i].second );
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
struct edge {
    int u, v, flag;
};

int st[maxn * 2], ans[maxn * 2], re[maxn * 2];
edge a[maxn * 2];
int head[maxn], id[maxn * 4], Next[maxn * 4], ver[maxn * 4], tot, totm, tot_ans;
bool v[maxn * 4], vis[maxn * 4];
int deg[maxn];
int Top;
void add(int x, int y, int z) {
    ver[++tot] = y, id[tot] = z, Next[tot] = head[x], head[x] = tot;
}
void euler (int s) {
    for( int cure = head[s];cure;cure = Next[cure] ){
        if(v[cure]) continue
        v[cure] = v[cure^1] = 1;
        int y = ver[cure];
        euler(y);
        ans[++tot_ans] =  id[cure];
    }
}
int main() {
    int n, m, x, y;
    scanf("%d%d", &n, &m);
    tot = 1;
    for (int i = 1; i <= m; i++) {
        scanf("%d%d", &x, &y);
        totm++;
        a[totm] = (edge){x, y, 1};
        add(x, y, totm), add(y, x, totm);
        deg[x]++, deg[y]++;
    }
    for (int i = 1; i <= n; i++) {
        if(deg[i] & 1) {
            totm++;
            a[totm] = (edge){0, i, 0};
            add(0, i, totm), add(i, 0, totm);
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        tot_ans = 0;
        euler(i);
        for (int j = 2; j <= tot_ans; j += 2) {
            int now = ans[j];
            if(a[now].flag == 0) vis[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(a[tmp].flag == 0 && vis[tmp] == 0) {
                    vis[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == tot_ans) Next = 1;
                tmp = ans[Next];
                if(a[tmp].flag == 0 && vis[tmp] == 0) {
                    vis[tmp] = 1;
                    continue;
                }
                vis[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res);
    for (int i = 1; i <= totm; i++) {
        if(vis[i] == 0) {
            if(a[i].flag == 1) {
                printf("%d %d\n", a[i].u, a[i].v);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],vis2[maxn];
void euler( lint x){
    vis2[x] = 1;
    for( lint cure = he[x];cure;cure = ne[cure] ){
        if( vis[cure] ) continue;
        vis[cure] = vis[cure^1] = 1;
        lint y = ver[cure];
        euler( y );
        ans.push_back( id[cure] );
    }
}
vector<pii> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,0 );add( i,0,0 );
        }
    }
    lint used ,vis1;
    for( lint i = 0;i <= n;i++ ){
        if( vis2[i] ) continue;
        used = 0; ans.clear();vis1 = 0;
        euler(i);
        for( lint j = 0;j < ans.size();j++ ){
            if( (j&1) && ans[j]  ) {
                if (!used && !ans[j - 1]) {
                    if (j - 1 == 0) vis1 = 1;
                    res.push_back( pii(edge[ans[j]].first, edge[ans[j]].second));
                } else if (j + 1 < ans.size() && ans[j + 1] == 0) {
                    used = 1;
                    res.push_back( pii(edge[ans[j]].first, edge[ans[j]].second));
                } else if (j + 1 == ans.size() && !vis1 && ans[0] == 0) {
                    res.push_back( pii(edge[ans[j]].first, edge[ans[j]].second));
                } else {
                    used = 0;
                }
            }else if( j%2 == 0 && ans[j] ){
                res.push_back( pii( edge[ans[j]].first, edge[ans[j]].second));
            }
        }
    }
    printf("%d\n",res.size());
    for( lint i =0;i < res.size();i++ ){
        printf("%d %d\n",res[i].first,res[i].second);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],v[maxn],vis2[maxm],st[maxm],re[maxm];
void euler( lint x ){
    lint top = 0;
    st[++top] = x;
    re[0] = 0;
    v[x] = 1;
    while( top>0 ){
        x = st[top];
        lint cure  = he[x];
        while( cure && vis[cure] ) cure = ne[cure];
        if( cure ){
            lint y = ver[cure];v[y] = 1;
            vis[cure] = vis[cure^1] = 1;
            st[++top] = y;
            re[top] = id[cure];
        }else{
            if( top !=  1  )ans.push_back( re[top] );
            top--;
        }
    }
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    lint totm = m;
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,++totm );add( i,0,totm );
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        ans.clear();
        if(v[i]) continue;
        euler(i);
        for (int j = 1; j < ans.size(); j += 2) {
            int now = ans[j];
            if(now > m) vis2[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(tmp> m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == ans.size()) Next = 0;
                tmp = ans[Next];
                if(tmp > m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                vis2[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res );
    for( lint i = 1;i <= m;i++ ){
        if( vis2[i] ) continue;
        printf("%d %d\n", edge[i].first,edge[i].second );
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 1000001;
const lint maxm = 2000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm];
void euler( lint x,lint e ){
    for( lint cure = he[x];cure;cure = ne[cure] ){
        if( vis[cure] ) continue;
        vis[cure] = vis[cure^1] = 1;
        lint y = ver[cure];
        euler( y,cure );
    }
    if( e )
    ans.push_back( id[e] );
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,0 );add( i,0,0 );
        }
    }
    for( lint i = 0;i <= n;i++ )
    euler(i,0);
    memset( vis,0,sizeof(vis) );
    lint cnt = 0;
    for( lint i = 0;i < ans.size();i++ ){
        if( (i & 1)  && ans[i] ) {
            if( ans[i-1] == 0 && !vis[i-1] ){
                vis[i-1] = 1;
            }else if(  ans[(i+1)%ans.size()] == 0 && !vis[(i+1)%ans.size()] ){
                vis[(i+1)%ans.size()] = 1;
            }else{
                vis[i] = 1;
                cnt++;
            }
        }
    }
    printf("%d\n", m-cnt );
    for( lint i = 0;i < ans.size();i++ ){
        if( !vis[i] && ans[i] ){
            lint x = edge[ ans[i] ].first;
            lint y = edge[ans[i]].second;
            printf("%d %d\n",x,y);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],v[maxn],vis2[maxm],st[maxm],re[maxm];
void euler( lint x ){
    lint top = 0;
    st[++top] = x;
    re[0] = 0;
    v[x] = 1;
    while( top>0 ){
        x = st[top];
        lint cure  = he[x];
        while( cure && vis[cure] ) cure = ne[cure];
        if( cure ){
            lint y = ver[cure];v[y] = 1;
            vis[cure] = vis[cure^1] = 1;
            st[++top] = y;
            re[top] = id[cure];
            he[x] = ne[cure];
        }else{
            if( top !=  1  )ans.push_back( re[top] );
            top--;
        }
    }
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    lint totm = m;
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,++totm );add( i,0,totm );
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        ans.clear();
        if(v[i]) continue;
        euler(i);
        for (int j = 1; j < ans.size(); j += 2) {
            int now = ans[j];
            if(now > m) vis2[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(tmp> m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == ans.size()) Next = 0;
                tmp = ans[Next];
                if(tmp > m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                vis2[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res );
    for( lint i = 1;i <= m;i++ ){
        if( vis2[i] ) continue;
        printf("%d %d\n", edge[i].first,edge[i].second );
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const lint maxn = 2000001;
const lint maxm = 4000001;
lint tot,ver[maxm],he[maxn],ne[maxm],id[maxm];
pii edge[maxm];
void add( lint x,lint y,lint n ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    id[tot] = n;
}
vector<lint> ans;
lint vis[maxm],v[maxn],vis2[maxm],st[maxm],re[maxm];
void euler( lint x ){
    lint top = 0;
    st[++top] = x;
    re[0] = 0;
    //v[x] = 1;
    while( top>0 ){
        x = st[top];
        lint cure  = he[x];
        while( cure && vis[cure] ) cure = ne[cure];
        if( cure ){
            lint y = ver[cure];
            vis[cure] = vis[cure^1] = 1;
            st[++top] = y;
            re[top] = id[cure];
        }else{
            if( top !=  1  )ans.push_back( re[top] );
            top--;
        }
    }
}
vector<lint> res;
lint du[maxm];
int main(){
    lint n,m;
    scanf("%d%d",&n,&m);
    tot = 1;
    for( lint x,y,i = 1;i <= m;i++ ){
        scanf("%d%d",&x,&y);
        add( x,y,i );
        add( y,x,i );
        du[x]++;du[y]++;
        edge[i].first = x;
        edge[i].second = y;
    }
    lint totm = m;
    for( lint i = 1;i <= n;i++ ){
        if( du[i]&1 ){
            add( 0,i,++totm );add( i,0,totm );
        }
    }
    int res = m;
    for (int i = 0; i <= n; i++) {
        ans.clear();
        euler(i);
        for (int j = 1; j < ans.size(); j += 2) {
            int now = ans[j];
            if(now > m) vis2[now] = 1;
            else {
                int tmp = ans[j - 1];
                if(tmp> m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                int Next = j + 1;
                if(j == ans.size()) Next = 0;
                tmp = ans[Next];
                if(tmp > m && vis2[tmp] == 0) {
                    vis2[tmp] = 1;
                    continue;
                }
                vis2[now] = 1;
                res--;
            }
        }
    }
    printf("%d\n", res );
    for( lint i = 1;i <= m;i++ ){
        if( vis2[i] ) continue;
        printf("%d %d\n", edge[i].first,edge[i].second );
    }
    return 0;
}