/*
Author: QAQ-Automaton
LANG: C++
PROG: E.cpp
Mail: cnyalilk@vip.qq.com
*/
#include<bits/stdc++.h>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define DEBUG printf("Passing [%s] in LINE %lld\n",__FUNCTION__,__LINE__)
#define Debug debug("Passing [%s] in LINE %lld\n",__FUNCTION__,__LINE__)
#define all(x) x.begin(),x.end()
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
#define inf 0x3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f
const double eps=1e-8;
const double pi=acos(-1.0);
template<class T>ll chkmin(T &a,T b){return a>b?a=b,1:0;}
template<class T>ll chkmax(T &a,T b){return a<b?a=b,1:0;}
template<class T>T sqr(T a){return a*a;}
template<class T>T mmin(T a,T b){return a<b?a:b;}
template<class T>T mmax(T a,T b){return a>b?a:b;}
template<class T>T aabs(T a){return a<0?-a:a;}
template<class T>ll dcmp(T a,T b){return a>b;}
template<ll *a>ll cmp_a(ll x,ll y){return a[x]<a[y];}
#define min mmin
#define max mmax
#define abs aabs
namespace io {
	const ll SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; ll f, qr;
	// getchar
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	// prll the remaining part
	inline void flush () {
		fwrite (obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	// putchar
	inline void putc (char x) {
		*oS ++ = x;
		if (oS == oT) flush ();
	}
	// input a signed lleger
	inline bool read (signed &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;else if(c==EOF)return 0;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
		return 1;
	}

	inline bool read (long long &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;else if(c==EOF)return 0;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
		return 1;
	}
	inline bool read (char &x) {
		x=gc();
		return x!=EOF;
	}
	inline bool read(char *x){
		while((*x=gc())=='\n' || *x==' '||*x=='\r')if(*x==EOF)return 0;
		while(!(*x=='\n'||*x==' '||*x=='\r'))*(++x)=gc();
		*x=0;
		return 1;
	}
	template<typename A,typename ...B>
	inline bool read(A &x,B &...y){
		return read(x)&&read(y...);
	}
	// prll a signed lleger
	inline bool write (signed x) {
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
		return 0;
	}

	inline bool write (long long x) {
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
		return 0;
	}
	inline bool write (char x) {
		putc(x);
		return 0;
	}
	inline bool write(const char *x){
		while(*x){putc(*x);++x;}
		return 0;
	}
	inline bool write(char *x){
		while(*x){putc(*x);++x;}
		return 0;
	}
	template<typename A,typename ...B>
	inline bool write(A x,B ...y){
		return write(x)||write(y...);
	}
	//no need to call flush at the end manually!
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: read;
using io :: putc;
using io :: write;
ll cnt,m,tp,x,y,s,d;
pii stk[300005];
ll top;
void init(){
	s=d=0;
	top=1;
	stk[top]=make_pair(0,0);
}
void add1(){
	pii nw=make_pair(cnt,-s-d*cnt);
	cnt+=x;
	if(stk[top].y+d*stk[top].x+s==0)return;
	while(top>1 && (nw.y-stk[top].y)*1./(nw.x-stk[top].x)<=(nw.y-stk[top-1].y)*1./(nw.x-stk[top-1].x))--top;
	stk[++top]=nw;
}
void add2(){
	s+=x;d+=y;
	while(top>1 && (stk[top].y-stk[top-1].y)*1./(stk[top].x-stk[top-1].x)>=-d)--top;
}
int main(){
#ifdef QAQAutoMaton
	freopen("E.in","r",stdin);
	freopen("E.out","w",stdout);
#endif
	read(cnt,m);
	init();
	for(;m;--m){
		read(tp,x);
		if(tp==1){
			cnt+=x;
			init();
		}
		else if(tp==2){
			add1();
		}
		else{
			read(y);
			add2();
		}
		write(stk[top].x+1,' ',stk[top].y+s+stk[top].x*d,'\n');
	}
	return 0;
}


#include<stdio.h>
#define it register int
#define ct const int
#define il inline
const int N=1050005;
typedef long long ll;
const double eps=1e-8;
struct ky{
	ll x,y;
	ky(const ll a=0,const ll b=0){x=a,y=b;}
	ky operator - (const ky&p)const{return ky(x-p.x,y-p.y);}
	double operator * (const ky &p)const{return 1.0*x*p.y-1.0*y*p.x;}
}s[N];
int top,Q;
ll n,k,b;
il ll cal(const ky p){return k*p.x+b+p.y;}
int main(){
	scanf("%lld%d",&n,&Q);register ky now;it x,op;
	s[top=1]=ky(0,0);
	while(Q--){
		scanf("%d",&op);
		if(op==1) s[top=1]=ky(0,0),scanf("%d",&x),n+=x,k=b=0;
		if(op==2){
			now=ky(n,-(n*k+b)),scanf("%d",&x),n+=x;
			while(top>1&&(now-s[top-1])*(s[top]-s[top-1])>-eps) --top;
			s[++top]=now;
		}
		if(op==3) scanf("%d",&x),b+=x,scanf("%d",&x),k+=x;
		while(top>1&&cal(s[top])>=cal(s[top-1])) --top;
		printf("%lld %lld\n",s[top].x+1,cal(s[top]));
	}
	return 0;
}


#include <stdio.h>
const int N=3e5;
int x[N];
long long y[N];
int main()
{
	int n, m, cnt=0;
	long long bsum=0, ssum=0;
	scanf("%d%d", &n, &m);
	while(m--) {
		int op;
		scanf("%d", &op);
		if(op==1) {
			int k;
			scanf("%d", &k);
			cnt=0;
			n+=k;
			bsum=ssum=0;
		}
		if(op==2) {
			int k;
			scanf("%d", &k);
			while(cnt>=1 && (long double)(y[cnt]-y[cnt-1])*(n-x[cnt])>=(long double)(x[cnt]-x[cnt-1])*(-ssum*n-bsum-y[cnt])) --cnt;
			x[++cnt]=n;
			y[cnt]=-ssum*n-bsum;
			n+=k;
		}
		if(op==3) {
			int b, s;
			scanf("%d%d", &b, &s);
			bsum+=b;
			ssum+=s;
		}
		while(cnt && ssum*x[cnt-1]+y[cnt-1]<=ssum*x[cnt]+y[cnt]) --cnt;
		printf("%d %I64d\n", x[cnt]+1, ssum*x[cnt]+y[cnt]+bsum);
	}
	return 0;
}


#include <stdio.h>
const int N=3e5;
int x[N];
long long y[N];
int main()
{
	int n, m, cnt=0;
	long long bsum=0, ssum=0;
	scanf("%d%d", &n, &m);
	while(m--) {
		int op;
		scanf("%d", &op);
		if(op==1) {
			int k;
			scanf("%d", &k);
			cnt=0;
			n+=k;
			bsum=ssum=0;
		}
		if(op==2) {
			int k;
			scanf("%d", &k);
			while(cnt && bsum*x[cnt]+y[cnt]+ssum>=0) --cnt;
			x[++cnt]=n;
			y[cnt]=-bsum*n-ssum;
			n+=k;
		}
		if(op==3) {
			int b, s;
			scanf("%d%d", &s, &b);
			bsum+=b;
			ssum+=s;
			while(cnt && y[cnt-1]-y[cnt]<=bsum*(x[cnt]-x[cnt-1])) --cnt;
		}
		printf("%d %I64d\n", x[cnt]+1, bsum*x[cnt]+y[cnt]+ssum);
	}
	return 0;
}


#include <stdio.h>
const int N=3e5;
int x[N];
long long y[N];
int main()
{
	int n, m, cnt=0;
	long long bsum=0, ssum=0;
	scanf("%d%d", &n, &m);
	while(m--) {
		int op;
		scanf("%d", &op);
		if(op==1) {
			int k;
			scanf("%d", &k);
			cnt=0;
			n+=k;
			bsum=ssum=0;
		}
		if(op==2) {
			int k;
			scanf("%d", &k);
			while(cnt && bsum*x[cnt]+y[cnt]+ssum>0) --cnt;
			if(bsum*x[cnt]+y[cnt]+ssum) {
				x[++cnt]=n;
				y[cnt]=-bsum*n-ssum;
			}
			n+=k;
		}
		if(op==3) {
			int b, s;
			scanf("%d%d", &s, &b);
			bsum+=b;
			ssum+=s;
			while(cnt && y[cnt-1]-y[cnt]<=bsum*(x[cnt]-x[cnt-1])) --cnt;
		}
		printf("%d %I64d\n", x[cnt]+1, bsum*x[cnt]+y[cnt]+ssum);
	}
	return 0;
}


#include<iostream>
#include<utility>
using namespace std;
typedef long long LL;
int n,m,top;
LL h,t,B,S;
pair<LL,int>sta[300005];
inline LL get(pair<LL,int>x){return x.first+B+(x.second-1)*S;}
inline bool cross(pair<LL,int>a,pair<LL,int>b,pair<LL,int>c){
#define x first
#define y second
	a.x-=c.x,a.y-=c.y;
	b.x-=c.x,b.y-=c.y;
	return 1.*a.x/b.x>=1.*a.y/b.y;
#undef x
#undef y
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	h=0,t=n;
	sta[top=1]=make_pair(0,1);
	while(m--){
		int op;
		cin>>op;
		if(op==1){
			int k;
			cin>>k;
			top=1;
			B=S=0;
			h+=k;
			sta[1]=make_pair(0,1);
		}else
			if(op==2){
				int k;
				cin>>k;
				if(get(sta[top])>0){
					pair<LL,int>p=make_pair(-B-S*(h+t),h+t+1);
					while(top&&cross(p,sta[top],sta[top-1]))--top;
					sta[++top]=p;
				}
				t+=k;
			}else{
				int b,s;
				cin>>b>>s;
				B+=b,S+=s;
				while(top>1&&get(sta[top])>=get(sta[top-1]))--top;
			}
//		for(int i=1;i<=top;++i)
//			cout<<get(sta[i])<<' '<<sta[i].second<<';';
//		cout<<endl;
		cout<<sta[top].second<<' '<<get(sta[top])<<'\n';

	}
	return 0;
}


#include<iostream>
#include<utility>
using namespace std;
typedef long long LL;
int n,m,top;
LL h,t,B,S;
pair<LL,int>sta[300005];
inline LL get(pair<LL,int>x){return x.first+B+(x.second-1)*S;}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	h=0,t=n;
	sta[top=1]=make_pair(0,1);
	while(m--){
		int op;
		cin>>op;
		if(op==1){
			int k;
			cin>>k;
			top=1;
			B=S=0;
			h+=k;
			sta[1]=make_pair(0,1);
		}else
			if(op==2){
				int k;
				cin>>k;
				if(get(sta[top])>0)
					sta[++top]=make_pair(-B-S*(h+t),h+t+1);
				t+=k;
			}else{
				int b,s;
				cin>>b>>s;
				B+=b,S+=s;
				while(top>1&&get(sta[top])>=get(sta[top-1]))--top;
			}
		cout<<sta[top].second<<' '<<get(sta[top])<<'\n';

	}
	return 0;
}


#include <bits/stdc++.h>
#define maxn 300005
#define LL long long
using namespace std;
const double eps = 1e-8;
struct Point{
	LL x,y; Point(){}
	Point(LL x,LL y):x(x),y(y){}
	Point operator - (const Point &p)const{return {x-p.x,y-p.y};}
	double operator * (const Point &p)const{return (double)x*p.y-(double)y*p.x;}
}q[maxn],now;
int n,m,top;
LL k,b;
int main()
{
	scanf("%d%d",&n,&m);
	q[top=1]=Point(0,0);
	int op,x,y;
	while(m--){
		scanf("%d%d",&op,&x);
		switch(op){
			case 1:
				k=b=0,q[top=1]=Point(0,0),n+=x;break;
			case 2:
				now=Point(n,-(n*k+b)),n+=x;
				while(top>1&&(q[top]-q[top-1])*(now-q[top-1])<eps) top--;
				q[++top]=now;break;
			case 3:
				scanf("%d",&y),b+=x,k+=y;break;
		}
		now=Point(-1,k);
		while(top>1&&(q[top-1]-q[top])*now<eps) top--;
		printf("%I64d %I64d\n",q[top].x+1,q[top].x*k+b+q[top].y);
	}
}


#include <bits/stdc++.h>
#define maxn 300005
#define LL long long
using namespace std;
const double eps = 1e-8;
struct Point{
	LL x,y;
	Point operator - (const Point &p)const{return {x-p.x,y-p.y};}
	double operator * (const Point &p)const{return (double)x*p.y-(double)y*p.x;}
}q[maxn],now;
int n,m,top;
LL k,b;
int main()
{
	scanf("%d%d",&n,&m);
	q[top=1]={0,0};
	int op,x,y;
	while(m--){
		scanf("%d%d",&op,&x);
		switch(op){
			case 1:
				k=b=0,q[top=1]={0,0},n+=x;break;
			case 2:
				now={n,-(n*k+b)},n+=x;
				while(top>1&&(q[top]-q[top-1])*(now-q[top-1])<eps) top--;
				q[++top]=now;break;
			case 3:
				scanf("%d",&y),b+=x,k+=y;break;
		}
		now={-1,k};
		while(top>1&&(q[top-1]-q[top])*now<eps) top--;
		printf("%I64d %I64d\n",q[top].x+1,q[top].x*k+b+q[top].y);
	}
}


#include <bits/stdc++.h>
#define maxn 300005
#define LL long long
using namespace std;
const double eps = 1e-8;
struct Point{
	LL x,y;
	Point operator - (const Point &p)const{return {x-p.x,y-p.y};}
	double operator * (const Point &p)const{return (double)x*p.y-(double)y*p.x;}
}q[maxn],now;
int n,m,top;
LL k,b;
int main()
{
	scanf("%d%d",&n,&m);
	q[top=1]={0,0};
	int op,x,y;
	while(m--){
		scanf("%d%d",&op,&x);
		switch(op){
			case 1:
				k=b=0,q[top=1]={0,0},n+=x;break;
			case 2:
				now={n,-(n*k+b)},n+=x;
				while(top>1&&(q[top]-q[top-1])*(now-q[top-1])<eps) top--;
				q[++top]=now;break;
			case 3:
				scanf("%d",&y),b+=x,k+=y;break;
		}
		now={-1,k};
		while(top>1&&(q[top-1]-q[top])*now<eps) top--;
		printf("%d %I64d\n",q[top].x+1,q[top].x*k+b+q[top].y);
	}
}


#include <bits/stdc++.h>
#define maxn 300005
#define LL long long
using namespace std;
const double eps = 1e-8;
struct Point{
	LL x,y; Point(){}
	Point(LL x,LL y):x(x),y(y){}
	Point operator - (const Point &p)const{return {x-p.x,y-p.y};}
	double operator * (const Point &p)const{return (double)x*p.y-(double)y*p.x;}
}q[maxn],now;
int n,m,top;
LL k,b;
int main()
{
	scanf("%d%d",&n,&m);
	q[top=1]=Point(0,0);
	int op,x,y;
	while(m--){
		scanf("%d%d",&op,&x);
		switch(op){
			case 1:
				k=b=0,q[top=1]=Point(0,0),n+=x;break;
			case 2:
				now=Point(n,-(n*k+b)),n+=x;
				while(top>1&&(q[top]-q[top-1])*(now-q[top-1])<eps) top--;
				q[++top]=now;break;
			case 3:
				scanf("%d",&y),b+=x,k+=y;break;
		}
		now=Point(-1,k);
		while(top>1&&(q[top-1]-q[top])*now<eps) top--;
		printf("%d %I64d\n",q[top].x+1,q[top].x*k+b+q[top].y);
	}
}


#include "bits/stdc++.h"
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define ri register int
#define Max(x, y) (((x) > (y)) ? (x) : (y))
#define Min(x, y) (((x) < (y)) ? (x) : (y))
#define Abs(x) ((x) < 0 ? (-(x)) : (x))
#define int long long
const int maxn = 3e5 + 10;
inline int read()
{
    int f = 1, r = 0;
    char c = getchar();
    while (!isdigit(c)) {
        if (c == '-') {
            f = -1;
        }
        c = getchar();
    }
    while (isdigit(c)) {
        r = 10 * r + c - '0';
        c = getchar();
    }
    return f * r;
}
inline void write(int x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
inline void writesp(int x) { write(x), putchar(' '); }
inline void writeln(int x) { write(x), puts(""); }
int N, M, S, B, r;
struct Node {
    int pos, s, b;
} Q[maxn];
int calc(int a)
{
    return (Q[a].b + B) + Q[a].pos * (Q[a].s + S);
}
double slope(int a, int b)
{
    return 1.0 * (calc(b) - calc(a)) / (Q[a].pos - Q[b].pos);
}
signed main()
{
    N = read(), M = read();
    r = 1, Q[r].b = Q[r].pos = Q[r].s = 0;
    for (ri i = 1; i <= M; ++i) {
        int t = read();
        if (t == 1) {
            r = 1, Q[r].b = Q[r].pos = Q[r].s = 0, B = S = 0, N += read();
        } else if (t == 2) {
            Q[r + 1].b = -B, Q[r + 1].s = -S, Q[r + 1].pos = N;
            int now = r + 1;
            double a1 = slope(r - 1, r), a2 = slope(r, now);
            while (r > 1 && slope(r - 1, r) <= slope(r, now)) {
                r--;
            }
            ++r, Q[r].b = -B, Q[r].s = -S, Q[r].pos = N, N += read();
        } else {
            B += read(), S += read();
        }
        while (r > 1 && calc(r - 1) <= calc(r)) {
            --r;
        }
        writesp(Q[r].pos + 1), writeln(calc(r));
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#define int long long
#define double long double
#define M 1000005
int n,m,ml,mr,nowl,nowr,ans_id;
//int MAXN;
std::pair <int,long long> Q[M];
long long tB,tS,key,ans_val;
int read(){
	char c=getchar();int ans=0;
	while (c<'0'||c>'9') c=getchar();
	while (c>='0'&&c<='9') ans=ans*10+c-'0',c=getchar();
	return ans;
}
void Write(long long x){
	if (x<10) putchar(x^48);
	else Write(x/10),putchar((x%10)^48);
	return;
}
bool check(long long X1,long long Y1,long long X2,long long Y2){
	return (double)(X1)/Y1<(X2+0.0)/Y2;
}
void get_ansid(){
	while (ml<mr&&(Q[mr].second-Q[mr-1].second)>=-tS*(double)(Q[mr].first-Q[mr-1].first)) --mr;
	//for (register int i=ml;i<=mr;i++) printf("(%d %lld) ",Q[i].first,Q[i].second);printf("\n");
	ans_id=Q[mr].first,ans_val=Q[mr].second;return;
}
void modify1(int K){
	key+=K*tS,nowl-=K;std::pair <int,long long> now=std::make_pair(nowl,key-tB);
	//printf("now=(%d,%lld)\n",now.first,now.second);
	while (ml<mr&&check(Q[ml+1].second-Q[ml].second,Q[ml+1].first-Q[ml].first,Q[ml].second-now.second,Q[ml].first-now.first)) ml++;
	Q[--ml]=now;get_ansid();return;
}
void modify2(int K){
	nowr+=K;std::pair <int,long long> now=std::make_pair(nowr-K+1,-(nowr-K+1-nowl)*tS+key-tB);
	//printf("now=(%d,%lld)\n",now.first,now.second);
	while (ml<mr&&check(now.second-Q[mr].second,now.first-Q[mr].first,Q[mr].second-Q[mr-1].second,Q[mr].first-Q[mr-1].first)) mr--;
	Q[++mr]=now;get_ansid();return;
}
signed main(){
	//freopen("s.in","r",stdin);
	//freopen("s.out","w",stdout);
	n=read(),m=read(),nowl=0,nowr=n-1;
	Q[ml=mr=500000]=std::make_pair(0,0);
	for (register int _=1,opt,x,y;_<=m;_++){
		opt=read();
		if (opt==1) x=read(),modify1(x);
		if (opt==2) x=read(),modify2(x);
		if (opt==3) x=read(),y=read(),tB+=x,tS+=y,get_ansid();
		//MAXN=std::max(MAXN,mr-ml+1);
		Write(ans_id+1-nowl),putchar(' ');
		Write(ans_val+(ans_id-nowl)*tS+tB-key),putchar('\n');
	}
	//printf("%d",MAXN);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#define int long long
#define double long double
#define M 1000005
int n,m,ml,mr,nowl,nowr,ans_id;
//int MAXN;
std::pair <int,long long> Q[M];
long long tB,tS,key,ans_val;
int read(){
	char c=getchar();int ans=0;
	while (c<'0'||c>'9') c=getchar();
	while (c>='0'&&c<='9') ans=ans*10+c-'0',c=getchar();
	return ans;
}
void Write(long long x){
	if (x<10) putchar(x^48);
	else Write(x/10),putchar((x%10)^48);
	return;
}
bool check(long long X1,long long Y1,long long X2,long long Y2){
	return (double)(X1)/Y1<(X2+0.0)/Y2;
}
void get_ansid(){
	while (ml<mr&&(double)(Q[mr].second-Q[mr-1].second)/tS>=-(Q[mr].first-Q[mr-1].first)) --mr;
	//for (register int i=ml;i<=mr;i++) printf("(%d %lld) ",Q[i].first,Q[i].second);printf("\n");
	ans_id=Q[mr].first,ans_val=Q[mr].second;return;
}
void modify1(int K){
	key+=K*tS,nowl-=K;std::pair <int,long long> now=std::make_pair(nowl,key-tB);
	//printf("now=(%d,%lld)\n",now.first,now.second);
	while (ml<mr&&check(Q[ml+1].second-Q[ml].second,Q[ml+1].first-Q[ml].first,Q[ml].second-now.second,Q[ml].first-now.first)) ml++;
	Q[--ml]=now;get_ansid();return;
}
void modify2(int K){
	nowr+=K;std::pair <int,long long> now=std::make_pair(nowr-K+1,-(nowr-K+1-nowl)*tS+key-tB);
	//printf("now=(%d,%lld)\n",now.first,now.second);
	while (ml<mr&&check(now.second-Q[mr].second,now.first-Q[mr].first,Q[mr].second-Q[mr-1].second,Q[mr].first-Q[mr-1].first)) mr--;
	Q[++mr]=now;get_ansid();return;
}
signed main(){
	//freopen("s.in","r",stdin);
	//freopen("s.out","w",stdout);
	n=read(),m=read(),nowl=0,nowr=n-1;
	Q[ml=mr=500000]=std::make_pair(0,0);
	for (register int _=1,opt,x,y;_<=m;_++){
		opt=read();
		if (opt==1) x=read(),modify1(x);
		if (opt==2) x=read(),modify2(x);
		if (opt==3) x=read(),y=read(),tB+=x,tS+=y,get_ansid();
		//MAXN=std::max(MAXN,mr-ml+1);
		Write(ans_id+1-nowl),putchar(' ');
		Write(ans_val+(ans_id-nowl)*tS+tB-key),putchar('\n');
	}
	//printf("%d",MAXN);
	return 0;
}


#include <bits/stdc++.h>

// 20030830

inline int read()
{
	int res = 0; bool bo = 0; char c;
	while (((c = getchar()) < '0' || c > '9') && c != '-');
	if (c == '-') bo = 1; else res = c - 48;
	while ((c = getchar()) >= '0' && c <= '9')
		res = (res << 3) + (res << 1) + (c - 48);
	return bo ? ~res + 1 : res;
}

typedef long long ll;

const int N = 3e5 + 5;

int n, m, stk[N], top;
ll rsid, suml, sums, sumb, X[N], Y[N], offset, firs;
bool le0 = 1, ri0 = 1;

bool check(int i, int j, int k)
{
	return 1.0 * (Y[i] - Y[j]) / (X[i] - X[j]) <=
		1.0 * (Y[j] - Y[k]) / (X[j] - X[k]);
}

ll calc(int i)
{
	return Y[i] - X[i] * sums;
}

int main()
{
	int op, x, y;
	rsid = read(); m = read();
	while (m--)
	{
		op = read(); x = read();
		if (op == 1) offset += x, le0 = 1;
		else if (op == 2) rsid += x, ri0 = 1;
		else
		{
			if (le0) firs = x;
			else firs += x;
			y = read();
			if (ri0)
			{
				X[++n] = suml; Y[n] = suml * sums + sumb;
				while (top > 1 && check(stk[top - 1], stk[top], n)) top--;
				stk[++top] = n;
				suml = rsid; sums += y; sumb += offset * y + x;
				while (top > 1 && calc(stk[top]) <= calc(stk[top - 1])) top--;
			}
			else
			{
				sums += y; sumb += offset * y + x;
				while (top > 1 && calc(stk[top]) <= calc(stk[top - 1])) top--;
			}
			le0 = ri0 = 0;
		}
		if (le0) {puts("1 0"); continue;}
		if (ri0) {printf("%lld 0\n", offset + suml + 1); continue;}
		ll pos = offset + X[stk[top]] + 1, val = sumb - calc(stk[top]);
		if (firs <= val) pos = 1, val = firs;
		printf("%lld %lld\n", pos, val);
	}
	return 0;
}


#include <bits/stdc++.h>

// 20030830

inline int read()
{
	int res = 0; bool bo = 0; char c;
	while (((c = getchar()) < '0' || c > '9') && c != '-');
	if (c == '-') bo = 1; else res = c - 48;
	while ((c = getchar()) >= '0' && c <= '9')
		res = (res << 3) + (res << 1) + (c - 48);
	return bo ? ~res + 1 : res;
}

typedef long long ll;

const int N = 3e5 + 5;

int n, m, stk[N], top;
ll rsid, suml, sums, sumb, X[N], Y[N], offset;
bool le0 = 1, ri0 = 1;

bool check(int i, int j, int k)
{
	return 1.0 * (Y[i] - Y[j]) / (X[i] - X[j]) <=
		1.0 * (Y[j] - Y[k]) / (X[j] - X[k]);
}

ll calc(int i)
{
	return Y[i] - X[i] * sums;
}

int main()
{
	int op, x, y;
	rsid = read(); m = read();
	while (m--)
	{
		op = read(); x = read();
		if (op == 1) offset += x, le0 = 1;
		else if (op == 2) rsid += x, ri0 = 1;
		else
		{
			y = read(); le0 = ri0 = 0;
			X[++n] = suml - 1; Y[n] = (suml - 1) * sums + sumb;
			while (top > 1 && check(stk[top - 1], stk[top], n)) top--;
			stk[++top] = n;
			suml = rsid; sums += y; sumb += offset * y + x;
			while (top > 1 && calc(stk[top]) <= calc(stk[top - 1])) top--;
		}
		if (le0) {puts("1 0"); continue;}
		if (ri0) {printf("%lld 0\n", offset + suml + 1); continue;}
		printf("%lld %lld\n", offset + X[stk[top]] + 1, sumb - calc(stk[top]));
	}
	return 0;
}


#include <bits/stdc++.h>

// 20030830

inline int read()
{
	int res = 0; bool bo = 0; char c;
	while (((c = getchar()) < '0' || c > '9') && c != '-');
	if (c == '-') bo = 1; else res = c - 48;
	while ((c = getchar()) >= '0' && c <= '9')
		res = (res << 3) + (res << 1) + (c - 48);
	return bo ? ~res + 1 : res;
}

typedef long long ll;

const int N = 3e5 + 5;

int n, m, stk[N], top;
ll rsid, suml, sums, sumb, X[N], Y[N], offset, firs;
bool le0 = 1, ri0 = 1;

bool check(int i, int j, int k)
{
	return 1.0 * (Y[i] - Y[j]) / (X[i] - X[j]) <=
		1.0 * (Y[j] - Y[k]) / (X[j] - X[k]);
}

ll calc(int i)
{
	return Y[i] - X[i] * sums;
}

int main()
{
	int op, x, y;
	rsid = read(); m = read();
	while (m--)
	{
		op = read(); x = read();
		if (op == 1) offset += x, le0 = 1;
		else if (op == 2) rsid += x, ri0 = 1;
		else
		{
			if (le0) firs = x;
			else firs += x;
			y = read();
			if (ri0)
			{
				X[++n] = suml; Y[n] = suml * sums + sumb;
				while (top > 1 && check(stk[top - 1], stk[top], n)) top--;
				stk[++top] = n;
				suml = rsid; sums += y; sumb += offset * y + x;
				while (top > 1 && calc(stk[top]) <= calc(stk[top - 1])) top--;
			}
			else sums += y, sumb += offset * y + x;
			le0 = ri0 = 0;
		}
		if (le0) {puts("1 0"); continue;}
		if (ri0) {printf("%lld 0\n", offset + suml + 1); continue;}
		ll pos = offset + X[stk[top]] + 1, val = sumb - calc(stk[top]);
		if (firs <= val) pos = 1, val = firs;
		printf("%lld %lld\n", pos, val);
	}
	return 0;
}


#include <bits/stdc++.h>

// 20030830

inline int read()
{
	int res = 0; bool bo = 0; char c;
	while (((c = getchar()) < '0' || c > '9') && c != '-');
	if (c == '-') bo = 1; else res = c - 48;
	while ((c = getchar()) >= '0' && c <= '9')
		res = (res << 3) + (res << 1) + (c - 48);
	return bo ? ~res + 1 : res;
}

typedef long long ll;

const int N = 3e5 + 5;

int n, m, stk[N], top;
ll rsid, suml, sums, sumb, X[N], Y[N], offset, firs;
bool le0 = 1, ri0 = 1;

bool check(int i, int j, int k)
{
	return 1.0 * (Y[i] - Y[j]) / (X[i] - X[j]) <=
		1.0 * (Y[j] - Y[k]) / (X[j] - X[k]);
}

ll calc(int i)
{
	return Y[i] - X[i] * sums;
}

int main()
{
	int op, x, y;
	rsid = read(); m = read();
	while (m--)
	{
		op = read(); x = read();
		if (op == 1) offset += x, le0 = 1;
		else if (op == 2) rsid += x, ri0 = 1;
		else
		{
			if (le0) firs = x;
			else firs += x;
			y = read();
			if (ri0)
			{
				X[++n] = suml + 1; Y[n] = (suml + 1) * sums + sumb;
				while (top > 1 && check(stk[top - 1], stk[top], n)) top--;
				stk[++top] = n;
				suml = rsid; sums += y; sumb += offset * y + x;
				while (top > 1 && calc(stk[top]) <= calc(stk[top - 1])) top--;
			}
			else sums += y, sumb += offset * y + x;
			le0 = ri0 = 0;
		}
		if (le0) {puts("1 0"); continue;}
		if (ri0) {printf("%lld 0\n", offset + suml + 1); continue;}
		ll pos = offset + X[stk[top]] + 1, val = sumb - calc(stk[top]);
		if (firs <= val) pos = 1, val = firs;
		printf("%lld %lld\n", pos, val);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int t1,t2;

// n = position of free spot
// offset = add this to the position to get the real position
int n,m,offset;

// use a map
std::map<int,long long> mm;
std::set<pair<long long,int>> gone;
std::map<int,long long>::iterator it,it2;

pair<long long,int> getval(std::map<int,long long>::iterator it)
{
    it2=it;
    --it2;
    long long rise=it2->second-it->second;
    int run=it->first-it2->first;
    //printf("(%I64d %d)\n",(rise+run-1)/run,it->first);
    return {(rise+run-1)/run,it->first};    // numerator cannot be negative :(
}

long long bb,slant;

int main()
{
    #ifdef NOT_DMOJ
    freopen("data.txt","r",stdin);
    #endif // NOT_DMOJ
    scanf("%d%d",&n,&m);
    mm[0]=0;
    offset=1;
    while (m--) {
        scanf("%d",&t1);
        if (t1==1) {
            scanf("%d",&t1);
            mm.clear();
            mm[0]=0;
            gone.clear();
            bb=slant=0;
            n+=t1;
            offset=1;
        }
        else if (t1==2) {
            scanf("%d",&t1);
            mm[n]=-bb-slant*n;
            gone.insert(getval(mm.lower_bound(n)));
            n+=t1;
        }
        else {
            scanf("%d%d",&t1,&t2);
            bb+=t1;
            slant+=t2;
        }
        while (!gone.empty() && slant>=gone.begin()->first) {
            t1=gone.begin()->second;
            it=mm.lower_bound(t1);
            gone.erase(getval(it));
            ++it;
            if (it!=mm.end()) {
                gone.erase(getval(it));
                mm.erase(t1);
                it=mm.lower_bound(t1);
                gone.insert(getval(it));
            }
            else {
                mm.erase(t1);
            }
        }
        // answer query
        it=mm.end();
        --it;
        printf("%d %I64d\n",it->first+offset,it->second+bb+slant*it->first);
    }
}


#include <bits/stdc++.h>
using namespace std;

int t1,t2;

// n = position of free spot
// offset = add this to the position to get the real position
int n,m,offset;

// use a map
std::map<int,long long> mm;
std::set<pair<long long,int>> gone;
std::map<int,long long>::iterator it,it2;

pair<long long,int> getval(std::map<int,long long>::iterator it)
{
    it2=it;
    --it2;
    long long rise=it2->second-it->second;
    int run=it->first-it2->first;
    //printf("(%I64d %d)\n",(rise+run-1)/run,it->first);
    return {(rise+run-1)/run,it->first};    // numerator cannot be negative :(
}

long long bb,slant;

int main()
{
    #ifdef NOT_DMOJ
    freopen("data.txt","r",stdin);
    #endif // NOT_DMOJ
    scanf("%d%d",&n,&m);
    mm[0]=0;
    offset=1;
    while (m--) {
        scanf("%d",&t1);
        if (t1==1) {
            scanf("%d",&t1);
            mm.clear();
            mm[0]=0;
            gone.clear();
            n+=t1;
            offset=1;
        }
        else if (t1==2) {
            scanf("%d",&t1);
            mm[n]=-bb-slant*n;
            gone.insert(getval(mm.lower_bound(n)));
            n+=t1;
        }
        else {
            scanf("%d%d",&t1,&t2);
            bb+=t1;
            slant+=t2;
        }
        while (!gone.empty() && slant>=gone.begin()->first) {
            t1=gone.begin()->second;
            it=mm.lower_bound(t1);
            gone.erase(getval(it));
            ++it;
            if (it!=mm.end()) {
                gone.erase(getval(it));
                mm.erase(t1);
                it=mm.lower_bound(t1);
                gone.insert(getval(it));
            }
            else {
                mm.erase(t1);
            }
        }
        // answer query
        it=mm.end();
        --it;
        printf("%d %I64d\n",it->first+offset,it->second+bb+slant*it->first);
    }
}


#include <bits/stdc++.h>
#define ll long long
#define res register int
#define int ll
#define inf 0x3f3f3f3f
#define eps 1e-10
#define N 300005
using namespace std;
int n, m, k, b, top;
inline int read(){
    res w = 0, X = 0; register char ch = 0;
    while(!isdigit(ch)){w |= ch == '-'; ch = getchar();}
    while(isdigit(ch)){X = (X << 1) + (X << 3) + (ch ^ 48); ch = getchar();}
    return w ? -X : X;
}
struct Point{
	int x, y;
	Point():x(0), y(0){};
	Point(int x0, int y0):x(x0), y(y0){};
	inline Point operator - (const Point &b) const{
	  return Point(x - b.x, y - b.y);
	}
	inline int operator * (const Point &b) const{
	  return x * b.y - y * b.x;
	}
}st[N];
inline int check(Point P){
	return P.x * k + b + P.y;
}
signed main(){
	n = read();
	st[top = 1] = Point();
	for(m = read(); m; m--){
		res op = read();
		if(op == 1){
			n += read(), k = 0, b = 0;
			st[top = 1] = Point();
		}
		else if(op == 2){
			Point NP = Point(n, -n * k - b);
			while(top > 1 && (NP - st[top - 1]) * (st[top] - st[top - 1]) > -eps) top--;
			st[++top] = NP;
			n += read();
		}
		else{
			b += read(), k += read();
		}
		while(top > 1 && check(st[top - 1]) <= check(st[top]))
		  top--;
		printf("%lld %lld\n", st[top].x + 1, check(st[top]));
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define res register int
#define int ll
#define inf 0x3f3f3f3f
#define eps 1e-10
#define N 300005
using namespace std;
int n, m, k, b, top;
inline int read(){
    res w = 0, X = 0; register char ch = 0;
    while(!isdigit(ch)){w |= ch == '-'; ch = getchar();}
    while(isdigit(ch)){X = (X << 1) + (X << 3) + (ch ^ 48); ch = getchar();}
    return w ? -X : X;
}
struct Point{
	int x, y;
	Point():x(0), y(0){};
	Point(int x0, int y0):x(x0), y(y0){};
	inline Point operator - (const Point &b) const{
	  return Point(x - b.x, y - b.y);
	}
}st[N];
inline int check(Point P){
	return P.x * k + b + P.y;
}
signed main(){
	n = read();
	st[top = 1] = Point();
	for(m = read(); m; m--){
		res op = read();
		if(op == 1){
			n += read(), k = 0, b = 0;
			st[top = 1] = Point();
		}
		else if(op == 2){
			Point NP = Point(n, -n * k - b);
			while(top > 1 && (double) 1.0 * (NP.y - st[top - 1].y) / (NP.x - st[top - 1].y) <= (double) 1.0 * (st[top].y - st[top - 1].y) / (st[top].x - st[top - 1].x) + eps) top--;
			st[++top] = NP;
			n += read();
		}
		else{
			b += read(), k += read();
		}
		while(top > 1 && check(st[top - 1]) <= check(st[top]))
		  top--;
		printf("%lld %lld\n", st[top].x + 1, check(st[top]));
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define res register int
#define int ll
#define inf 0x3f3f3f3f
#define eps 1e-10
#define N 300005
using namespace std;
int n, m, k, b, top;
inline int read(){
    res w = 0, X = 0; register char ch = 0;
    while(!isdigit(ch)){w |= ch == '-'; ch = getchar();}
    while(isdigit(ch)){X = (X << 1) + (X << 3) + (ch ^ 48); ch = getchar();}
    return w ? -X : X;
}
struct Point{
	int x, y;
	Point():x(0), y(0){};
	Point(int x0, int y0):x(x0), y(y0){};
	inline Point operator - (const Point &b) const{
	  return Point(x - b.x, y - b.y);
	}
}st[N];
inline int check(Point P){
	return P.x * k + b + P.y;
}
signed main(){
	n = read();
	st[top = 1] = Point();
	for(m = read(); m; m--){
		res op = read();
		if(op == 1){
			n += read(), k = 0, b = 0;
			st[top = 1] = Point();
		}
		else if(op == 2){
			Point NP = Point(n, -n * k - b);
			while(top > 1 && (double) 1.0 * (NP.y - st[top - 1].y) / (NP.x - st[top - 1].x) <= (double) 1.0 * (st[top].y - st[top - 1].y) / (st[top].x - st[top - 1].x) + eps) top--;
			st[++top] = NP;
			n += read();
		}
		else{
			b += read(), k += read();
		}
		while(top > 1 && check(st[top - 1]) <= check(st[top]))
		  top--;
		printf("%lld %lld\n", st[top].x + 1, check(st[top]));
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define res register int
#define int ll
#define inf 0x3f3f3f3f
#define eps 1e-10
#define N 300005
using namespace std;
int n, m, k, b, top;
inline int read(){
    res w = 0, X = 0; register char ch = 0;
    while(!isdigit(ch)){w |= ch == '-'; ch = getchar();}
    while(isdigit(ch)){X = (X << 1) + (X << 3) + (ch ^ 48); ch = getchar();}
    return w ? -X : X;
}
struct Point{
	int x, y;
	Point():x(0), y(0){};
	Point(int x0, int y0):x(x0), y(y0){};
	inline Point operator - (const Point &b) const{
	  return Point(x - b.x, y - b.y);
	}
}st[N];
inline int check(Point P){
	return P.x * k + b + P.y;
}
signed main(){
	n = read();
	st[top = 1] = Point();
	for(m = read(); m; m--){
		res op = read();
		if(op == 1){
			n += read(), k = 0, b = 0;
			st[top = 1] = Point();
		}
		else if(op == 2){
			Point NP = Point(n, -n * k - b);
			while(top > 1 && (double) 1.0 * (NP.y - st[top - 1].y) / (NP.x - st[top - 1].x) <= (double) 1.0 * (st[top].y - st[top - 1].y) / (st[top].x - st[top - 1].x)) top--;
			st[++top] = NP;
			n += read();
		}
		else{
			b += read(), k += read();
		}
		while(top > 1 && check(st[top - 1]) <= check(st[top]))
		  top--;
		printf("%lld %lld\n", st[top].x + 1, check(st[top]));
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define PB push_back
typedef long long LL;
const LL P = 1e9+7;
const int INF = 1e9;
const int N = 3e5+5;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct dat{
	LL k,b;
}S[N];
int m, t, r;
LL n, k, b, x, y;

double getk(dat a,dat b){return 1.0*(b.b-a.b)/(b.k-a.k);}
LL calc(dat a){return (a.k-1) * k + b + a.b;}

int main(){
	//freopen("test.in","r",stdin);
	scanf("%lld%d",&n,&m);
	S[r = 1] = {1, 0};

	rep(i,1,m){
		scanf("%d",&t);
		if(t==1){
			scanf("%lld",&x);
			n += x;
			k = b = 0;
			S[r = 1] = {1,0};
		}else if(t==2){
			scanf("%lld",&x);
			dat a = {n+1,-calc({n+1,0})};
			while(r>1 && getk(S[r],a) < getk(S[r-1],S[r])) --r;
			S[++r] = a;
			n += x;
		}else{
			scanf("%lld%lld",&x,&y);
			b += x, k += y;
		}

		while(r>1 && calc(S[r])>=calc(S[r-1]) ) --r;
		printf("%lld %lld\n",S[r].k,calc(S[r]));
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair <ll, int> pii;

#define N 300010

ll a[N], d[N], c[N], L, B, S;
int prv[N], nxt[N], cnt;
set <pii> s;

void fix() {
    while(!s.empty()) {
        pii P = *s.begin();
        if(P.first > S) break;
        int i = P.second;
        s.erase(s.begin());
        if(i == cnt) {
            cnt = prv[cnt];
            continue;
        }
        int l = prv[i], r = nxt[i];
        s.erase(pii(c[r], r));
        c[r] = (a[l] - a[r] + d[r] - d[l] - 1) / (d[r] - d[l]);
        s.insert(pii(c[r], r));
        nxt[l] = r, prv[r] = l;
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    L = n, B = 0, S = 0;
    a[1] = 0, d[1] = 0;
    cnt = 1;
    while(m --) {
        int type, x, y;
        scanf("%d", &type);
        if(type == 1) {
            scanf("%d", &x);
            L += x;
            cnt = 1;
            a[1] = -B, d[1] = 0;
            s.clear();
        }
        if(type == 2) {
            scanf("%d", &x);
            nxt[cnt] = cnt+1;
            prv[cnt+1] = cnt;
            cnt ++;
            a[cnt] = -B-L*S, d[cnt] = L;
            c[cnt] = (a[cnt-1] - a[cnt] + d[cnt] - d[cnt-1] - 1) / (d[cnt] - d[cnt-1]);
            s.insert(pii(c[cnt], cnt));
            L += x;
        }
        if(type == 3) {
            scanf("%d%d", &x, &y);
            B += x, S += y;
        }
        fix();
        printf("%I64d %I64d\n", d[cnt]+1, B+a[cnt]+d[cnt]*S);
    }
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair <ll, int> pii;

#define N 300010

ll a[N], d[N], c[N], L, B, S;
int prv[N], nxt[N], cnt;
set <pii> s;

void fix(int x, int y) {
    B += x;
    while(!s.empty()) {
        pii P = *s.begin();
        if(P.first > S + y) break;
        int i = P.second;
        s.erase(s.begin());
        if(i == cnt) {
            cnt = prv[cnt];
            continue;
        }
        int l = prv[i], r = nxt[i];
        s.erase(pii(c[r], r));
        c[r] = (a[l] - a[r] + d[r] - d[l] - 1) / (d[r] - d[l]);
        s.insert(pii(c[r], r));
        nxt[l] = r, prv[r] = l;
    }
    S += y;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    L = n, B = 0, S = 0;
    a[1] = 0, d[1] = 0;
    cnt = 1;
    while(m --) {
        int type, x, y;
        scanf("%d", &type);
        if(type == 1) {
            scanf("%d", &x);
            L += x;
            cnt = 1;
            a[1] = -B, d[1] = 0;
            s.clear();
        }
        if(type == 2) {
            scanf("%d", &x);
            nxt[cnt] = cnt+1;
            prv[cnt+1] = cnt;
            cnt ++;
            a[cnt] = -B-L*S, d[cnt] = L;
            c[cnt] = (a[cnt-1] - a[cnt] + d[cnt] - d[cnt-1] - 1) / (d[cnt] - d[cnt-1]);
            s.insert(pii(c[cnt], cnt));
            L += x;
            fix(0, 0);
        }
        if(type == 3) {
            scanf("%d%d", &x, &y);
            fix(x, y);
        }
        printf("%I64d %I64d\n", d[cnt]+1, B+a[cnt]+d[cnt]*S);
    }
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair <ll, int> pii;

#define N 300010

ll a[N], d[N], c[N];
int prv[N], nxt[N];
set <pii> s;

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    ll L = n, B = 0, S = 0;
    a[1] = 0, d[1] = 0;
    int k = 1;
    while(m --) {
        int type, x, y;
        scanf("%d", &type);
        if(type == 1) {
            scanf("%d", &x);
            L += x;
            k = 1;
            a[1] = -B, d[1] = 0;
            s.clear();
        }
        if(type == 2) {
            scanf("%d", &x);
            nxt[k] = k+1;
            prv[k+1] = k;
            k ++;
            a[k] = -B-L*S, d[k] = L;
            c[k] = (a[k-1] - a[k]) / (d[k] - d[k-1]);
            s.insert(pii(c[k], k));
            L += x;
        }
        if(type == 3) {
            scanf("%d%d", &x, &y);
            B += x;
            while(!s.empty()) {
                pii P = *s.begin();
                if(P.first > S + y) break;
                int i = P.second;
                s.erase(s.begin());
                if(i == k) {
                    k = prv[k];
                    continue;
                }
                int l = prv[i], r = nxt[i];
                s.erase(pii(c[r], r));
                c[r] = (a[l] - a[r]) / (d[r] - d[l]);
                s.insert(pii(c[r], r));
                nxt[l] = r, prv[r] = l;
            }
        }
        printf("%I64d %I64d\n", d[k]+1, B+a[k]+d[k]*S);
    }
}


#include <iostream>
#include <queue>
#include <set>
#include <cstring>
#include <stdio.h>
#include <unordered_map>
#include <cmath>
#include <iterator>
#include <algorithm>

using namespace std;

#define ll long long
#define pii pair<ll, ll>
#define mp make_pair

int read() {
    int f = 1;
    int res = 0;
    char ch;
    do {
        ch = getchar();
        if (ch == '-') f = -f;
    } while (ch < '0' || ch > '9');
    do {
        res = res * 10 + ch - '0';
        ch = getchar();
    } while (ch >= '0' && ch <= '9');
    return f == 1 ? res : -res;
}

const int N = 300010;
const ll INF = 2000000000000LL;
int n,m,D;
int mod = 1000000007;
char str[3][20];

ll q[N][3], sz;
ll bSum = 0;
ll sSum = 0;

void add(ll x, ll b, ll s) {
    q[sz][0] = x;
    q[sz][1] = b;
    q[sz][2] = s;
    sz++;
}

ll cross(pii &a, pii &b, pii &c) {
    ll x1 = b.first - a.first;
    ll y1 = b.second - a.second;
    ll x2 = c.first - a.first;
    ll y2 = c.second - a.second;

    return x1*y2 - x2*y1;
}

ll cal(ll x, ll b, ll s) {
    return bSum - b + (x - 1) * (sSum - s);
}

int main() {

//    freopen("/Users/mobike/Downloads/10.in", "r", stdin);
//    freopen("/Users/mobike/Downloads/10.out", "w", stdout);
    n = read();
    m = read();
    ll total = n;

    sz = 0;
    q[sz][0] = 1;
    q[sz][1] = bSum;
    q[sz++][2] = sSum;

    for (int i = 0; i < m; i++) {
        int o = read();
        n = read();
        if (o == 1) {
            total += n;
            printf("1 0\n");
            sz = 0;
            add(1, bSum, sSum);
        } else if (o == 2) {
            int last = sz - 1;
            if (q[last][1] != bSum) {
                pii cur = mp(total+1, 0);
                while (sz >= 2) {
                    pii a =  mp(q[sz - 1][0], cal(q[sz-1][0], q[sz-1][1], q[sz-1][2]));
                    pii b =  mp(q[sz - 2][0], cal(q[sz-2][0], q[sz-2][1], q[sz-2][2]));
                    ll tmp = cross(cur, a, b);
                    if (tmp >= 0) sz --;
                    else break;
                }
                add(total + 1, bSum, sSum);
                printf("%d 0\n", total + 1);
            } else {
                printf("%d 0\n", q[last][0]);
            }
            total += n;
        } else {
            ll s = read();
            bSum += n;
            sSum += s;

            while (sz >= 2) {
                ll y1 = cal(q[sz-1][0], q[sz-1][1], q[sz-1][2]);
                ll y2 = cal(q[sz-2][0], q[sz-2][1], q[sz-2][2]);
                if (y1 >= y2) {
                    sz--;
                    continue;
                }
                if (sz > 2) {
                    pii cur = mp(q[sz - 1][0], y1);
                    pii a = mp(q[sz-2][0], y2);
                    pii b = mp(q[sz-3][0], cal(q[sz-3][0], q[sz-3][1], q[sz-3][2]));
                    ll tmp = cross(cur, a, b);
                    if (tmp >= 0) sz --;
                    else break;
                } else {
                    break;
                }
            }
            printf("%I64d %I64d\n", q[sz-1][0], cal(q[sz-1][0], q[sz-1][1], q[sz-1][2]));
        }
    }
    return 0;
}


#include <iostream>
#include <queue>
#include <set>
#include <cstring>
#include <stdio.h>
#include <unordered_map>
#include <cmath>
#include <iterator>
#include <algorithm>

using namespace std;

#define ll long long
#define pii pair<ll, int>
#define mp make_pair

int read() {
    int f = 1;
    int res = 0;
    char ch;
    do {
        ch = getchar();
        if (ch == '-') f = -f;
    } while (ch < '0' || ch > '9');
    do {
        res = res * 10 + ch - '0';
        ch = getchar();
    } while (ch >= '0' && ch <= '9');
    return f == 1 ? res : -res;
}

const int N = 100010;
const ll INF = 2000000000000LL;
int n,m,D;
int mod = 1000000007;
char str[3][20];

int main() {

//    freopen("/Users/mobike/Downloads/10.in", "r", stdin);
//    freopen("/Users/mobike/Downloads/10.out", "w", stdout);
    n = read();
    m = read();
    vector<pii> cur;
    int total = n;
    cur.push_back(mp(0, 1));
    for (int i = 0; i < m; i++) {
        int o = read();
        n = read();
        if (o == 1) {
            total += n;
            printf("1 0\n");
            cur.clear();
            cur.push_back(mp(0, 1));
        } else if (o == 2) {
            int last = cur.size() - 1;
            if (cur[last].first > 0) {
                cur.push_back(mp(0, total + 1));
                printf("%d 0\n", total + 1);
            } else {
                printf("%d 0\n", cur[last].second);
            }
            total += n;
        } else {
            ll s = read();
            vector<pii> ncur;
            ncur.push_back(mp(cur[0].first += n + (cur[0].second - 1) * s, cur[0].second));
            for (int j = 1; j < cur.size(); j++) {
                ll tmp = cur[j].first += n + (cur[j].second - 1) * s;
                if (tmp < cur[j-1].first) {
                    ncur.push_back(mp(tmp, cur[j].second));
                }
            }
            cur.clear();
            cur = ncur;
            int last = cur.size() - 1;
            printf("%d %I64d\n", cur[last].second, cur[last].first);
        }
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <cassert>
#include <stdint.h>

int64_t TB,TS;

struct Point{
  int64_t x,y;
  Point(int64_t x,int64_t y):x(x),y(y){
  }
  struct Point operator-(struct Point p)const{
    return Point(x-p.x,y-p.y);
  }
  int64_t cross(struct Point p)const{
    return x*p.y-y*p.x;
  }
  int64_t eval(){
    return y+x*TS+TB;
  }
};

std::vector<struct Point> hull;
int64_t length=0;

void add(int64_t K){
  struct Point p(length,-TB-TS*length);
  while(hull.size()>=2&&(p-hull[hull.size()-2]).cross(hull.back()-hull[hull.size()-2])>0){
    hull.pop_back();
  }
  hull.push_back(p);
  length+=K;
}

void reduce(){
  while(hull.size()>1&&hull.back().eval()>=hull[hull.size()-2].eval()){
    hull.pop_back();
  }
}

int main(){
  hull.emplace_back(0,0);
  int64_t M;
  scanf("%I64d %I64d",&length,&M);
  while(M-->0){
    int64_t T;
    scanf("%I64d",&T);
    if(T==1){
      int64_t K;
      scanf("%I64d",&K);
      TB=TS=0;
      hull.clear();
      int64_t tmp=length;
      length-=tmp;
      add(K);
      length+=tmp;
    }else if(T==2){
      int64_t K;
      scanf("%I64d",&K);
      add(K);
    }else if(T==3){
      int64_t B,S;
      scanf("%I64d %I64d",&B,&S);
      TB+=B,TS+=S;
    }else{
      assert(0);
    }
    reduce();
    /*
    for(struct Point p:hull){
      printf("(%I64d, %I64d)\n",p.x,p.eval());
    }
    */
    printf("%I64d %I64d\n",hull.back().x+1,hull.back().eval());
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <cassert>
#include <stdint.h>

int64_t TB,TS;

struct Point{
  int64_t x,y;
  Point(int64_t x,int64_t y):x(x),y(y){
  }
  struct Point operator-(struct Point p)const{
    return Point(x-p.x,y-p.y);
  }
  long double cross(struct Point p)const{
    return (long double)x*p.y-(long double)y*p.x;
  }
  int64_t eval(){
    return y+(long double)x*TS+TB;
  }
};

std::vector<struct Point> hull;
int64_t length=0;

void add(int64_t K){
  struct Point p(length,-TB-(long double)TS*length);
  while(hull.size()>=2&&(p-hull[hull.size()-2]).cross(hull.back()-hull[hull.size()-2])>0){
    hull.pop_back();
  }
  hull.push_back(p);
  length+=K;
}

void reduce(){
  while(hull.size()>1&&hull.back().eval()>=hull[hull.size()-2].eval()){
    hull.pop_back();
  }
}

int main(){
  hull.emplace_back(0,0);
  int64_t M;
  scanf("%I64d %I64d",&length,&M);
  while(M-->0){
    int64_t T;
    scanf("%I64d",&T);
    if(T==1){
      int64_t K;
      scanf("%I64d",&K);
      TB=TS=0;
      hull.clear();
      int64_t tmp=length;
      length-=tmp;
      add(K);
      length+=tmp;
    }else if(T==2){
      int64_t K;
      scanf("%I64d",&K);
      add(K);
    }else if(T==3){
      int64_t B,S;
      scanf("%I64d %I64d",&B,&S);
      TB+=B,TS+=S;
    }else{
      assert(0);
    }
    reduce();
    /*
    for(struct Point p:hull){
      printf("(%I64d, %I64d)\n",p.x,p.eval());
    }
    */
    printf("%I64d %I64d\n",hull.back().x+1,hull.back().eval());
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <cassert>
#include <stdint.h>

int64_t TB,TS;

struct Point{
  int64_t x,y;
  Point(int64_t x,int64_t y):x(x),y(y){
  }
  struct Point operator-(struct Point p)const{
    return Point(x-p.x,y-p.y);
  }
  int64_t cross(struct Point p)const{
    return x*p.y-y*p.x;
  }
  int64_t eval(){
    return y+x*TS+TB;
  }
};

std::vector<struct Point> hull;
int64_t length=0;

int64_t add(int64_t K){
  struct Point p(length,-TB-TS*length);
  while(hull.size()>=2&&(p-hull[hull.size()-2]).cross(hull.back()-hull[hull.size()-2])>0){
    hull.pop_back();
  }
  hull.push_back(p);
  length+=K;
}

void reduce(){
  while(hull.size()>1&&hull.back().eval()>=hull[hull.size()-2].eval()){
    hull.pop_back();
  }
}

int main(){
  hull.emplace_back(0,0);
  int64_t M;
  scanf("%I64d %I64d",&length,&M);
  while(M-->0){
    int64_t T;
    scanf("%I64d",&T);
    if(T==1){
      int64_t K;
      scanf("%I64d",&K);
      TB=TS=0;
      hull.clear();
      int64_t tmp=length;
      length-=tmp;
      add(K);
      length+=tmp;
    }else if(T==2){
      int64_t K;
      scanf("%I64d",&K);
      add(K);
    }else if(T==3){
      int64_t B,S;
      scanf("%I64d %I64d",&B,&S);
      TB+=B,TS+=S;
    }else{
      assert(0);
    }
    reduce();
    /*
    for(struct Point p:hull){
      printf("(%I64d, %I64d)\n",p.x,p.eval());
    }
    */
    printf("%I64d %I64d\n",hull.back().x+1,hull.back().eval());
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <cassert>
#include <stdint.h>

int64_t TB,TS;

struct Point{
  int64_t x,y;
  Point(int64_t x,int64_t y):x(x),y(y){
  }
  struct Point operator-(struct Point p)const{
    return Point(x-p.x,y-p.y);
  }
  int64_t cross(struct Point p)const{
    return x*p.y-y*p.x;
  }
  int64_t eval(){
    return y+x*TS+TB;
  }
};

std::vector<struct Point> hull;
int64_t length=0;

int64_t add(int64_t K){
  struct Point p(length,-TB-TS*length);
  while(hull.size()>=2&&(p-hull[hull.size()-2]).cross(hull.back()-hull[hull.size()-2])>0){
    hull.pop_back();
  }
  hull.push_back(p);
  length+=K;
}

void reduce(){
  while(hull.size()>1&&hull.back().eval()>=hull[hull.size()-2].eval()){
    hull.pop_back();
  }
}

int main(){
  int64_t M;
  scanf("%I64d %I64d",&length,&M);
  while(M-->0){
    int64_t T;
    scanf("%I64d",&T);
    if(T==1){
      int64_t K;
      scanf("%I64d",&K);
      TB=TS=0;
      hull.clear();
      int64_t tmp=length;
      length-=tmp;
      add(K);
      length+=tmp;
    }else if(T==2){
      int64_t K;
      scanf("%I64d",&K);
      add(K);
    }else if(T==3){
      int64_t B,S;
      scanf("%I64d %I64d",&B,&S);
      TB+=B,TS+=S;
    }else{
      assert(0);
    }
    reduce();
    /*
    for(struct Point p:hull){
      printf("(%I64d, %I64d)\n",p.x,p.eval());
    }
    */
    printf("%I64d %I64d\n",hull.back().x+1,hull.back().eval());
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <cassert>
#include <stdint.h>

int64_t TB,TS;

struct Point{
  int64_t x,y;
  Point(int64_t x,int64_t y):x(x),y(y){
  }
  struct Point operator-(struct Point p)const{
    return Point(x-p.x,y-p.y);
  }
  int64_t cross(struct Point p)const{
    return x*p.y-y*p.x;
  }
  int64_t eval(){
    return y+x*TS+TB;
  }
};

std::vector<struct Point> hull;
int64_t length=0;

int64_t add(int64_t K){
  struct Point p(length,-TB-TS*length);
  while(hull.size()>=2&&(p-hull[hull.size()-2]).cross(hull.back()-hull[hull.size()-2])>0){
    hull.pop_back();
  }
  hull.push_back(p);
  length+=K;
}

void reduce(){
  while(hull.size()>1&&hull.back().eval()>=hull[hull.size()-2].eval()){
    hull.pop_back();
  }
}

int main(){
  int64_t M;
  scanf("%ld %ld",&length,&M);
  while(M-->0){
    int64_t T;
    scanf("%ld",&T);
    if(T==1){
      int64_t K;
      scanf("%ld",&K);
      TB=TS=0;
      hull.clear();
      int64_t tmp=length;
      length-=tmp;
      add(K);
      length+=tmp;
    }else if(T==2){
      int64_t K;
      scanf("%ld",&K);
      add(K);
    }else if(T==3){
      int64_t B,S;
      scanf("%ld %ld",&B,&S);
      TB+=B,TS+=S;
    }else{
      assert(0);
    }
    reduce();
    /*
    for(struct Point p:hull){
      printf("(%ld, %ld)\n",p.x,p.eval());
    }
    */
    printf("%ld %ld\n",hull.back().x+1,hull.back().eval());
  }
  return 0;
}


#include <bits/stdc++.h>

const int MAXN = 300010;
typedef long long LL;
typedef long double LD;
int ks[MAXN], hav, top;
LL bs[MAXN], db, dx;
int main() {
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	int Q; std::cin >> hav >> Q; top = 1;
	while (Q --> 0) {
		int opt, x, y;
		std::cin >> opt >> x;
		if (opt == 1) {
			top = 1, db = dx = ks[1] = bs[1] = 0; hav += x;
		} else if (opt == 2) {
			*ks = hav, hav += x, *bs = -((LL) dx * *ks + db);
			while (top > 1) {
				LD d = (LD) (bs[top] - bs[top - 1]) * (*ks - ks[top]);
				d -= (LD) (*bs - bs[top]) * (ks[top] - ks[top - 1]);
				if (d < -1e-5) break;
				--top;
			}
			++top, ks[top] = *ks, bs[top] = *bs;
		} else {
			std::cin >> y, dx += y, db += x;
		}
		while (top > 1) {
			LD v1 = bs[top - 1] + ks[top - 1] * dx;
			LD v2 = bs[top] + ks[top] * dx;
			if (v1 > v2) break;
			--top;
		}
		std::cout << ks[top] + 1 << ' ' << (LL) ks[top] * dx + bs[top] + db << '\n';
	}
	return 0;
}


#include <bits/stdc++.h>

const int MAXN = 300010;
typedef long long LL;
typedef long double LD;
int ks[MAXN], dx, hav, top;
LL bs[MAXN], db;
int main() {
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	int Q; std::cin >> hav >> Q; top = 1;
	while (Q --> 0) {
		int opt, x, y;
		std::cin >> opt >> x;
		if (opt == 1) {
			top = 1, db = dx = ks[1] = bs[1] = 0; hav += x;
		} else if (opt == 2) {
			*ks = hav, hav += x, *bs = -((LL) dx * *ks + db);
			while (top > 1) {
				LD d = (bs[top] - bs[top - 1]) * (*ks - ks[top]);
				d -= (*bs - bs[top]) * (ks[top] - ks[top - 1]);
				if (d < -1e-5) break;
				--top;
			}
			++top, ks[top] = *ks, bs[top] = *bs;
		} else {
			std::cin >> y, dx += y, db += x;
		}
		while (top > 1) {
			LD v1 = bs[top - 1] + (LL) ks[top - 1] * dx;
			LD v2 = bs[top] + (LL) ks[top] * dx;
			if (v1 > v2) break;
			--top;
		}
		std::cout << ks[top] + 1 << ' ' << (LL) ks[top] * dx + bs[top] + db << '\n';
	}
	return 0;
}


#include <bits/stdc++.h>

const int MAXN = 300010;
typedef long long LL;
typedef long double LD;
int ks[MAXN], hav, top;
LL bs[MAXN], db, dx;
int main() {
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	int Q; std::cin >> hav >> Q; top = 1;
	while (Q --> 0) {
		int opt, x, y;
		std::cin >> opt >> x;
		if (opt == 1) {
			top = 1, db = dx = ks[1] = bs[1] = 0; hav += x;
		} else if (opt == 2) {
			*ks = hav, hav += x, *bs = -((LL) dx * *ks + db);
			while (top > 1) {
				LD d = (bs[top] - bs[top - 1]) * (*ks - ks[top]);
				d -= (*bs - bs[top]) * (ks[top] - ks[top - 1]);
				if (d < -1e-5) break;
				--top;
			}
			++top, ks[top] = *ks, bs[top] = *bs;
		} else {
			std::cin >> y, dx += y, db += x;
		}
		while (top > 1) {
			LD v1 = bs[top - 1] + ks[top - 1] * dx;
			LD v2 = bs[top] + ks[top] * dx;
			if (v1 > v2) break;
			--top;
		}
		std::cout << ks[top] + 1 << ' ' << (LL) ks[top] * dx + bs[top] + db << '\n';
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <array>
#include <climits>
#include <bitset>
#include <cassert>

// BEGIN CUT HERE
#ifdef _MSC_VER
#include <agents.h>
#endif
// END CUT HERE

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define UNIQUE(v) (v).erase(unique(ALL(v)), (v).end())
#define MP make_pair
#define MT make_tuple

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

const int N = 1e5 + 10;

struct EulerPath{
	struct edge{
		int to, cap, rev;
	};

	int n;
	vector<vector<edge>> G;
	vector<int> idx;

	EulerPath(int _n) : n(_n){
		G.resize(n);
	}

	void add_edge(int s, int t){
		G[s].push_back({ t, 1, G[t].size() + (s == t) });
		G[t].push_back({ s, 1, G[s].size() - 1 });
	}

	void visit(int s, vector<int> &path){
		stack<int> st;
		st.push(s);
		while (!st.empty()){
			int v = st.top(); st.pop();
			bool ok = true;
			for (int &i = idx[v]; i < G[v].size(); ++i){
				auto &e = G[v][i];
				if (e.cap){
					e.cap = G[e.to][e.rev].cap = 0;
					ok = false;
					st.push(v);
					st.push(e.to);
					break;
				}
			}
			if (ok) path.push_back(v);
		}
	}

	bool get(vector<int> &path, int start){
		int odd = 0;
		for (int i = 0; i < n; ++i){
			if (G[i].size() % 2){
				if (start == -1) start = i;
				++odd;
			}
		}

		if (odd != 0 && odd != 2) return false;
		if (start < 0) start = 0;
		if (odd == 2 && G[start].size() % 2 == 0) return false;
		path.clear();
		idx.assign(n, 0);
		visit(start, path);
		reverse(path.begin(), path.end());
		return true;
	}
};

vector<int> path;

int idx[N];

int deg[N];
int deg2[N];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.setf(ios::fixed);
	cout.precision(20);

	int n, m;
	scanf("%d %d", &n, &m);

	EulerPath ep(n);
	rep(i, m){
		int a, b;
		scanf("%d %d", &a, &b);
		--a, --b;
		ep.add_edge(a, b);
		deg[a] ^= 1;
		deg[b] ^= 1;
	}

	queue<int> q;
	for (int i = 0; i < n; ++i) if (deg[i]) q.push(i);

	while (!q.empty()){
		int a, b;
		a = q.front(); q.pop();
		b = q.front(); q.pop();
		ep.add_edge(a, b);
		deg[a] ^= 1;
		deg[b] ^= 1;
		++m;
	}

	vector<int> path;
	ep.get(path, -1);
	rep(i, path.size()) ++path[i];
	int x = m % 2 ? path[m] : -1;

	printf("%d\n", m + (x >= 0));
	for (int i = 0; i < m; ++i){
		if (i & 1){
			printf("%d %d\n", path[i], path[i + 1]);
		}
		else{
			printf("%d %d\n", path[i + 1], path[i]);
		}
	}
	if (x >= 0) printf("%d %d\n", x, x);
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <array>
#include <climits>
#include <bitset>
#include <cassert>

// BEGIN CUT HERE
#ifdef _MSC_VER
#include <agents.h>
#endif
// END CUT HERE

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define UNIQUE(v) (v).erase(unique(ALL(v)), (v).end())
#define MP make_pair
#define MT make_tuple

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

const int N = 1e5 + 10;

struct edge{
	int to, cap, rev;
};

vector<edge> G[N];

void add_edge(int s, int t){
	G[s].push_back({ t, 1, G[t].size() });
	G[t].push_back({ s, 1, G[s].size() - 1 });
}

vector<int> path;

int idx[N];

int deg[N];
int deg2[N];

void visit(int s){
	for (int &i = idx[s]; i < G[s].size(); ++i){
		auto &e = G[s][i];
		if (e.cap){
			e.cap = G[e.to][e.rev].cap = 0;
			visit(e.to);
		}
	}
	path.push_back(s);
}

void euler(){
	visit(1);
	reverse(ALL(path));
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.setf(ios::fixed);
	cout.precision(20);

	int n, m;
	scanf("%d %d", &n, &m);

	rep(i, m){
		int a, b;
		scanf("%d %d", &a, &b);
		add_edge(a, b);
		++deg[a];
		++deg[b];
	}

	queue<int> q, qq;
	int x = -1;
	for (int i = 1; i <= n; ++i){
		if (!deg[i]) qq.push(i);
		if (deg[i] % 2) q.push(i);
		if (deg[i] >= 2) x = i;
	}

	while (!qq.empty()){
		if (!q.empty()){
			int a = q.front(); q.pop();
			int b = qq.front(); qq.pop();
			add_edge(a, b);
			++deg[a];
			++deg[b];
			++m;
			q.push(b);
		}
		else{
			int a = x;
			int b = qq.front(); qq.pop();
			++deg[a];
			++deg[b];
			q.push(a);
			q.push(b);
		}
	}

	while (!q.empty()){
		int a, b;
		a = q.front(); q.pop();
		b = q.front(); q.pop();
		add_edge(a, b);
		++deg[a];
		++deg[b];
		++m;
	}
	MEMSET(deg, 0);

	euler();

	int x = m % 2 ? path[m]: -1;

	printf("%d\n", m + (x >= 0));
	for (int i = 0; i < m; ++i){
		if (i & 1){
			printf("%d %d\n", path[i], path[i + 1]);
		}
		else{
			printf("%d %d\n", path[i + 1], path[i]);
		}
	}
	if (x >= 0) printf("%d %d\n", x, x);
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <array>
#include <climits>
#include <bitset>
#include <cassert>

// BEGIN CUT HERE
#ifdef _MSC_VER
#include <agents.h>
#endif
// END CUT HERE

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define UNIQUE(v) (v).erase(unique(ALL(v)), (v).end())
#define MP make_pair
#define MT make_tuple

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

const int N = 1e5 + 10;

struct edge{
	int to, cap, rev;
};

vector<edge> G[N];

void add_edge(int s, int t){
	G[s].push_back({ t, 1, G[t].size() });
	G[t].push_back({ s, 1, G[s].size() - 1 });
}

vector<int> path;

int idx[N];

int deg[N];
int deg2[N];

void visit(int s){
	for (int &i = idx[s]; i < G[s].size(); ++i){
		auto &e = G[s][i];
		if (e.cap){
			e.cap = G[e.to][e.rev].cap = 0;
			visit(e.to);
		}
	}
	path.push_back(s);
}

void euler(){
	visit(1);
	reverse(ALL(path));
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.setf(ios::fixed);
	cout.precision(20);

	int n, m;
	scanf("%d %d", &n, &m);

	rep(i, m){
		int a, b;
		scanf("%d %d", &a, &b);
		add_edge(a, b);
		deg[a] ^= 1;
		deg[b] ^= 1;
	}

	queue<int> q;
	for (int i = 1; i <= n; ++i) if (deg[i]) q.push(i);

	while (!q.empty()){
		int a, b;
		a = q.front(); q.pop();
		b = q.front(); q.pop();
		add_edge(a, b);
		deg[a] ^= 1;
		deg[b] ^= 1;
		++m;
	}

	euler();

	int x = m % 2 ? path[m]: -1;

	printf("%d\n", m + (x >= 0));
	for (int i = 0; i < m; ++i){
		if (i & 1){
			printf("%d %d\n", path[i], path[i + 1]);
		}
		else{
			printf("%d %d\n", path[i + 1], path[i]);
		}
	}
	if (x >= 0) printf("%d %d\n", x, x);
}


#define _CRT_SECURE_NO_DEPRECATE
#include <ctime>
#include <float.h>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <cstring>
#include <cstdio>
using namespace std;
#define pb push_back
#define inf 1000000000
#define ll long long
#define all(c) (c).begin(), (c).end()
#define VI vector<int>
#define ppb pop_back
#define mp make_pair
#define pii pair<int,int>
#define pdd pair<double,double>
#define L(s) (int)(s).size()
#define x first
#define y second
#define pi 2 * acos(0.)
int n, m, k;
VI a[111111];
int u[111111];
int inp[111111], out[111111];
vector<pii> ans(0);
void dfs(int v, int pr) {
	u[v] = 1;
	for (int i = 0; i < L(a[v]); ++i) {
		if (!u[a[v][i]]) {
			dfs(a[v][i], v);
		}
		else {
			if (a[v][i] != pr && u[a[v][i]] == 1) {
				out[v]++;
				inp[a[v][i]]++;
				ans.pb(mp(v, a[v][i]));
			}
		}
	}
	u[v] = 2;
	if (v == 0 && (inp[v] % 2 || out[v] % 2)) {
		ans.pb(mp(v, v));
		return;
	}
	if (v == 0) {
		return;
	}
	for (int i = 0; i < L(a[v]); ++i) {
		if (a[v][i] == pr) {
			if (inp[v] % 2) {
				ans.pb(mp(pr, v));
				inp[v]++;
				out[pr]++;
			}
			else {
				ans.pb(mp(v, pr));
				out[v]++;
				inp[pr]++;
			}
		}
	}
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; ++i) {
		int x, y; scanf("%d%d", &x, &y);
		--x; --y;
		if (x == y) {
			ans.pb(mp(x, y));
			inp[x]++;
			out[x]++;
		}
		else {
			a[x].pb(y); a[y].pb(x);
		}
	}

	int last = -1;
	for (int i = 0; i < n; ++i) {
		if (L(a[i]) % 2 == 1) {
			if (last == -1) {
				last = i;
			}
			else {
				a[i].pb(last);
				a[last].pb(i);
				last = -1;
			}
		}
	}

	dfs(0, -1);

	printf("%d\n", L(ans));
	for (int i = 0; i < L(ans); ++i) {
		printf("%d %d\n", ans[i].x + 1, ans[i].y + 1);
	}
}


#define _CRT_SECURE_NO_DEPRECATE
#include <ctime>
#include <float.h>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <cstring>
#include <cstdio>
using namespace std;
#define pb push_back
#define inf 1000000000
#define ll long long
#define all(c) (c).begin(), (c).end()
#define VI vector<int>
#define ppb pop_back
#define mp make_pair
#define pii pair<int,int>
#define pdd pair<double,double>
#define L(s) (int)(s).size()
#define x first
#define y second
#define pi 2 * acos(0.)
int n, m, k;
VI a[111111];
int u[111111];
int inp[111111], out[111111];
vector<pii> ans(0);
void dfs(int v, int pr) {
	u[v] = 1;
	for (int i = 0; i < L(a[v]); ++i) {
		if (!u[a[v][i]]) {
			dfs(a[v][i], v);
		}
		else {
			if (a[v][i] != pr && u[a[v][i]] == 1) {
				out[v]++;
				inp[a[v][i]]++;
				ans.pb(mp(v, a[v][i]));
			}
		}
	}
	u[v] = 2;
	if (v == 0 && (inp[v] % 2 || out[v] % 2)) {
		ans.pb(mp(v, v));
		return;
	}
	if (v == 0) {
		return;
	}
	if (inp[v] % 2) {
		ans.pb(mp(pr, v));
		inp[v]++;
		out[pr]++;
	}
	else {
		ans.pb(mp(v, pr));
		out[v]++;
		inp[pr]++;
	}

}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; ++i) {
		int x, y; scanf("%d%d", &x, &y);
		--x; --y;
		if (x == y) {
			ans.pb(mp(x, y));
			inp[x]++;
			out[x]++;
		}
		else {
			a[x].pb(y); a[y].pb(x);
		}
	}

	int last = -1;
	for (int i = 0; i < n; ++i) {
		if (L(a[i]) % 2 == 1) {
			if (last == -1) {
				last = i;
			}
			else {
				a[i].pb(last);
				a[last].pb(i);
				last = -1;
			}
		}
	}

	dfs(0, -1);

	printf("%d\n", L(ans));
	for (int i = 0; i < L(ans); ++i) {
		printf("%d %d\n", ans[i].x + 1, ans[i].y + 1);
	}
}


#include <iostream>
#include <fstream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <queue>

typedef long long ll;
typedef long double ld;

using namespace std;

const int MAXN = 220000;

vector<int> eds[MAXN];
vector<pair<int, int> > ed;

vector<int> vv;
int n, m;
vector<pair<int, int> > ans;
int was[MAXN * 4];

int p[MAXN];

void add_edge(int a, int b) {
	ed.push_back({a, b});
	eds[a].push_back(ed.size() - 1);
	eds[b].push_back(ed.size() - 1);
}

void dfs(int v) {
	while (p[v] != (int)eds[v].size()) {
		int xx = eds[v][p[v]];
		if (was[xx]) {
			++p[v];
			continue;
		}
		ans.push_back({v, ed[xx].first ^ ed[xx].second ^ v});
		was[xx] = 1;
		++p[v];
		dfs(ed[xx].first ^ ed[xx].second ^ v);
	}
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; ++i) {
		int a, b;
		scanf("%d%d", &a, &b);
		--a;
		--b;
		add_edge(a, b);
	}
	for (int i = 0; i < n; ++i) {
		if (eds[i].size() % 2 == 1)
			vv.push_back(i);
	}
	for (int i = 0; i < (int)vv.size(); i += 2)
		add_edge(vv[i], vv[i + 1]);
	if (ed.size() % 2 == 1)
		add_edge(0, 0);
	dfs(0);
	cout << ans.size() << "\n";
	for (int i = 0; i < (int)ans.size(); ++i) {
		if (i % 2 == 0) {
			printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
		}
		else {
			printf("%d %d\n", ans[i].second + 1, ans[i].first + 1);
		}
	}
	return 0;
}


#include <iostream>
#include <fstream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <queue>

typedef long long ll;
typedef long double ld;

using namespace std;

const int MAXN = 220000;

vector<int> eds[MAXN];
vector<pair<int, int> > ed;

vector<int> vv;
int n, m;
vector<pair<int, int> > ans;
int was[MAXN * 4];

int p[MAXN];

void add_edge(int a, int b) {
	ed.push_back({a, b});
	eds[a].push_back(ed.size() - 1);
	eds[b].push_back(ed.size() - 1);
}

void dfs(int v) {
	while (p[v] != (int)eds[v].size()) {
		int xx = eds[v][p[v]];
		if (was[xx]) {
			++p[v];
			continue;
		}
		was[xx] = 1;
		++p[v];
		dfs(ed[xx].first ^ ed[xx].second ^ v);
		ans.push_back({v, ed[xx].first ^ ed[xx].second ^ v});
	}
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; ++i) {
		int a, b;
		scanf("%d%d", &a, &b);
		--a;
		--b;
		add_edge(a, b);
	}
	for (int i = 0; i < n; ++i) {
		if (eds[i].size() % 2 == 1)
			vv.push_back(i);
	}
	for (int i = 0; i < (int)vv.size(); i += 2)
		add_edge(vv[i], vv[i + 1]);
	if (ed.size() % 2 == 1)
		add_edge(0, 0);
	dfs(0);
	cout << ans.size() << "\n";
	for (int i = 0; i < (int)ans.size(); ++i) {
		if (i % 2 == 0) {
			printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
		}
		else {
			printf("%d %d\n", ans[i].second + 1, ans[i].first + 1);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define F first
#define S second
typedef long long LL;
using namespace std;
const int MOD = 1e9+7;
const int SIZE = 1e6+10;
VPII e[SIZE];
int used[SIZE],tt;
int one[SIZE],on;
int en;
int it[SIZE];
int ty;
void dfs3(int x){
    while(it[x]<SZ(e[x])){
        if(used[e[x][it[x]].S]!=tt){
            used[e[x][it[x]].S]=tt;
            int me=e[x][it[x]].F;
            it[x]++;
            dfs3(me);
            if(ty)printf("%d %d\n",x,me);
            else printf("%d %d\n",me,x);
            ty^=1;
        }
        else it[x]++;
    }
}
void dfs2(int x){
    en+=SZ(e[x]);
    used[x]=tt;
    REP(i,SZ(e[x])){
        int y=e[x][i].F;
        if(used[y]==tt)continue;
        dfs2(y);
    }
}
void dfs(int x){
    if(SZ(e[x])&1)one[on++]=x;
    used[x]=tt;
    REP(i,SZ(e[x])){
        int y=e[x][i].F;
        if(used[y]==tt)continue;
        dfs(y);
    }
}
int main(){
    int n,m;
    while(RII(n,m)==2){
        //part1
        tt++;
        REP(i,m){
            DRII(x,y);
            e[x].PB(MP(y,i));
            e[y].PB(MP(x,i));
        }
        REPP(i,1,n+1){
            if(used[i]!=tt){
                dfs(i);
            }
        }
        one[on]=one[0];
        for(int i=1;i<=on;i+=2){
            e[one[i]].PB(MP(one[i+1],m));
            e[one[i+1]].PB(MP(one[i],m));
            m++;
        }
        //part2
        tt++;
        REPP(i,1,n+1){
            if(used[i]!=tt){
                en=0;
                dfs2(i);
                if((en/2)%2==1){
                    e[i].PB(MP(i,m));
                    m++;
                }
            }
        }
        //part3
        printf("%d\n",m);
        tt++;
        REPP(i,1,n+1){
            if(used[i]!=tt){
                dfs3(i);
            }
        }
    }
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <deque>
#include <list>
#include <iterator>
#include <functional>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <climits>
#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef double ld;//
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pnt;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

const int MAXN = 1000 * 100 + 10;

vector <pii> g[MAXN];
vector <int> bad;
vector <int> ans;
bool was[3000 * 1000];
void dfs(int v){
	while (!g[v].empty() &&
		   was[g[v].back().se]) g[v].pop_back();
	if (g[v].empty()) return;
	int ne = g[v].back().fi;
	was[g[v].back().se] = 1;
	g[v].pop_back();
	dfs(ne);
	ans.pb(v);
}
int main() {
#ifdef HOME
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#else
  //freopen(FILE ".in", "r", stdin);
  //freopen(FILE ".out", "w", stdout);
#endif
  ios_base::sync_with_stdio(false); //
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int cnt = 0;
  for (int i = 0; i < m; i++){
	  int a, b;
	  cin >> a >> b;
	  a--, b--;
	  g[a].pb({b, cnt});
	  g[b].pb({a, cnt});
	  cnt++;
  }
  for (int i = 0; i < n; i++)
	  if ((int)g[i].size() % 2){
		  bad.pb(i);
	  }
  for (int i = 0; i < (int)bad.size(); i+= 2){
	  int a = bad[i],
		  b = bad[i + 1];
	  g[a].pb({b, cnt});
	  g[b].pb({a, cnt});
	  cnt++;
  }
  if (cnt % 2){
	  g[0].pb({0, cnt});
	  cnt++;
  }
  dfs(0);
  cout << cnt << '\n';
  for (int i = 0; i < cnt; i++){
	  int ii = i + 1;
	  if (i + 1 == cnt) ii = 0;
	  if (i % 2){
		  cout << ans[i] + 1 << " " << ans[ii] + 1 << '\n';
	  } else {
		  cout << ans[ii] + 1 << " " << ans[i] + 1 << '\n';
	  }
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <deque>
#include <list>
#include <iterator>
#include <functional>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <climits>
#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef double ld;//
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pnt;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

const int MAXN = 1000 * 100 + 10;

vector <pii> g[MAXN];
vector <int> bad;
vector <int> ans;
bool was[3000 * 1000];
void dfs(int v){
	while (!g[v].empty() &&
		   was[g[v].back().se]) g[v].pop_back();
	if (g[v].empty()) return;
	int ne = g[v].back().fi;
	was[g[v].back().se] = 1;
	g[v].pop_back();
	dfs(ne);
	ans.pb(v);
}
int main() {
#ifdef HOME
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#else
  //freopen(FILE ".in", "r", stdin);
  //freopen(FILE ".out", "w", stdout);
#endif
  ios_base::sync_with_stdio(false); //
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int cnt = 0;
  for (int i = 0; i < m; i++){
	  int a, b;
	  cin >> a >> b;
	  a--, b--;
	  g[a].pb({b, cnt});
	  g[b].pb({a, cnt});
	  cnt++;
  }
  for (int i = 0; i < n; i++)
	  if ((int)g[i].size() % 2){
		  bad.pb(i);
	  }
  for (int i = 0; i < (int)bad.size(); i+= 2){
	  int a = bad[i],
		  b = bad[i + 1];
	  g[a].pb({b, cnt});
	  g[b].pb({a, cnt});
	  cnt++;
  }
  if (cnt % 2){
	  g[0].pb({0, cnt});
	  cnt++;
  }
  dfs(0);
  cout << cnt << '\n';
  for (int i = 0; i < cnt; i++){
	  int ii = i + 1;
	  if (i + 1 == cnt) ii = 0;
	  if (i % 2){
		  cout << ans[i] + 1 << " " << ans[ii] + 1 << '\n';
	  } else {
		  cout << ans[i + 1] + 1 << " " << ans[i] + 1 << '\n';
	  }
  }
  return 0;
}


#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <deque>
#include <list>
#include <iterator>
#include <functional>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <climits>
#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef double ld;//
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pnt;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

const int MAXN = 1000 * 100 + 10;

vector <pii> g[MAXN];
vector <int> bad;
vector <int> ans;
bool was[3000 * 1000];
void dfs(int v){
	while (!g[v].empty() &&
		   was[g[v].back().se]) g[v].pop_back();
	if (g[v].empty()) return;
	int ne = g[v].back().fi;
	was[g[v].back().se] = 1;
	g[v].pop_back();
	dfs(ne);
	ans.pb(v);
	dfs(v);
}
int main() {
#ifdef HOME
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#else
  //freopen(FILE ".in", "r", stdin);
  //freopen(FILE ".out", "w", stdout);
#endif
  ios_base::sync_with_stdio(false); //
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int cnt = 0;
  for (int i = 0; i < m; i++){
	  int a, b;
	  cin >> a >> b;
	  a--, b--;
	  g[a].pb({b, cnt});
	  g[b].pb({a, cnt});
	  cnt++;
  }
  for (int i = 0; i < n; i++)
	  if ((int)g[i].size() % 2){
		  bad.pb(i);
	  }
  for (int i = 0; i < (int)bad.size(); i += 2){
	  int a = bad[i],
		  b = bad[i + 1];
	  g[a].pb({b, cnt});
	  g[b].pb({a, cnt});
	  cnt++;
  }
  if (cnt % 2){
	  g[0].pb({0, cnt});
	  cnt++;
  }
  dfs(0);
  cout << cnt << '\n';
  for (int i = 0; i < cnt; i++){
	  int ii = i + 1;
	  if (i + 1 == cnt) ii = 0;
	  if (i % 2){
		  cout << ans[i] + 1 << " " << ans[ii] + 1 << '\n';
	  } else {
		  cout << ans[ii] + 1 << " " << ans[i] + 1 << '\n';
	  }
  }
  return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <stdio.h>
#include <map>
using namespace std;

int n, m;
vector < int > ptr, od, used;
vector < vector < pair <int, int> > > g;
vector < pair <int, int> > answer;

void euler_cycle(int v, int odd)
{
    while( ptr[v] < g[v].size() )
    {
        if (used[g[v][ptr[v]].second]) {
            ptr[v]++;
            continue;
        }
        int to = g[v][ptr[v]].first;
        od[v] ^= odd;
        od[to] ^= (1 ^ odd);
        pair <int, int> add = { v, to };
        if (odd)
        {
            swap(add.first, add.second);
        }
        answer.push_back(add);
        used[g[v][ptr[v]].second] = 1;
        ptr[v]++;
        euler_cycle(to, odd ^ 1);
    }
}

int main()
{
    cin >> n >> m;
    g.resize(n);
    od.resize(n, 0);
    ptr.resize(n, 0);
    used.resize(2*m, 0);
    for (int i = 0; i < m; i++)
    {
        int a, b; cin >> a >> b; a--; b--;
        g[a].push_back({ b, i });
        g[b].push_back({ a, i });
    }

    int last = -1;
    int add_edges = m;
    for (int i = 0; i < n; i++)
    {
        if (g[i].size() & 1)
        {
            if (last == -1)
            {
                last = i;
            }
            else
            {
                g[last].push_back({ i, add_edges });
                g[i].push_back({ last, add_edges });
                add_edges++;
                last = -1;
            }
        }
    }

    if (add_edges % 2 == 1)
    {
        g[0].push_back({ 0, add_edges });
        add_edges++;
    }

    euler_cycle(0, 0);

    cout << answer.size() << endl;

    for (int i = 0; i < answer.size(); i++)
    {
        cout << answer[i].first + 1 << " " << answer[i].second + 1 << "\n";
    }

    cout.flush();

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <stdio.h>
#include <map>
using namespace std;

int n, m;
vector < int > ptr, od, used;
vector < vector < pair <int, int> > > g;
vector < pair <int, int> > answer;

void euler_cycle(int v, int odd)
{
    while( ptr[v] < g[v].size() )
    {
        if (used[g[v][ptr[v]].second]) {
            ptr[v]++;
            continue;
        }
        int to = g[v][ptr[v]].first;
        pair <int, int> add = { v, to };
        if (odd)
        {
            swap(add.first, add.second);
        }
        od[add.second]++;
        answer.push_back(add);
        used[g[v][ptr[v]].second] = 1;
        ptr[v]++;
        euler_cycle(to, odd ^ 1);
    }
}

int main()
{
    cin >> n >> m;
    g.resize(n);
    od.resize(n, 0);
    ptr.resize(n, 0);
    used.resize(2*m, 0);
    for (int i = 0; i < m; i++)
    {
        int a, b; cin >> a >> b; a--; b--;
        g[a].push_back({ b, i });
        g[b].push_back({ a, i });
    }

    int last = -1;
    int add_edges = m;
    for (int i = 0; i < n; i++)
    {
        if (g[i].size() & 1)
        {
            if (last == -1)
            {
                last = i;
            }
            else
            {
                g[last].push_back({ i, add_edges });
                g[i].push_back({ last, add_edges });
                add_edges++;
                last = -1;
            }
        }
    }

    euler_cycle(0, 0);

    if (answer.size() & 1) {

        answer.push_back({ 0, 0 });
    }

    cout << answer.size() << endl;

    for (int i = 0; i < answer.size(); i++)
    {
        cout << answer[i].first + 1 << " " << answer[i].second + 1 << "\n";
    }

    cout.flush();

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <stdio.h>
#include <map>
using namespace std;

int n, m;
vector < int > ptr, used, od;
vector < vector < pair <int, int> > > g;
vector < pair <int, int> > answer;

void euler_cycle(int v)
{
    while( ptr[v] < g[v].size() )
    {
        if (used[g[v][ptr[v]].second]) {
            ptr[v]++;
            continue;
        }
        int to = g[v][ptr[v]].first;
        used[g[v][ptr[v]].second] = 1;
        ptr[v]++;
        euler_cycle(to);
        answer.push_back({ v, to });
        if (answer.size() & 1)
            swap(answer[answer.size() - 1].first, answer[answer.size() - 1].second);
    }
}

int main()
{
    cin >> n >> m;
    g.resize(n);
    ptr.resize(n, 0);
    od.resize(n, 0);
    used.resize(2*m, 0);
    for (int i = 0; i < m; i++)
    {
        int a, b; cin >> a >> b; a--; b--;
        g[a].push_back({ b, i });
        g[b].push_back({ a, i });
    }

    int last = -1;
    int add_edges = m;
    for (int i = 0; i < n; i++)
    {
        if (g[i].size() & 1)
        {
            if (last == -1)
            {
                last = i;
            }
            else
            {
                g[last].push_back({ i, add_edges });
                g[i].push_back({ last, add_edges });
                add_edges++;
                last = -1;
            }
        }
    }

    euler_cycle(0);

    if (answer.size() & 1) {

        answer.push_back({ 0, 0 });
    }

    cout << answer.size() << endl;

    for (int i = 0; i < answer.size(); i++)
    {
        cout << answer[i].first + 1 << " " << answer[i].second + 1 << "\n";
    }

    cout.flush();

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <stdio.h>
#include <map>
using namespace std;

int n, m;
vector < int > ptr, used, od;
vector < vector < pair <int, int> > > g;
vector < pair <int, int> > answer;

void euler_cycle(int v)
{
    while( ptr[v] < g[v].size() )
    {
        if (used[g[v][ptr[v]].second]) {
            ptr[v]++;
            continue;
        }
        int to = g[v][ptr[v]].first;
        od[answer[answer.size() - 1].second]++;
        used[g[v][ptr[v]].second] = 1;
        ptr[v]++;
        euler_cycle(to);
                answer.push_back({ v, to });
                if (answer.size() & 1)
                    swap(answer[answer.size() - 1].first, answer[answer.size() - 1].second);
    }
}

int main()
{
    cin >> n >> m;
    g.resize(n);
    ptr.resize(n, 0);
    od.resize(n, 0);
    used.resize(2*m, 0);
    for (int i = 0; i < m; i++)
    {
        int a, b; cin >> a >> b; a--; b--;
        g[a].push_back({ b, i });
        g[b].push_back({ a, i });
    }

    int last = -1;
    int add_edges = m;
    for (int i = 0; i < n; i++)
    {
        if (g[i].size() & 1)
        {
            if (last == -1)
            {
                last = i;
            }
            else
            {
                g[last].push_back({ i, add_edges });
                g[i].push_back({ last, add_edges });
                add_edges++;
                last = -1;
            }
        }
    }

    euler_cycle(0);

    if (answer.size() & 1) {

        answer.push_back({ 0, 0 });
    }

    cout << answer.size() << endl;

    for (int i = 0; i < answer.size(); i++)
    {
        cout << answer[i].first + 1 << " " << answer[i].second + 1 << "\n";
    }

    cout.flush();

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <stdio.h>
#include <map>
using namespace std;

int n, m;
vector < int > ptr, od, used;
vector < vector < pair <int, int> > > g;
vector < pair <int, int> > answer;

void euler_cycle(int v, int odd)
{
    while( ptr[v] < g[v].size() )
    {
        if (used[g[v][ptr[v]].second]) {
            ptr[v]++;
            continue;
        }
        int to = g[v][ptr[v]].first;
        od[v] ^= odd;
        od[to] ^= (1 ^ odd);
        pair <int, int> add = { v, to };
        if (odd)
        {
            swap(add.first, add.second);
        }
        answer.push_back(add);
        used[g[v][ptr[v]].second] = 1;
        ptr[v]++;
        euler_cycle(to, odd ^ 1);
    }

    if (od[v])
    {
        answer.push_back({ v, v });
        od[v] ^= 1;
    }
}

int main()
{
    cin >> n >> m;
    g.resize(n);
    od.resize(n, 0);
    ptr.resize(n, 0);
    used.resize(2*m, 0);
    for (int i = 0; i < m; i++)
    {
        int a, b; cin >> a >> b; a--; b--;
        g[a].push_back({ b, i });
        g[b].push_back({ a, i });
    }

    int last = -1;
    int add_edges = m;
    for (int i = 0; i < n; i++)
    {
        if (g[i].size() & 1)
        {
            if (last == -1)
            {
                last = i;
            }
            else
            {
                g[last].push_back({ i, add_edges });
                g[i].push_back({ last, add_edges });
                add_edges++;
                last = -1;
            }
        }
    }

    euler_cycle(0, 0);

    cout << answer.size() << endl;

    for (int i = 0; i < answer.size(); i++)
    {
        cout << answer[i].first + 1 << " " << answer[i].second + 1 << "\n";
    }

    cout.flush();

    return 0;
}


#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <numeric>
#include <memory.h>
#include <cstdio>
#include <assert.h>

using namespace std;

#define pb push_back
#define INF 1011111111
#define FOR(i, a, b) for (int _n(b), i(a); i < _n; i++)
#define rep(i, n) FOR(i, 0, n)
#define CL(a, v) memset((a), (v), sizeof(a))
#define mp make_pair
#define X first
#define Y second
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))

typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> pii;

/*** TEMPLATE CODE ENDS HERE */

const int maxn = 1e5 + 5;
VI g[maxn];
vector<pii> edges;
VI used;

void dfs(int at, vector<pii> &euler) {
  while (g[at].size()) {
    int id = g[at].back();
    g[at].pop_back();
    int to = edges[id].X == at ? edges[id].Y : edges[id].X;
    if (used[id]) continue;
    used[id] = true;
    dfs(to, euler);
    if (euler.size() & 1) {
      euler.push_back(mp(at, to));
    } else {
      euler.push_back(mp(to, at));
    }
  }
}

int main() {
#ifdef LOCAL_HOST
  freopen("input.txt", "r", stdin);
// freopen("output.txt","w",stdout);
#endif

  ios_base::sync_with_stdio(false);

  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    --x, --y;
    g[x].pb((int)edges.size());
    g[y].pb((int)edges.size());
    edges.push_back(mp(x, y));
  }

  int prev = -1;
  for (int i = 0; i < n; ++i) {
    if (g[i].size() & 1) {
      if (prev == -1) {
        prev = i;
      } else {
        g[i].push_back((int)edges.size());
        g[prev].push_back((int)edges.size());
        edges.push_back(mp(prev, i));
        prev = -1;
      }
    }
  }
  used = VI(edges.size());
  vector<pii> euler;

  dfs(0, euler);

  if (euler.size() & 1) {
    euler.push_back(mp(0, 0));
  }

  cout << euler.size() << endl;
  for (const pii &e : euler) {
    cout << e.X + 1 << " " << e.Y + 1 << endl;
  }

#ifdef LOCAL_HOST
  printf("TIME: %.3lf\n", double(clock()) / CLOCKS_PER_SEC);
#endif

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#if defined(ILIKEGENTOO)
void E(){}template<class A,class...B>void E(A _,B...$){cerr<<' '<<_;E($...);}
#define E($...) E(#$,'=',$,'\n')
#else
#define E($...) ;
#endif
#define all(x) begin(x), end(x)

int n, m;
typedef tuple<int, int, int> Edge;

vector<Edge> edges;

struct Vert {
	vector<int> e;
	int co, ci;
	int loops;
	int col;
};
vector<Vert> verts;

int go(int e, int v) {
	if (get<0>(edges[e]) == v)
		return get<1>(edges[e]);
	else if (get<1>(edges[e]) == v)
		return get<0>(edges[e]);
	assert(false);
	return -1;
}

void setdir(int e, int v) {
	auto &ed = edges[e];
	if (get<0>(ed) == v) {
		get<2>(ed) = 1;
		++verts[get<0>(ed)].co;
		++verts[get<1>(ed)].ci;
	} else {
		get<2>(ed) = -1;
		++verts[get<0>(ed)].ci;
		++verts[get<1>(ed)].co;
	}
}

void dfs(int vi) {
	auto &v = verts[vi];
	if (v.col != 0)
		return;
	v.col = 1;

	for (int ch: v.e)
		dfs(go(ch, vi));

	v.co += v.loops;
	v.ci += v.loops;

	for (int ch: v.e) if (!get<2>(edges[ch])) {
		if (v.co & 1)
			setdir(ch, vi);
		else
			setdir(ch, go(ch, vi));
	}

	v.col = 2;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	scanf("%d%d", &n, &m);
	verts.resize(n);
	edges.resize(m);
	for (int i = 0; i < m; ++i) {
		int a, b;
		scanf("%d%d", &a, &b);
		--a; --b;
		edges[i] = make_tuple(a, b, 0);
		if (a == b) {
			++verts[a].loops;
		} else {
			verts[a].e.push_back(i);
			verts[b].e.push_back(i);
		}
	}
	int odd = -1;
	for (int i = 0; i < n; ++i) if (verts[i].e.size() & 1) {
		if (odd < 0) {
			odd = i;
		} else {
			verts[odd].e.emplace_back(edges.size());
			verts[i].e.emplace_back(edges.size());
			edges.emplace_back(odd, i, 0);
			odd = -1;
		}
	}
	assert(odd < 0);

	dfs(0);

	odd = -1;
	for (int i = 0; i < n; ++i) {
		auto &v = verts[i];
		assert(((v.ci + v.co) & 1) == 0);
		if (v.ci & 1) {
			assert(odd < 0);
			odd = i;
		}
	}

	if (odd >= 0) {
		edges.emplace_back(odd, odd, 0);
	}

	printf("%d\n", int(edges.size()));
	for (auto &e: edges) {
		if (get<2>(e) < 0)
			swap(get<0>(e), get<1>(e));
		else if (get<2>(e) == 0)
			assert(get<0>(e) == get<1>(e));
		printf("%d %d\n", get<0>(e) + 1, get<1>(e) + 1);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define N 100010
#define M 800010

int n, m, h[N], p[M], n1[M], ee, st[N * 4], top, d[N], b[N], tot;
bool vis[M];

void ae(int x, int y){
	p[ee] = y; n1[ee] = h[x]; h[x] = ee ++;
}

void dfs(int u){
	for(;~h[u];h[u] = n1[h[u]]){
		int i = h[u], v = p[i];
		if(!vis[i]){
			vis[i] = vis[i ^ 1] = 1;
			dfs(p[i]);
			st[++ top] = u;
		}
		if(h[u] == -1) break;
	}
}

int main(){
//	freopen("data.in", "r", stdin);
	scanf("%d%d", &n, &m);
	memset(h, -1, sizeof(h));
	int x, y;
	for(int i = 1;i <= m;i ++){
		scanf("%d%d", &x, &y);
		ae(x, y);
		ae(y, x);
		d[x] ++;
		d[y] ++;
	}
	for(int i = 1;i <= n;i ++) if(d[i] & 1) b[++ tot] = i;
	for(int i = 1;i <= tot / 2;i ++){
		ae(b[i * 2 - 1], b[i * 2]);
		ae(b[i * 2], b[i * 2 - 1]);
		++ m;
	}
	if(tot & 1) ae(b[tot], b[tot]), ++ m;
	if(m & 1) ae(1, 1), ++m;
	dfs(1);
	printf("%d\n", m);
	for(int i = 1;i <= top;i ++){
		int u = st[i], v = (i == top) ? st[1] : st[i + 1];
		if(i & 1) swap(u, v);
		printf("%d %d\n", u, v);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define N 100010
#define M 400010

int n, m, h[N], p[M], n1[M], ee, st[N * 4], top, d[N], b[N], tot;
bool vis[M];

void ae(int x, int y){
	p[ee] = y; n1[ee] = h[x]; h[x] = ee ++;
}

void dfs(int u){
	for(;~h[u];h[u] = n1[h[u]]){
		int i = h[u], v = p[i];
		if(!vis[i]){
			vis[i] = vis[i ^ 1] = 1;
			dfs(p[i]);
			st[++ top] = u;
		}
		if(h[u] == -1) break;
	}
}

int main(){
	scanf("%d%d", &n, &m);
	memset(h, -1, sizeof(h));
	int x, y;
	for(int i = 1;i <= m;i ++){
		scanf("%d%d", &x, &y);
		ae(x, y);
		ae(y, x);
		d[x] ++;
		d[y] ++;
	}
	for(int i = 1;i <= n;i ++) if(d[i] & 1) b[++ tot] = i;
	for(int i = 1;i <= tot / 2;i ++){
		ae(b[i * 2 - 1], b[i * 2]);
		ae(b[i * 2], b[i * 2 - 1]);
		++ m;
	}
	if(tot & 1) ae(b[tot], b[tot]), ++ m;
	if(m & 1) ae(1, 1);
	dfs(1);
	for(int i = 1;i <= top;i ++){
		int u = st[i], v = (i == top) ? st[1] : st[i + 1];
		if(i & 1) swap(u, v);
		printf("%d %d\n", u, v);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define N 100010
#define M 400010

int n, m, h[N], p[M], n1[M], ee, st[N * 4], top, d[N], b[N], tot;
bool vis[M];

void ae(int x, int y){
	p[ee] = y; n1[ee] = h[x]; h[x] = ee ++;
}

void dfs(int u){
	for(;~h[u];h[u] = n1[h[u]]){
		int i = h[u], v = p[i];
		if(!vis[i]){
			vis[i] = vis[i ^ 1] = 1;
			dfs(p[i]);
			st[++ top] = u;
		}
		if(h[u] == -1) break;
	}
}

int main(){
	freopen("data.in", "r", stdin);
	scanf("%d%d", &n, &m);
	memset(h, -1, sizeof(h));
	int x, y;
	for(int i = 1;i <= m;i ++){
		scanf("%d%d", &x, &y);
		ae(x, y);
		ae(y, x);
		d[x] ++;
		d[y] ++;
	}
	for(int i = 1;i <= n;i ++) if(d[i] & 1) b[++ tot] = i;
	for(int i = 1;i <= tot / 2;i ++){
		ae(b[i * 2 - 1], b[i * 2]);
		ae(b[i * 2], b[i * 2 - 1]);
		++ m;
	}
	if(tot & 1) ae(b[tot], b[tot]), ++ m;
	if(m & 1) ae(1, 1), ++m;
	dfs(1);
	printf("%d\n", m);
	for(int i = 1;i <= top;i ++){
		int u = st[i], v = (i == top) ? st[1] : st[i + 1];
		if(i & 1) swap(u, v);
		printf("%d %d\n", u, v);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define N 100010
#define M 400010

int n, m, h[N], p[M], n1[M], ee, st[N * 4], top, d[N], b[N], tot;
bool vis[M];

void ae(int x, int y){
	p[ee] = y; n1[ee] = h[x]; h[x] = ee ++;
}

void dfs(int u){
	for(;~h[u];h[u] = n1[h[u]]){
		int i = h[u], v = p[i];
		if(!vis[i]){
			vis[i] = vis[i ^ 1] = 1;
			dfs(p[i]);
			st[++ top] = u;
		}
		if(h[u] == -1) break;
	}
}

int main(){
	scanf("%d%d", &n, &m);
	memset(h, -1, sizeof(h));
	int x, y;
	for(int i = 1;i <= m;i ++){
		scanf("%d%d", &x, &y);
		ae(x, y);
		ae(y, x);
		d[x] ++;
		d[y] ++;
	}
	for(int i = 1;i <= n;i ++) if(d[i] & 1) b[++ tot] = i;
	for(int i = 1;i <= tot / 2;i ++){
		ae(b[i * 2 - 1], b[i * 2]);
		ae(b[i * 2], b[i * 2 - 1]);
		++ m;
	}
	if(tot & 1) ae(b[tot], b[tot]), ++ m;
	if(m & 1) ae(1, 1), ++m;
	dfs(1);
	printf("%d\n", m);
	for(int i = 1;i <= top;i ++){
		int u = st[i], v = (i == top) ? st[1] : st[i + 1];
		if(i & 1) swap(u, v);
		printf("%d %d\n", u, v);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

#define N 1000000

multiset <int> E[N];
int pos;

int grau[N];
int n, m;
vector <int> ans;

void dfs (int v){
	while (E[v].size() > 0){
		int x = *(E[v].begin());
		E[v].erase(E[v].find(x));
		E[x].erase(E[x].find(v));
		dfs (x);
	}
	ans.pb(v);
}

int main (){
	cin >> n >> m;
	f (i, 0, m){
		int x, y; cin >> x >> y;
		x--, y--;
		E[x].insert(y), E[y].insert(x);
		grau[x]++, grau[y]++;
	}
	vector <int> imp;
	f (i, 0, n) if (grau[i]%2 == 1) imp.pb(i);
	for (int i = 0; i < imp.size(); i+=2){
		int x = imp[i], y = imp[i+1];
		E[x].insert(y), E[y].insert(x);
	}
	if ((imp.size()/2+m)%2 == 1) E[0].insert(0), E[0].insert(0), m++;

	dfs(0);
	cout << ans.size()-1 << endl;
	f (i, 0, ans.size()-1){
		if (i%2 == 0) printf("%d %d\n", ans[i]+1, ans[i+1]+1);
		else printf("%d %d\n", ans[i+1]+1, ans[i]+1);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

#define N 1000000

multiset <int> E[N];
int pos;

int grau[N];
int n, m;
vector <int> ans;

void dfs (int v){
	while (E[v].size() > 0){
		int x = *(E[v].begin());
		E[v].erase(E[v].find(x));
		E[x].erase(E[x].find(v));
		dfs (x);
	}
	ans.pb(v);
}

int main (){
	cin >> n >> m;
	f (i, 0, m){
		int x, y; cin >> x >> y;
		x--, y--;
		E[x].insert(y), E[y].insert(x);
		grau[x]++, grau[y]++;
	}
	vector <int> imp;
	f (i, 0, n) if (grau[i]%2 == 1) imp.pb(i);
	for (int i = 0; i < imp.size(); i+=2){
		int x = imp[i], y = imp[i+1];
		E[x].insert(y), E[y].insert(x);
	}
	if ((imp.size()+m)%2 == 1) E[0].insert(0), m++;

	dfs(0);
	cout << m+(int)(imp.size()) << endl;
	ans.pb(ans[0]);
	f (i, 0, ans.size()-1){
		if (i%2 == 0) printf("%d %d\n", ans[i]+1, ans[i+1]+1);
		else printf("%d %d\n", ans[i+1]+1, ans[i]+1);
	}

	return 0;
}


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

#define PB push_back
#define MP make_pair
#define F first
#define S second
using namespace std;

const int MAXN = 100005;

multiset<pair<int, int> > s;
vector<int> v[MAXN];
int in[MAXN], deg[MAXN], od[MAXN], ind, in1, ans[MAXN * 5];

void DFS(int n)
{
	for(int x : v[n])
		if(s.find({min(n, x), max(n, x)}) != s.end())
		{
			s.erase(s.find({min(n, x), max(n, x)}));
			DFS(x);
		}
	ans[in1++] = n + 1;
}

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].PB(b);
		if(a != b)
			v[b].PB(a);
		s.insert({min(a, b), max(a, b)});
		deg[a]++, deg[b]++;
	}
	for(int i = 0; i < n; i++)
		if(deg[i] % 2 == 1)
			od[ind++] = i;
	for(int i = 1; i < ind; i += 2, m++)
	{
		v[od[i]].PB(od[i - 1]), v[od[i - 1]].PB(od[i]);
		s.insert({min(od[i], od[i + 1]), max(od[i + 1], od[i])});
	}
	DFS(0);
	if(m % 2 == 0)
		printf("%d\n", m);
	else
		printf("%d\n", m + 1);
	for(int i = 0; i < in1 - 1; i++)
		if(i % 2 == 0)
		{
			printf("%d %d\n", ans[i], ans[i + 1]);
			in[ans[i + 1]]++;
		}
		else
		{
			printf("%d %d\n", ans[i + 1], ans[i]);
			in[ans[i]]++;
		}
	for(int i = 1; i <= n; i++)
		if(in[i] % 2 == 1)
			printf("%d %d\n", i, i);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>

#define PB push_back
#define MP make_pair
#define F first
#define S second
using namespace std;

const int MAXN = 100005;

map<pair<int, int>, int> mp[MAXN];
vector<int> od, ans;
vector<pair<int, int> > v[MAXN];
int in[MAXN], deg[MAXN];

void DFS(int n)
{
	for(auto x : v[n])
		if(!mp[n][x])
		{
			mp[n][x] = mp[x.F][MP(n, x.S)] = 1;
			DFS(x.F);
		}
	ans.PB(n + 1);
}

int main()
{
	ios::sync_with_stdio(false);
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].PB(MP(b, i));
		if(a != b)
			v[b].PB(MP(a, i));
		deg[a]++, deg[b]++;
	}
	for(int i = 0; i < n; i++)
		if(deg[i] % 2 == 1)
			od.PB(i);
	for(int i = 1; i < od.size(); i += 2, m++)
		v[od[i]].PB(MP(od[i - 1], m)), v[od[i - 1]].PB(MP(od[i], m));
	DFS(0);
	if(m % 2 == 0)
		printf("%d\n", m);
	else
		printf("%d\n", m + 1);
	for(int i = 0; i < ans.size() - 1; i++)
		if(i % 2 == 0)
		{
			printf("%d %d\n", ans[i], ans[i + 1]);
			in[ans[i + 1]]++;
		}
		else
		{
			printf("%d %d\n", ans[i + 1], ans[i]);
			in[ans[i]]++;
		}
	for(int i = 1; i <= n; i++)
		if(in[i] % 2 == 1)
			printf("%d %d\n", i, i);
	return 0;
}


#include<iostream>
#include<algorithm>
#include<vector>
#include<map>

#define PB push_back
#define MP make_pair
#define F first
#define S second
using namespace std;

const int MAXN = 200005;

map<pair<int, int>, int> mp[MAXN];
vector<int> od, ans;
vector<pair<int, int> > v[MAXN];
int in[MAXN], deg[MAXN];

void DFS(int n)
{
	for(auto x : v[n])
		if(!mp[n][x])
		{
			mp[n][x] = mp[x.F][MP(n, x.S)] = 1;
			DFS(x.F);
		}
	ans.PB(n + 1);
}

int main()
{
	int n, m;
	cin >> n >> m;
	for(int i = 0; i < m; i++)
	{
		int a, b;
		cin >> a >> b;
		a--, b--;
		v[a].PB(MP(b, i));
		if(a != b)
			v[b].PB(MP(a, i));
		deg[a]++, deg[b]++;
	}
	for(int i = 0; i < n; i++)
		if(deg[i] % 2 == 1)
			od.PB(i);
	for(int i = 1; i < od.size(); i += 2, m++)
		v[od[i]].PB(MP(od[i - 1], m)), v[od[i - 1]].PB(MP(od[i], m));
	DFS(0);
	if(m % 2 == 0)
		cout << m << endl;
	else
		cout << m + 1 << endl;
	for(int i = 0; i < ans.size() - 1; i++)
		if(i % 2 == 0)
		{
			cout << ans[i] << ' ' << ans[i + 1] << endl;
			in[ans[i + 1]]++;
		}
		else
		{
			cout << ans[i + 1] << ' ' << ans[i] << endl;
			in[ans[i]]++;
		}
	for(int i = 1; i <= n; i++)
		if(in[i] % 2 == 1)
			cout << i << ' ' << i << endl;
	return 0;
}


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

#define PB push_back
#define MP make_pair
#define F first
#define S second
using namespace std;

const int MAXN = 100005;

map<pair<int, int>, int> mp[MAXN];
vector<pair<int, int> > v[MAXN];
int in[MAXN], deg[MAXN], od[MAXN], ind, in1, ans[MAXN * 5];

void DFS(int n)
{
	for(auto x : v[n])
		if(!mp[n][x])
		{
			mp[n][x] = mp[x.F][MP(n, x.S)] = 1;
			DFS(x.F);
		}
	ans[in1++] = n + 1;
}

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].PB(MP(b, i));
		if(a != b)
			v[b].PB(MP(a, i));
		deg[a]++, deg[b]++;
	}
	for(int i = 0; i < n; i++)
		if(deg[i] % 2 == 1)
			od[ind++] = i;
	for(int i = 1; i < ind; i += 2, m++)
		v[od[i]].PB(MP(od[i - 1], m)), v[od[i - 1]].PB(MP(od[i], m));
	DFS(0);
	if(m % 2 == 0)
		printf("%d\n", m);
	else
		printf("%d\n", m + 1);
	for(int i = 0; i < in1 - 1; i++)
		if(i % 2 == 0)
		{
			printf("%d %d\n", ans[i], ans[i + 1]);
			in[ans[i + 1]]++;
		}
		else
		{
			printf("%d %d\n", ans[i + 1], ans[i]);
			in[ans[i]]++;
		}
	for(int i = 1; i <= n; i++)
		if(in[i] % 2 == 1)
			printf("%d %d\n", i, i);
	return 0;
}