#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()
{
	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()
{
	ios::sync_with_stdio(false);
	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<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<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 - 1)), v[od[i - 1]].PB(MP(od[i], m - 1));
	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>
#include<set>

#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].count(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;
}


#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], ind[MAXN];

void DFS(int n)
{
	for(; ind[n] < v[n].size();)
	{
		auto x = v[n][ind[n]];
		ind[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<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 i = v[n].size() - 1; i >= 0; i--)
	{
		int x = v[n][i];
		if(s.find({min(n, x), max(n, x)}) != s.end())
		{
			s.erase(s.find({min(n, x), max(n, x)}));
			v[n].pop_back();
			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 <bits/stdc++.h>

typedef long long int64;
#define sz(A) (int((A).size()))

using namespace std;

void dfs(int u, multiset <int> *&G, int *&res, int &iter)
{
    while (!G[u].empty())
    {
        int to = *G[u].begin();
        G[u].erase(G[u].find(to));

        if (u != to)
            G[to].erase(G[to].find(u));
        dfs(to, G, res, iter);
    }
    res[iter++] = u;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    auto *G = new multiset <int> [n];
    int *deg = new int [n]();

    for (int i = 0; i < n; i++)
        deg[i] = 0;
    int edges = 0;

    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].insert(b);

        if (a != b)
            G[b].insert(a);
        deg[a]++;
        deg[b]++;
        edges++;
    }
    int prev = -1;

    for (int i = 0; i < n; i++)
    {
        if (deg[i] & 1)
        {
            if (prev == -1)
                prev = i;
            else
            {
                G[prev].insert(i);
                G[i].insert(prev);
                deg[i]++;
                deg[prev]++;
                edges++;
                prev = -1;
            }
        }
    }

    if (edges & 1)
        G[0].insert(0), edges++;
    cout << edges << '\n';

    int *res = new int [edges + 1];
    int iter = 0;
    dfs(0, G, res, iter);

    for (int i = 0; i < edges; i++)
        cout << res[i + (i & 1)] + 1 << ' ' << res[i + 1 - (i & 1)] + 1 << '\n';
    return 0;
}


#include <bits/stdc++.h>

typedef long long int64;
#define sz(A) (int((A).size()))

using namespace std;

void dfs(int u, vector <multiset <int> > &G, vector <int> &res)
{
    while (!G[u].empty())
    {
        int to = *G[u].begin();
        G[u].erase(G[u].find(to));

        if (u != to)
            G[to].erase(G[to].find(u));
        dfs(to, G, res);
    }
    res.push_back(u);
}

int main()
{
    ios::sync_with_stdio(0);
//    cin.tie(0);

    int n, m;
    cin >> n >> m;
    vector <multiset <int> > G(n);
    vector <int> deg(n);
    int edges = 0;

    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].insert(b);

        if (a != b)
            G[b].insert(a);
        deg[a]++;
        deg[b]++;
        edges++;
    }
    set <int> V;

    for (int i = 0; i < n; i++)
        if (deg[i] % 2 != 0)
            V.insert(i);

    while (!V.empty())
    {
        int a = *V.begin();
        V.erase(V.begin());
        int b = *V.begin();
        V.erase(V.begin());

        deg[a]++;
        deg[b]++;
        G[a].insert(b);
        G[b].insert(a);
        edges++;
    }

    if (edges % 2)
        G[0].insert(0), edges++;
    cout << edges << '\n';

    vector <int> res;
    dfs(0, G, res);

    for (int i = 0; i < sz(res) - 1; i++)
    {
        if (i % 2 == 0)
            cout << res[i] + 1 << ' ' << res[i + 1] + 1 << '\n';
        else
            cout << res[i + 1] + 1 << ' ' << res[i] + 1 << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>

typedef long long int64;
#define sz(A) (int((A).size()))

using namespace std;

void dfs(int u, vector <multiset <int> > &G, vector <int> &res)
{
    multiset <int> X = G[u];

    for (auto to: X)
    {
        if (G[u].find(to) != G[u].end())
        {
            G[u].erase(G[u].find(to));

            if (u != to)
                G[to].erase(G[to].find(u));
            dfs(to, G, res);
        }
    }
    res.push_back(u);
}

int main()
{
    ios::sync_with_stdio(0);
//    cin.tie(0);

    int n, m;
    cin >> n >> m;
    vector <multiset <int> > G(n);
    vector <int> deg(n);
    int edges = 0;

    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].insert(b);

        if (a != b)
            G[b].insert(a);
        deg[a]++;
        deg[b]++;
        edges++;
    }
    set <int> V;

    for (int i = 0; i < n; i++)
        if (deg[i] % 2 != 0)
            V.insert(i);

    while (!V.empty())
    {
        int a = *V.begin();
        V.erase(V.begin());
        int b = *V.begin();
        V.erase(V.begin());

        deg[a]++;
        deg[b]++;
        G[a].insert(b);
        G[b].insert(a);
        edges++;
    }

    if (edges % 2)
        G[0].insert(0), edges++;
    cout << edges << '\n';

    vector <int> res;
    dfs(0, G, res);

    for (int i = 0; i < sz(res) - 1; i++)
    {
        if (i % 2 == 0)
            cout << res[i] + 1 << ' ' << res[i + 1] + 1 << '\n';
        else
            cout << res[i + 1] + 1 << ' ' << res[i] + 1 << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>

typedef long long int64;
#define sz(A) (int((A).size()))

using namespace std;

void dfs(int u, vector <multiset <int> > &G, vector <int> &res)
{
    while (!G[u].empty())
    {
        int to = *G[u].begin();
        G[u].erase(G[u].find(to));

        if (u != to)
            G[to].erase(G[to].find(u));
        dfs(to, G, res);
    }
    res.push_back(u);
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    vector <multiset <int> > G(n);
    vector <int> deg(n);
    int edges = 0;

    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].insert(b);

        if (a != b)
            G[b].insert(a);
        deg[a]++;
        deg[b]++;
        edges++;
    }
    int prev = -1;

    for (int i = 0; i < n; i++)
    {
        if (deg[i] % 2 != 0)
        {
            if (prev == -1)
                prev = i;
            else
            {
                G[prev].insert(i);
                G[i].insert(prev);
                deg[i]++;
                deg[prev]++;
                edges++;
                prev = -1;
            }
        }
    }

    if (edges % 2)
        G[0].insert(0), edges++;
    cout << edges << '\n';

    vector <int> res;
    dfs(0, G, res);

    for (int i = 0; i < sz(res) - 1; i++)
    {
        if (i % 2 == 0)
            cout << res[i] + 1 << ' ' << res[i + 1] + 1 << '\n';
        else
            cout << res[i + 1] + 1 << ' ' << res[i] + 1 << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int M = 100100;

pair<int, int> operator +(const pair<int, int> &x, const pair<int, int> &y) {
    return make_pair(x.first ^ y.first, x.second ^ y.second);
}

pair<int, int> ZERO(0, 0), ONE(1, 1), ZO(0, 1), OZ(1, 0);

int n;
pair<int, int> a[M];
vector<pair<int, int>> e;
vector<int> g[M];
bool used[M];

void flipEdge(int no) {
    int x = e[no].first, y = e[no].second;
    a[x] = a[x] + ONE;
    a[y] = a[y] + ONE;
    swap(e[no].first, e[no].second);
}

void addEdge(int x, int y) {
    e.emplace_back(x, y);
    a[x].first ^= 1;
    a[y].second ^= 1;
}

void read() {
    int m;
    cin >> n >> m;
    for (int i = 0, x, y; i < m; ++i) {
        cin >> x >> y;
        addEdge(x, y);
    }
}

void pre() {
    vector<int> bad;
    for (int i = 1; i <= n; ++i)
        if (a[i] == ZO || a[i] == OZ)
            bad.push_back(i);

    assert(bad.size() % 2 == 0);
    for (int i = 0; i < (int) bad.size(); i += 2) {
        addEdge(bad[i], bad[i + 1]);
    }

    vector<int> one;
    for (int i = 1; i <= n; ++i)
        if (a[i] == ONE)
            one.push_back(i);

    if (one.size() % 2 == 1) {
        addEdge(one[0], one[0]);
    }
}

void build() {
    for (int i = 0; i < (int) e.size(); ++i) {
        g[e[i].first].push_back(i);
        g[e[i].second].push_back(i);
    }
}

void dfs(int v, int from = -1) {
    used[v] = true;

    for (auto no : g[v]) {
        int to = e[no].first ^ e[no].second ^ v;
        if (used[to])
            continue;
        if (v != e[no].first)
            flipEdge(no);

        dfs(to, no);
        assert(a[to] == ZERO);
    }

    if (a[v] == ONE)
        flipEdge(from);
}

void finish() {
    cout << e.size() << "\n";
    for (auto d : e) {
        cout << d.first << " " << d.second << "\n";
    }
}

void print() {
    for (int i = 1; i <= n; ++i) {
        cerr << i << ": (" << a[i].first << ", " << a[i].second << ")\n";
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    read();
    pre();
    build();
    //print();
    dfs(1);
    //print();
    finish();
    return 0;
}


#include <cstdio>
#include <vector>
using namespace std;
vector<pair<int,int> > graph[100100];
bool dead[400100];
bool step[100100];
int m,n;
bool par;
void solve(int v)
{
    while(!graph[v].empty())
    {
        if (dead[graph[v].back().second])
        {
            graph[v].pop_back();
            continue;
        }
        int u = graph[v].back().first;
        dead[graph[v].back().second] = true;
        graph[v].pop_back();
        solve(u);
        if (par)
            printf("%d %d\n",u,v);
        else
            printf("%d %d\n",v,u);
        par = !par;
    }

}

int main()
{
    scanf("%d %d",&n,&m);
    for (int i = 0; i < m; i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        graph[u].push_back({v,i});
        if (v!=u)
            graph[v].push_back({u,i});
        step[u] = !step[u];
        step[v] = !step[v];
    }
    int ind = -1;
    for(int i = 1; i <= n; i++)
    {
        if (!step[i])
            continue;
       // printf("%d\n",i);
        for (int j = i+1; j <= n; j++)
        {
            if (!step[j])
                continue;
            //printf("l %d %d\n",i,j);
            graph[i].push_back({j,m});
            graph[j].push_back({i,m});
            m++;
            i = j;
            break;
        }
    }
    if (m%2)
        graph[1].push_back({1,m++});
    printf("%d\n",m);
    solve(1);
    return 0;
}
/*
10 20
1 2
1 3
3 4
1 5
2 6
3 7
3 8
5 9
7 10
2 5
5 2
4 7
6 2
2 8
7 7
9 8
1 9
6 10
8 8
6 10
*/


#include <cstdio>
#include <vector>
using namespace std;
vector<pair<int,int> > graph[100100];
bool dead[400100];
bool step[100100];
int m,n;
bool par;
void solve(int v)
{
    while(!graph[v].empty())
    {
        if (dead[graph[v].back().second])
        {
            graph[v].pop_back();
            continue;
        }
        int u = graph[v].back().first;
        dead[graph[v].back().second] = true;
        graph[v].pop_back();
        solve(u);
        if (par)
            printf("%d %d\n",u,v);
        else
            printf("%d %d\n",v,u);
        par = !par;
    }

}

int main()
{
    scanf("%d %d",&n,&m);
    for (int i = 0; i < m; i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        graph[u].push_back({v,i});
        if (v!=u)
            graph[v].push_back({u,i});
        step[u] = !step[u];
        step[v] = !step[v];
    }
    int ind = -1;
    for(int i = 1; i <= n; i++)
    {
        if (!step[i])
            continue;
        for (int j = i+1; j <= n; j++)
        {
            if (!step[j])
                continue;
            graph[i].push_back({j,m});
            graph[j].push_back({i,m});
            m++;
            i = j+1;
            break;
        }
    }
    if (m%2)
        graph[1].push_back({1,m++});
    printf("%d\n",m);
    solve(1);
    return 0;
}


#define debug if(0)
// Grzegorz Guspiel
#include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<int(n);++i)
#define FOR(i,a,b) for (int i=(a); i<(b); ++i)
#define FORD(i,a,b) for (int i=((int)(a))-1; i>=(b); --i)
#define FWD(i,a,b) for (int i=(a); i<(b); ++i)
#define BCK(i,a,b) for (int i=(a); i>(b); --i)
#define SIZE(c) ((int)((c).size()))
#define ALL(v) (v).begin(), (v).end()
#define VAR(v) #v << " " << v << " "
#define pb push_back
#define mp make_pair
#define st first
#define nd second

template<typename T> void maxE(T& a, const T& b) { a = max(a, b); }
template<typename T> void minE(T& a, const T& b) { a = min(a, b); }

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& t_) {
    out << "[";
    for (auto i : t_) out << i << ", ";
    out << "]";
    return out;
}

template<typename S, typename T>
ostream& operator<<(ostream& out, const pair<S, T>& rhs) {
    out << "(" << rhs.st << "," << rhs.nd << ")";
    return out;
}
// CYKL EULERA w grafie eulerowskim O(V+E)

vector<int> s(vector<int> t) {
    REP (i, SIZE(t)) t[i]++;
    return t;
}

const int MAXN = 1100000, MAXM = 11000000; // max liczba wierzcholkow i krawedzi

struct edge {
    int v;
    int back_idx; //TYLKO DLA NIESKIEROWANYCH

    bool vis;     //TYLKO DLA NIESKIEROWANYCH
    edge(int vi):v(vi){
        vis = false; //TYLKO DLA NIESKIEROWANYCH
    }
};

int n;                // IN: liczba wierzcholkow
vector<edge> adj[MAXN]; // IN: lista sasiedztwa (dla skierowanych: do przodu)
int loops[MAXN];
int cc;               // OUT: dlugosc cyklu Eulera
edge *cycle[MAXM];    // OUT: kolejne krawedzie na cyklu Eulera
int cur[MAXN];

stack<edge*>e_stack_;

// aby znalezc sciezke Eulera: dodaj krawedz miedzy
// wierzcholkami o nieparzystym stopniu, znajdz cykl i
// potem usun ta krawedz
void search(int v) {
    while(true){
        if(cur[v] == (int)adj[v].size()) {
            if (!e_stack_.empty()) {
                cycle[cc++] = e_stack_.top();
                e_stack_.pop();
            }
        } else {
            edge *e = &adj[v][cur[v]++];
            if (!e->vis) {                          //TYLKO DLA NIESKIEROWANYCH
                adj[e->v][e->back_idx].vis = true;  //TYLKO DLA NIESKIEROWANYCH
                e_stack_.push(e);                   //TO ZOSTAJE ZAWSZE
            }                                       //TYLKO DLA NIESKIEROWANYCH
        }
        if (e_stack_.empty()) break;
        v = e_stack_.top()->v;
    }
}

void compute_cycle() {
    REP(v,n) cur[v] = 0;
    cc = 0;
    REP(v,n) search(v);
}

void add_edge(int a, int b){
    adj[a].push_back(edge(b));
    adj[b].push_back(edge(a));                   //TYLKO DLA NIESKIEROWANYCH
    adj[a].back().back_idx = adj[b].size()-1;    //TYLKO DLA NIESKIEROWANYCH
    adj[b].back().back_idx = adj[a].size()-1;    //TYLKO DLA NIESKIEROWANYCH
}

int main() {
    int m;
    assert(scanf("%d%d", &n, &m) == 2);
    REP (i, m) {
        int a, b;
        assert(scanf("%d%d", &a, &b) == 2);
        a--; b--;
        if (a == b) {
            loops[a]++;
        } else {
            add_edge(a, b);
        }
    }
    vector<int> oddDeg;
    REP (i, n) if (SIZE(adj[i]) % 2) oddDeg.pb(i);
    for (int i = 0; i < SIZE(oddDeg); i += 2) {
        m++;
        add_edge(oddDeg[i], oddDeg[i + 1]);
    }
    if (m % 2) {
        loops[0]++;
        m++;
    }
    compute_cycle();
    printf("%d\n", m);
    vector<int> mine;
    REP (i, cc) {
        int a = cycle[i]->v;
        while (loops[a]) {
            mine.pb(a);
            loops[a]--;
        }
        mine.pb(a);
    }
    assert(SIZE(mine) == m);
    int dir = 0;
    debug cout << VAR(s(mine)) << endl;
    REP (i, SIZE(mine)) {
        int a = mine[i];
        int b = mine[(i + 1) % SIZE(mine)];
        if (dir) swap(a, b);
        printf("%d %d\n", a + 1, b + 1);
        dir = 1 - dir;
    }
	return 0;
}


#define debug if(1)
// Grzegorz Guspiel
#include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<int(n);++i)
#define FOR(i,a,b) for (int i=(a); i<(b); ++i)
#define FORD(i,a,b) for (int i=((int)(a))-1; i>=(b); --i)
#define FWD(i,a,b) for (int i=(a); i<(b); ++i)
#define BCK(i,a,b) for (int i=(a); i>(b); --i)
#define SIZE(c) ((int)((c).size()))
#define ALL(v) (v).begin(), (v).end()
#define VAR(v) #v << " " << v << " "
#define pb push_back
#define mp make_pair
#define st first
#define nd second

template<typename T> void maxE(T& a, const T& b) { a = max(a, b); }
template<typename T> void minE(T& a, const T& b) { a = min(a, b); }

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& t_) {
    out << "[";
    for (auto i : t_) out << i << ", ";
    out << "]";
    return out;
}

template<typename S, typename T>
ostream& operator<<(ostream& out, const pair<S, T>& rhs) {
    out << "(" << rhs.st << "," << rhs.nd << ")";
    return out;
}

typedef long long LL;

struct S {
    set<int> s1;
    multiset<int> s2;
    void init(int h) {
        s1.insert(0);
        s1.insert(h);
        s2.insert(h);
    }
    void cut(int a) {
        s1.insert(a);
        auto i  = s1.find(a);
        int ap = *--set<int>::iterator(i);
        int an = *++set<int>::iterator(i);
        s2.erase(s2.find(an - ap));
        s2.insert(a - ap);
        s2.insert(an - a);
    }
    int get() {
        return *--s2.end();
    }
};

S sw, sh;

int main() {
    ios_base::sync_with_stdio(0);
    int w, h, n;
    assert(scanf("%d%d%d", &w, &h, &n) == 3);
    sw.init(w);
    sh.init(h);
    REP (i, n) {
        char buf[10];
        int a;
        assert(scanf("%s %d", buf, &a) == 2);
        if (buf[0] == 'H') {
            sh.cut(a);
        } else if (buf[0] == 'V') {
            sw.cut(a);
        } else assert(false);
        cout << ((LL)sw.get()) * sh.get() << endl;
    }
	return 0;
}


#define debug if(0)
// Grzegorz Guspiel
#include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<int(n);++i)
#define FOR(i,a,b) for (int i=(a); i<(b); ++i)
#define FORD(i,a,b) for (int i=((int)(a))-1; i>=(b); --i)
#define FWD(i,a,b) for (int i=(a); i<(b); ++i)
#define BCK(i,a,b) for (int i=(a); i>(b); --i)
#define SIZE(c) ((int)((c).size()))
#define ALL(v) (v).begin(), (v).end()
#define VAR(v) #v << " " << v << " "
#define pb push_back
#define mp make_pair
#define st first
#define nd second

template<typename T> void maxE(T& a, const T& b) { a = max(a, b); }
template<typename T> void minE(T& a, const T& b) { a = min(a, b); }

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& t_) {
    out << "[";
    for (auto i : t_) out << i << ", ";
    out << "]";
    return out;
}

template<typename S, typename T>
ostream& operator<<(ostream& out, const pair<S, T>& rhs) {
    out << "(" << rhs.st << "," << rhs.nd << ")";
    return out;
}
// CYKL EULERA w grafie eulerowskim O(V+E)

vector<int> s(vector<int> t) {
    REP (i, SIZE(t)) t[i]++;
    return t;
}

const int MAXN = 1100000, MAXM = 11000000; // max liczba wierzcholkow i krawedzi

struct edge {
    int v;
    int back_idx; //TYLKO DLA NIESKIEROWANYCH

    bool vis;     //TYLKO DLA NIESKIEROWANYCH
    edge(int vi):v(vi){
        vis = false; //TYLKO DLA NIESKIEROWANYCH
    }
};

int n;                // IN: liczba wierzcholkow
vector<edge> adj[MAXN]; // IN: lista sasiedztwa (dla skierowanych: do przodu)
int loops[MAXN];
int cc;               // OUT: dlugosc cyklu Eulera
edge *cycle[MAXM];    // OUT: kolejne krawedzie na cyklu Eulera
int cur[MAXN];

stack<edge*>e_stack_;

// aby znalezc sciezke Eulera: dodaj krawedz miedzy
// wierzcholkami o nieparzystym stopniu, znajdz cykl i
// potem usun ta krawedz
void search(int v) {
    while(true){
        if(cur[v] == (int)adj[v].size()) {
            if (!e_stack_.empty()) {
                cycle[cc++] = e_stack_.top();
                e_stack_.pop();
            }
        } else {
            edge *e = &adj[v][cur[v]++];
            if (!e->vis) {                          //TYLKO DLA NIESKIEROWANYCH
                adj[e->v][e->back_idx].vis = true;  //TYLKO DLA NIESKIEROWANYCH
                e_stack_.push(e);                   //TO ZOSTAJE ZAWSZE
            }                                       //TYLKO DLA NIESKIEROWANYCH
        }
        if (e_stack_.empty()) break;
        v = e_stack_.top()->v;
    }
}

void compute_cycle() {
    REP(v,n) cur[v] = 0;
    cc = 0;
    REP(v,n) search(v);
}

void add_edge(int a, int b){
    adj[a].push_back(edge(b));
    adj[b].push_back(edge(a));                   //TYLKO DLA NIESKIEROWANYCH
    adj[a].back().back_idx = adj[b].size()-1;    //TYLKO DLA NIESKIEROWANYCH
    adj[b].back().back_idx = adj[a].size()-1;    //TYLKO DLA NIESKIEROWANYCH
}

int main() {
    int m;
    assert(scanf("%d%d", &n, &m) == 2);
    REP (i, m) {
        int a, b;
        assert(scanf("%d%d", &a, &b) == 2);
        a--; b--;
        if (a == b) {
            loops[a]++;
        } else {
            add_edge(a, b);
        }
    }
    vector<int> oddDeg;
    REP (i, n) if (SIZE(adj[i]) % 2) oddDeg.pb(i);
    for (int i = 0; i < SIZE(oddDeg); i += 2) {
        m++;
        add_edge(oddDeg[i], oddDeg[i + 1]);
    }
    if (m % 2) {
        loops[0]++;
        m++;
    }
    compute_cycle();
    printf("%d\n", m);
    vector<int> mine;
    REP (i, cc) {
        int a = cycle[i]->v;
        while (loops[a]) {
            mine.pb(a);
            loops[a]--;
        }
        mine.pb(a);
    }
    if (cc == 0) {
        assert(n == 1);
        REP (i, loops[0]) mine.pb(0);
    }
    assert(SIZE(mine) == m);
    int dir = 0;
    debug cout << VAR(s(mine)) << endl;
    REP (i, SIZE(mine)) {
        int a = mine[i];
        int b = mine[(i + 1) % SIZE(mine)];
        if (dir) swap(a, b);
        printf("%d %d\n", a + 1, b + 1);
        dir = 1 - dir;
    }
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<ctime>
#include<map>
#include<string>
#include<vector>
#include<set>

using namespace std;
#define For(i,l,r) for (int i = l; i <= r; ++i)
#define Cor(i,l,r) for (int i = l; i >= r; --i)
#define Fill(a,b) memset(a,b,sizeof(a))
#define FI first
#define SE second
#define MP make_pair
#define PII pair<int,int>
#define flt double
#define INF (0x3f3f3f3f)
#define MaxN 1020304
#define MaxNode 1020304
#define MD 1000000007
#define next __

long long getLL() {
    long long ret = 0;
    char c;
    while (1) {
        c = getchar();
        if (c >= '0' && c <= '9') break ;
    }
    while (1) {
        ret = ret * 10 + c - '0';
        c = getchar();
        if (c < '0' || c > '9') break ;
    }
    return ret;
}

int getInt() {
    int ret = 0;
    char c;
    while (1) {
        c = getchar();
        if (c >= '0' && c <= '9') break ;
    }
    while (1) {
        ret = ret * 10 + c - '0';
        c = getchar();
        if (c < '0' || c > '9') break ;
    }
    return ret;
}

int v[MaxN], next[MaxN], h[MaxN], tot;
void add(int b, int e) {
    v[++tot] = b; next[tot] = h[e]; h[e] = tot;
    v[++tot] = e; next[tot] = h[b]; h[b] = tot;
}

int n, m, d[MaxN], q[MaxN], who[MaxN], vis[MaxN], fa[MaxN], tmp[MaxN], rev[MaxN];
PII ori[MaxN];
int main() {
    //freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout);
    cin >> n >> m;
    For(i,1,m) {
        int b, e;
        scanf("%d%d", &b, &e);
        add(b, e);
        d[b] ^= 2; d[e] ^= 1;
        ori[i] = MP(b,e);
    }
    int Tot = 0;
    For(i,1,n) if (d[i] != 0 && d[i] != 3) {
        tmp[++Tot] = i;
    }
    if (Tot & 1) while(1);
    vector< PII > ans;
    For(i,1,Tot / 2) {
        ans.push_back({tmp[i], tmp[i + Tot / 2]});
        d[tmp[i]] ^= 2; d[tmp[i + Tot / 2]] ^= 1;
    }
    int hd = 0, tl = 1;
    Fill(vis, 0);
    vis[q[1] = 1] = true;
    while (hd < tl) {
        int vex = q[++hd];
        for (int z = h[vex]; z; z = next[z]) if (!vis[v[z]]) {
            vis[q[++tl] = v[z]] = true;
            fa[v[z]] = vex; who[v[z]] = (z + 1) / 2;
        }
    }
    Cor(i,tl,2) {
        int vex = q[i];
        if (d[vex] == 3) {
            rev[who[vex]] ^= 1; d[vex] ^= 3; d[fa[vex]] ^= 3;
        }
    }
    if (d[1] == 3) {
        ans.push_back({1,1});
    }
    For(i,1,m) if (rev[i]) ans.push_back({ori[i].SE, ori[i].FI}); else ans.push_back(ori[i]);
    cout << ans.size() << endl;
    for (auto x : ans) {
        printf("%d %d\n", x.FI, x.SE);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c)  for(auto &(i) : (c))
#define x     first
#define y     second
#define pb  push_back
#define PB  pop_back()
#define iOS  ios_base::sync_with_stdio(false)
#define sqr(a)  (((a) * (a)))
#define all(a)  a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x)  ((x)<<1)
#define R(x)  (((x)<<1)+1)
#define umap  unordered_map
//#define max(x,y)  ((x) > (y) ? (x) : (y))
#define double long double
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;
const int maxn = 1e5 + 100;
int d[maxn][2], deg[maxn];
vector<int> odd;
vector<pii> ans;
vi adj[maxn];
map <pii, int> mp;
int n,m;
inline void edge(int v,int u){
		d[v][0] ++;
		d[u][1] ++;
		deg[v] ++;
		deg[u] ++;
		mp[{v, u}] ++;
		adj[v].pb(u);
		adj[u].pb(v);
}
bool mark[maxn];
inline void sw(int v,int u){
	mp[{v,u}] --;
	mp[{u,v}] ++;
}
inline void SWAP(int v,int u){
	if(mp[{v,u}])
		sw(v, u);
	else
		sw(u, v);
}
inline void dfs(int v){
	mark[v] = 1;
	rep(u, adj[v]) if(!mark[u]){
		if(d[v][0] % 2)
			SWAP(v,u), d[u][0] ++, d[v][0] ++;
		dfs(u);
	}
}
int main(){
    iOS;
	cin >> n >> m;
	while(m--){
		int v,u;
		cin >> v >> u;
		-- v, -- u;
		edge(v, u);
	}
	For(i,0,n)
		if(deg[i] % 2)
			odd.pb(i);
	for(int i = 0;i < odd.size(); i+= 2){
		int v = odd[i], u = odd[i+1];
		edge(v, u);
	}
	For(i,0,n)
		if(!mark[i])
			dfs(i);
	For(i,0,n)
		if(d[i][0] % 2)
			edge(i, i);
	Foreach(q, mp){
		pii p = q->x;
		For(i,0,mp[p])
			ans.pb(p);
	}
	cout << ans.size() << endl;
	assert(ans.size() % 2 == 0);
	rep(p, ans)
		cout << p.x + 1 << ' ' << p.y + 1 << '\n';

}


#include <bits/stdc++.h>
using namespace std;
#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c)  for(auto &(i) : (c))
#define x     first
#define y     second
#define pb  push_back
#define PB  pop_back()
#define iOS  ios_base::sync_with_stdio(false)
#define sqr(a)  (((a) * (a)))
#define all(a)  a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x)  ((x)<<1)
#define R(x)  (((x)<<1)+1)
#define umap  unordered_map
//#define max(x,y)  ((x) > (y) ? (x) : (y))
#define double long double
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;
const int maxn = 1e5 + 100;
int d[maxn][2], deg[maxn];
vector<int> odd;
vector<pii> ans;
vi adj[maxn];
map <pii, int> mp;
int n,m;
inline void edge(int v,int u){
		d[v][0] ++;
		d[u][1] ++;
		deg[v] ++;
		deg[u] ++;
		mp[{v, u}] ++;
		adj[v].pb(u);
		adj[u].pb(v);
}
bool mark[maxn];
inline void sw(int v,int u){
	mp[{v,u}] --;
	mp[{u,v}] ++;
}
inline void SWAP(int v,int u){
	if(mp[{v,u}])
		sw(v, u);
	else
		sw(u, v);
}
inline void dfs(int v){
	mark[v] = 1;
	rep(u, adj[v]) if(!mark[u]){
		dfs(u);
		if(d[u][0] % 2)
			SWAP(v,u), d[u][0] ++, d[v][0] ++;
	}
}
int main(){
    iOS;
	cin >> n >> m;
	while(m--){
		int v,u;
		cin >> v >> u;
		-- v, -- u;
		edge(v, u);
	}
	For(i,0,n)
		if(deg[i] % 2)
			odd.pb(i);
	for(int i = 0;i < odd.size(); i+= 2){
		int v = odd[i], u = odd[i+1];
		edge(v, u);
	}
	For(i,0,n)
		if(!mark[i])
			dfs(i);
	For(i,0,n)
		if(d[i][0] % 2)
			edge(i, i);
	Foreach(q, mp){
		pii p = q->x;
		For(i,0,mp[p])
			ans.pb(p);
	}
	cout << ans.size() << endl;
	rep(p, ans)
		cout << p.x + 1 << ' ' << p.y + 1 << '\n';

}


#include <bits/stdc++.h>
using namespace std;
#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c)  for(auto &(i) : (c))
#define x     first
#define y     second
#define pb  push_back
#define PB  pop_back()
#define iOS  ios_base::sync_with_stdio(false)
#define sqr(a)  (((a) * (a)))
#define all(a)  a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x)  ((x)<<1)
#define R(x)  (((x)<<1)+1)
#define umap  unordered_map
//#define max(x,y)  ((x) > (y) ? (x) : (y))
#define double long double
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;
const int maxn = 1e5 + 100;
int d[maxn][2], deg[maxn];
vector<int> odd;
vector<pii> ans;
vi adj[maxn];
map <pii, int> mp;
int n,m;
inline void edge(int v,int u){
		d[v][0] ++;
		d[u][1] ++;
		deg[v] ++;
		deg[u] ++;
		mp[{v, u}] ++;
		adj[v].pb(u);
		adj[u].pb(v);
}
bool mark[maxn];
inline void sw(int v,int u){
	mp[{v,u}] --;
	mp[{u,v}] ++;
}
inline void SWAP(int v,int u){
	if(mp[{v,u}])
		sw(v, u);
	else
		sw(u, v);
}
inline void dfs(int v){
	mark[v] = 1;
	rep(u, adj[v]) if(!mark[u]){
		if(d[v][0] % 2)
			SWAP(v,u), d[u][0] ++, d[v][0] ++;
		dfs(u);
	}
}
int main(){
    iOS;
	cin >> n >> m;
	while(m--){
		int v,u;
		cin >> v >> u;
		-- v, -- u;
		edge(v, u);
	}
	For(i,0,n)
		if(deg[i] % 2)
			odd.pb(i);
	for(int i = 0;i < odd.size(); i+= 2){
		int v = odd[i], u = odd[i+1];
		edge(v, u);
	}
	For(i,0,n)
		if(!mark[i])
			dfs(i);
	For(i,0,n)
		if(d[i][0] % 2)
			edge(i, i);
	Foreach(q, mp){
		pii p = q->x;
		For(i,0,mp[p])
			ans.pb(p);
	}
	cout << ans.size() << endl;
	rep(p, ans)
		cout << p.x + 1 << ' ' << p.y + 1 << '\n';

}


#include<cstdio>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<bitset>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<unordered_map>

#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>

using namespace std;

const int nmax = 100005;
const int mmax = 400005;

int n, m, x, y, z, cnt, i, edges, euler[mmax], odd[nmax];

vector<pii> v[nmax];
vector<int> st;
bitset<mmax> viz;

void add_edge(int x, int y, int z)
{
    v[x].pb(mp(y, z));
}

int main()
{
    cin.sync_with_stdio(false);

    cin >> n >> m;

    for(; m; m--)
    {
        cin >> x >> y;
        edges++;
        add_edge(x, y, edges);
        add_edge(y, x, edges);
    }

    for(i = 1; i <= n; i++)
        if(v[i].size() & 1)
            odd[++cnt] = i;

    for(i = 2; i <= cnt; i += 2)
    {
        edges++;
        add_edge(odd[i], odd[i - 1], edges);
        add_edge(odd[i - 1], odd[i], edges);
    }

    if(edges & 1)
    {
        edges++;
        add_edge(1, 1, edges);
        add_edge(1, 1, edges);
    }

    cnt = 0;
    st.pb(1);
    while(!st.empty())
    {
        x = st.back();
        if(!v[x].empty())
        {
            z = v[x].back().se;
            if(!viz[z])
            {
                viz[z] = 1;
                y = v[x].back().fi;
                st.pb(y);
            }
            v[x].pop_back();
        }
        else
        {
            euler[++cnt] = x;
            st.pop_back();
        }
    }

    cout << cnt - 1 << '\n';
    for(i = 2; i <= cnt; i ++)
    {
        if(i & 1) cout << euler[i] << " " << euler[i - 1] << '\n';
        else cout << euler[i - 1] << " " << euler[i] << '\n';
    }

    return 0;
}


#include<cstdio>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<bitset>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<unordered_map>

#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>

using namespace std;

const int nmax = 100005;

int n, m, x, y, cnt, i, edges, euler[nmax], odd[nmax];

vector<int> v[nmax];
vector<int> st;

void add_edge(int x, int y)
{
    v[x].pb(y);
}

void erase_edge(int x, int y)
{
    for(auto &it : v[x])
        if(it == y)
        {
            it = v[x].back();
            v[x].pop_back();
            return;
        }
}

int main()
{
    cin.sync_with_stdio(false);

    cin >> n >> m;

    for(; m; m--)
    {
        cin >> x >> y;
        add_edge(x, y);
        add_edge(y, x);
        edges++;
    }

    for(i = 1; i <= n; i++)
        if(v[i].size() & 1)
            odd[++cnt] = i;

    for(i = 2; i <= cnt; i += 2)
    {
        add_edge(odd[i], odd[i - 1]);
        add_edge(odd[i - 1], odd[i]);
        edges++;
    }

    if(edges & 1)
    {
        add_edge(1, 1);
        add_edge(1, 1);
    }

    cnt = 0;
    st.pb(1);
    while(!st.empty())
    {
        x = st.back();
        if(!v[x].empty())
        {
            y = v[x].back();
            erase_edge(x, y);
            erase_edge(y, x);
            st.pb(y);
        }
        else
        {
            euler[++cnt] = x;
            st.pop_back();
        }
    }

    cout << cnt - 1 << '\n';
    for(i = 2; i <= cnt; i ++)
    {
        if(i & 1) cout << euler[i] << " " << euler[i - 1] << '\n';
        else cout << euler[i - 1] << " " << euler[i] << '\n';
    }

    return 0;
}


#include<cstdio>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<bitset>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<unordered_map>

#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>

using namespace std;

const int nmax = 100005;
const int mmax = 200005;

int n, m, x, y, cnt, i, edges, euler[mmax], odd[nmax];

vector<int> v[nmax];
vector<int> st;

void add_edge(int x, int y)
{
    v[x].pb(y);
}

void erase_edge(int x, int y)
{
    for(auto &it : v[x])
        if(it == y)
        {
            it = v[x].back();
            v[x].pop_back();
            return;
        }
}

int main()
{
    cin.sync_with_stdio(false);

    cin >> n >> m;

    for(; m; m--)
    {
        cin >> x >> y;
        add_edge(x, y);
        add_edge(y, x);
        edges++;
    }

    for(i = 1; i <= n; i++)
        if(v[i].size() & 1)
            odd[++cnt] = i;

    for(i = 2; i <= cnt; i += 2)
    {
        add_edge(odd[i], odd[i - 1]);
        add_edge(odd[i - 1], odd[i]);
        edges++;
    }

    if(edges & 1)
    {
        add_edge(1, 1);
        add_edge(1, 1);
    }

    cnt = 0;
    st.pb(1);
    while(!st.empty())
    {
        x = st.back();
        if(!v[x].empty())
        {
            y = v[x].back();
            erase_edge(x, y);
            erase_edge(y, x);
            st.pb(y);
        }
        else
        {
            euler[++cnt] = x;
            st.pop_back();
        }
    }

    cout << cnt - 1 << '\n';
    for(i = 2; i <= cnt; i ++)
    {
        if(i & 1) cout << euler[i] << " " << euler[i - 1] << '\n';
        else cout << euler[i - 1] << " " << euler[i] << '\n';
    }

    return 0;
}


#include<cstdio>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<bitset>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<unordered_map>

#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>

using namespace std;

const int nmax = 100005;
const int mmax = 400005;

int n, m, x, y, cnt, i, edges, euler[mmax], odd[nmax];

vector<int> v[nmax];
vector<int> st;

void add_edge(int x, int y)
{
    v[x].pb(y);
}

void erase_edge(int x, int y)
{
    for(auto &it : v[x])
        if(it == y)
        {
            it = v[x].back();
            v[x].pop_back();
            return;
        }
}

int main()
{
    cin.sync_with_stdio(false);

    cin >> n >> m;

    for(; m; m--)
    {
        cin >> x >> y;
        add_edge(x, y);
        add_edge(y, x);
        edges++;
    }

    for(i = 1; i <= n; i++)
        if(v[i].size() & 1)
            odd[++cnt] = i;

    for(i = 2; i <= cnt; i += 2)
    {
        add_edge(odd[i], odd[i - 1]);
        add_edge(odd[i - 1], odd[i]);
        edges++;
    }

    if(edges & 1)
    {
        add_edge(1, 1);
        add_edge(1, 1);
    }

    cnt = 0;
    st.pb(1);
    while(!st.empty())
    {
        x = st.back();
        if(!v[x].empty())
        {
            y = v[x].back();
            erase_edge(x, y);
            erase_edge(y, x);
            st.pb(y);
        }
        else
        {
            euler[++cnt] = x;
            st.pop_back();
        }
    }

    cout << cnt - 1 << '\n';
    for(i = 2; i <= cnt; i ++)
    {
        if(i & 1) cout << euler[i] << " " << euler[i - 1] << '\n';
        else cout << euler[i - 1] << " " << euler[i] << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define int long long

#define ff first
#define ss second
#define mp make_pair
#define sqr(x) ((x)*(x))

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

const int maxN = 200 * 1000;

int n, m;
vector <pie> a[maxN];

int mark[maxN];
int idx[maxN], out[maxN];
vector <int> tour;
vector <pie> ans;

void dfs (int v) {
	for (; idx[v] < a[v].size(); idx[v]++) {
		if (mark[a[v][idx[v]].ss]) continue;
		mark[a[v][idx[v]].ss] = 1;
		out[v] ^= 1;
		dfs (a[v][idx[v]].ff);
	}
	tour.push_back (v);
}

main() {
	ios::sync_with_stdio (false);

	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int x, y; cin >> x >> y; x--; y--;
		a[x].push_back (pie (y, i));
		a[y].push_back (pie (x, i));
	}

	int o = -1;
	for (int i = 0; i < n; i++)
		if (a[i].size() % 2) {
			if (o == -1) o = i;
			else
				a[o].push_back (pie (i, m)),
				a[i].push_back (pie (o, m++)),
				o = -1;
		}

	dfs (0);

	for (int i = 1; i < tour.size(); i++) {
		int x = tour[i - 1], y = tour[i];
		if (out[x]) {
			ans.push_back (pie (y, x));
			out[x] ^= 1, out[y] ^= 1;
		}
		else
			ans.push_back (pie (x, y));
	}

	for (int i = 0; i < n; i++)
		if (out[i])
			ans.push_back (pie (i, i));

	cout << ans.size() << endl;
	for (auto x : ans)
		cout << x.ff + 1 << ' ' << x.ss + 1 << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define int long long

#define ff first
#define ss second
#define mp make_pair
#define sqr(x) ((x)*(x))

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

const int maxN = 500 * 1000 + 1000;

int n, m;
vector <pie> a[maxN];

int mark[maxN];
int idx[maxN], out[maxN];
vector <int> tour;
vector <pie> ans;

void dfs (int v) {
	for (; idx[v] < a[v].size(); idx[v]++) {
		if (mark[a[v][idx[v]].ss]) continue;
		mark[a[v][idx[v]].ss] = 1;
		out[v] ^= 1;
		dfs (a[v][idx[v]].ff);
	}
	tour.push_back (v);
}

main() {
	ios::sync_with_stdio (false);

	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int x, y; cin >> x >> y; x--; y--;
		a[x].push_back (pie (y, i));
		a[y].push_back (pie (x, i));
	}

	int o = -1;
	for (int i = 0; i < n; i++)
		if (a[i].size() % 2) {
			if (o == -1) o = i;
			else
				a[o].push_back (pie (i, m)),
				a[i].push_back (pie (o, m++)),
				o = -1;
		}

	dfs (0);

	for (int i = 1; i < tour.size(); i++) {
		int x = tour[i - 1], y = tour[i];
		if (out[x]) {
			ans.push_back (pie (y, x));
			out[x] ^= 1, out[y] ^= 1;
		}
		else
			ans.push_back (pie (x, y));
	}

	for (int i = 0; i < n; i++)
		if (out[i])
			ans.push_back (pie (i, i));

	cout << ans.size() << endl;
	for (auto x : ans)
		cout << x.ff + 1 << ' ' << x.ss + 1 << endl;

	return 0;
}


#include <iostream>
#include <unordered_set>
#include <vector>
#define F first
#define S second
using namespace std;
const int MN = 2e5+1000;
int t[MN];
unordered_multiset<int> st[MN];
int ans[5*MN];
int ansPos = 0;
void f(int x) {
    while(st[x].size()) {
        int y = *st[x].begin();
        st[x].erase(st[x].begin());
        st[y].erase(st[y].find(x));
        f(y);
    }
    ans[ansPos] = x;
    ++ansPos;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n,m;
    cin>>n>>m;
    vector<pair<int, int> > v(m);
    int cnt = 0;
    for(int i = 0; i < m; ++i) {
        int q,w;
        cin>>q>>w;
        ++t[q];
        ++t[w];
        ++cnt;
        st[q].insert(w);
        st[w].insert(q);
    }
    vector<int> v2;
    int lol = 0;
    for(int i = 0; i < MN; ++i) {
        if(t[i] % 2 == 1) {
            v2.push_back(i);
        }
        else if(t[i]){
            lol = i;
        }
    }
    for(int i = 0; i < (int)v2.size()-1; i += 2) {
        /*if(i == (int)v2.size()-2 && cnt % 2 == 0) {
            st[v2[i]].insert(lol);
            st[lol].insert(v2[i]);
            st[v2[i+1]].insert(lol);
            st[lol].insert(v2[i+1]);

        }
        else {
            */
            lol = v2[i];
            ++cnt;
            st[v2[i]].insert(v2[i+1]);
            st[v2[i+1]].insert(v2[i]);
        //}
    }
    if(cnt % 2 == 1) {
        st[1].insert(1);
        st[1].insert(1);
    }
    f(1);
    cout<<ansPos-1<<'\n';
    for(int i = 0; i < ansPos-1; ++i) {
        if(i % 2 == 0) {
            cout<<ans[i]<<' '<<ans[i+1]<<'\n';
        }
        else {
            cout<<ans[i+1]<<' '<<ans[i]<<'\n';
        }
    }

}


#include <iostream>
#include <unordered_set>
#include <vector>
#define F first
#define S second
using namespace std;
const int MN = 2e5+1000;
int t[MN];
unordered_multiset<int> st[MN];
int ans[5*MN];
int ansPos = 0;
void f(int x) {
    while(st[x].size()) {
        int y = *st[x].begin();
        st[x].erase(st[x].begin());
        st[y].erase(st[y].find(x));
        f(y);
    }
    ans[ansPos] = x;
    ++ansPos;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n,m;
    cin>>n>>m;
    vector<pair<int, int> > v(m);
    int cnt = 0;
    for(int i = 0; i < m; ++i) {
        int q,w;
        cin>>q>>w;
        ++t[q];
        ++t[w];
        ++cnt;
        st[q].insert(w);
        st[w].insert(q);
    }
    vector<int> v2;
    int lol = 0;
    for(int i = 0; i < MN; ++i) {
        if(t[i] % 2 == 1) {
            v2.push_back(i);
        }
        else if(t[i]){
            lol = i;
        }
    }
    for(int i = 0; i < (int)v2.size()-1; ++i) {
        if(i == (int)v2.size()-2 && cnt % 2 == 0) {
            st[v2[i]].insert(lol);
            st[lol].insert(v2[i]);
            st[v2[i+1]].insert(lol);
            st[lol].insert(v2[i+1]);

        }
        else {
            lol = v2[i];
            ++cnt;
            st[v2[i]].insert(v2[i+1]);
            st[v2[i+1]].insert(v2[i]);
        }
    }
    f(1);
    cout<<ansPos-1<<'\n';
    for(int i = 0; i < ansPos-1; ++i) {
        if(i % 2 == 0) {
            cout<<ans[i]<<' '<<ans[i+1]<<'\n';
        }
        else {
            cout<<ans[i+1]<<' '<<ans[i]<<'\n';
        }
    }

}


#include <iostream>
#include <unordered_set>
#include <vector>
#define F first
#define S second
using namespace std;
const int MN = 2e5+1000;
int t[MN];
unordered_multiset<int> st[MN];
int ans[5*MN];
int ansPos = 0;
void f(int x) {
    while(st[x].size()) {
        int y = *st[x].begin();
        st[x].erase(st[x].begin());
        st[y].erase(st[y].find(x));
        f(y);
    }
    ans[ansPos] = x;
    ++ansPos;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n,m;
    cin>>n>>m;
    vector<pair<int, int> > v(m);
    int cnt = 0;
    for(int i = 0; i < m; ++i) {
        int q,w;
        cin>>q>>w;
        ++t[q];
        ++t[w];
        ++cnt;
        st[q].insert(w);
        st[w].insert(q);
    }
    vector<int> v2;
    int lol = 0;
    for(int i = 0; i < MN; ++i) {
        if(t[i] % 2 == 1) {
            v2.push_back(i);
        }
        else if(t[i]){
            lol = i;
        }
    }
    for(int i = 0; i < (int)v2.size()-1; ++i) {
        /*if(i == (int)v2.size()-2 && cnt % 2 == 0) {
            st[v2[i]].insert(lol);
            st[lol].insert(v2[i]);
            st[v2[i+1]].insert(lol);
            st[lol].insert(v2[i+1]);

        }
        else {
            */
            lol = v2[i];
            ++cnt;
            st[v2[i]].insert(v2[i+1]);
            st[v2[i+1]].insert(v2[i]);
        //}
    }
    if(cnt % 2 == 1) {
        st[1].insert(1);
        st[1].insert(1);
    }
    f(1);
    cout<<ansPos-1<<'\n';
    for(int i = 0; i < ansPos-1; ++i) {
        if(i % 2 == 0) {
            cout<<ans[i]<<' '<<ans[i+1]<<'\n';
        }
        else {
            cout<<ans[i+1]<<' '<<ans[i]<<'\n';
        }
    }

}


#include <bits/stdc++.h>

using namespace std;
const int N = 500005;
pair<int, int> kr[N];
int st[N];
bool odw[N];
vector<pair<int, int> > V[N];
vector<int> stos;
int n, m;
vector<pair<int, int > >results;
void DFS(int w) {
    while(!V[w].empty()) {
        int u = V[w].back().first;
        int in = V[w].back().second;
        V[w].pop_back();
        if(odw[in] == false) {
            odw[in] = true;
            DFS(u);
            stos.push_back(u);
        }
    }
}

int main() {

    scanf("%d %d", &n, &m);
    for(int i = 1; i <= m; i++) {
        scanf("%d %d", &kr[i].first, &kr[i].second);
        int a = kr[i].first;
        int b = kr[i].second;
        st[a]++;
        st[b]++;
    }

    vector<int> nieparzysci;
    for(int i = 1; i <= n; i++) {
        if(st[i] % 2 == 1) {
            nieparzysci.push_back(i);
        }
    }
    for(int i = 0; i < nieparzysci.size(); i += 2) {
        kr[++m].first = nieparzysci[i];
        kr[m].second = nieparzysci[i + 1];
    }

    for(int i = 1; i <= m; i++) {
        int a = kr[i].first;
        int b = kr[i].second;
        V[a].push_back({b, i});
        V[b].push_back({a, i});
    }
    DFS(1);
    stos.push_back(1);
    printf("%d\n", m + m % 2);
    if(m % 2) {
        printf("1 1\n");
    }
    for(int i = 0; i < stos.size() - 1; i++) {
        if(i % 2 == 0) {
            printf("%d %d\n", stos[i], stos[i + 1]);
        } else {
            printf("%d %d\n", stos[i + 1], stos[i]);
        }
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> g[100010];
int use[100010];

int a[1000010], b[1000010], way[1000010];
int in[100010], out[100010], dp[100010];

void dfs(int u, int pu) {
    dp[u] = 0;
    use[u] = 1;
    if (in[u] % 2 == 1 && out[u] % 2 == 1) {
        dp[u] = 1;
    }
    for (auto id : g[u]) {
        int uu = a[id], vv = b[id];
        if (use[uu] && use[vv]) {
            continue;
        }
        if (vv == u) {
            swap(uu, vv);
        }
        dfs(vv, u);
        if (dp[vv] % 2 == 1) {
            way[id] = 1 - way[id];
        }
        dp[u] += dp[vv];
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i ++) {
        scanf("%d%d", &a[i], &b[i]);
        way[i] = 0;
        out[a[i]] ++;
        in[b[i]] ++;
        g[a[i]].push_back(i);
        g[b[i]].push_back(i);
    }
    int ecnt = m;
    vector<int> odds;
    for (int i = 1; i <= n; i ++) {
        if ((in[i] + out[i]) % 2 == 1) {
            odds.push_back(i);
        }
    }
    for (int i = 0; i < odds.size(); i += 2) {
        a[ecnt] = odds[i];
        b[ecnt ++] = odds[i + 1];
        out[odds[i]] ++;
        in[odds[i + 1]] ++;
    }
    int id = 1;
    int cnt = 0;
    for (int i = 1; i <= n; i ++) {
        if (in[i] % 2 == 1 && out[i] % 2 == 1) {
            id = i;
            cnt ++;
        }
    }
    use[id] = 1;
    dfs(id, -1);
    if (cnt % 2 == 1) {
        a[ecnt] = id;
        b[ecnt ++] = id;
    }
    printf("%d\n", ecnt);
    for (int i = 0; i < ecnt; i ++) {
        if (way[i] == 1) {
            printf("%d %d\n", b[i], a[i]);
        } else {
            printf("%d %d\n", a[i], b[i]);
        }
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> g[100010];
int use[100010];

int a[1000010], b[1000010], way[1000010];
int in[100010], out[100010], dp[100010];

void dfs(int u, int pu) {
    use[u] = 1;
    dp[u] = 0;
    if (in[u] % 2 == 1 && out[u] % 2 == 1) {
        dp[u] = 1;
    }
    for (auto id : g[u]) {
        int uu = a[id], vv = b[id];
        if (use[uu] && use[vv]) {
            continue;
        }
        if (vv == u) {
            swap(uu, vv);
        }
        if (use[vv]) {
            continue;
        }
        dfs(vv, u);
        if (dp[vv] % 2 == 1) {
            way[id] = 1 - way[id];
        }
        dp[u] += dp[vv];
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i ++) {
        scanf("%d%d", &a[i], &b[i]);
        way[i] = 0;
        out[a[i]] ++;
        in[b[i]] ++;
        g[a[i]].push_back(i);
        g[b[i]].push_back(i);
    }
    int ecnt = m;
    int id = 1;
    int cnt = 0;
    for (int i = 1; i <= n; i ++) {
        if (in[i] % 2 == 1 && out[i] % 2 == 1) {
            id = i;
            cnt ++;
        }
    }
    dfs(id, -1);
    if (cnt % 2 == 1) {
        a[ecnt] = id;
        b[ecnt ++] = id;
    }
    vector<int> t1, t2;
    for (int i = 1; i <= n; i ++) {
        if (in[i] % 2 == 0 && out[i] % 2 == 1) {
            t1.push_back(i);
        } else if (in[i] % 2 == 1 && out[i] % 2 == 0) {
            t2.push_back(i);
        }
    }
    for (int i = 0; i < t1.size(); i ++) {
        a[ecnt] = t1[i];
        b[ecnt ++] = t2[i];
    }
    printf("%d\n", ecnt);
    for (int i = 0; i < ecnt; i ++) {
        if (way[i] == 1) {
            printf("%d %d\n", b[i], a[i]);
        } else {
            printf("%d %d\n", a[i], b[i]);
        }
    }
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <complex>
#include <map>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<pii> vii;
typedef vector<string> vs;

vi euler(const vii & edges, int n) {
	vector < vector<int> > gr (n);
	vector < vector<int> > gre (n);
    vvi e;
    vector<int> deg (n);
    vi t(4);
    for (int i = 0; i < edges.size(); ++i) {
        int a = edges[i].first, b = edges[i].second;
        t[0] = a; t[1] = b; t[2] = deg[a]; t[3] = deg[b];
        if (a == b) ++t[3];
        e.push_back(t);
        ++deg[a];
        ++deg[b];
        gr[a].push_back(b);
        gr[b].push_back(a);
        gre[a].push_back(e.size() - 1);
        gre[b].push_back(e.size() - 1);
    }
	int first = 0;
	stack<int> st;
	st.push (first);
	vector<int> res;
    vvi was(n);
    vi it(n);
    for (int i = 0; i < n; ++i) was[i].assign(deg[i], 0);
	while (!st.empty())
	{
		int v = st.top();
		for (; it[v] < deg[v]; ++it[v])
			if (was[v][it[v]] == 0)
				break;
		if (it[v] == deg[v])
		{
			res.push_back (v);
			st.pop();
		}
		else
		{
            int ei = gre[v][it[v]];
            for (int t = 0; t < 2; ++t) {
                was[e[ei][t]][e[ei][t+2]] = 1;
            }
            assert(was[v][it[v]]);
			st.push (gr[v][it[v]]);
		}
	}
    return res;
}

int main() {
	int n, m;
    scanf("%d%d", &n, &m);
    vii edges(m);
    vi deg(n);
    for (int i = 0; i < m; ++i) {
        int a,b;
        scanf("%d%d", &a, &b);
        --a; --b;
        edges[i] = pii(a, b);
        ++deg[a]; ++deg[b];
    }
    int prev = -1;
    for (int i = 0; i < n; ++i) if (deg[i] % 2) {
        if (prev == -1) prev = i;
        else {
            ++deg[i];
            ++deg[prev];
            edges.push_back(pii(i, prev));
            prev = -1;
            ++m;
        }
    }
    if (m % 2) {
        edges.push_back(pii(0,0));
        ++m;
    }
    vi res = euler(edges, n);
    printf ("%d\n", (int)res.size() - 1);
    for (size_t i=0; i+1<res.size(); ++i) {
        if (i % 2) printf ("%d %d\n", res[i]+1, res[i+1] + 1);
        else printf ("%d %d\n", res[i+1]+1, res[i] + 1);
    }
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <complex>
#include <map>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<pii> vii;
typedef vector<string> vs;

vi euler(const vii & edges, int n) {
	vector < vector<int> > gr (n);
	vector < vector<int> > gre (n);
    vi t(4);
    for (int i = 0; i < edges.size(); ++i) {
        int a = edges[i].first, b = edges[i].second;
        gr[a].push_back(b);
        gr[b].push_back(a);
        gre[a].push_back(i);
        gre[b].push_back(i);
    }
	int first = 0;
	stack<int> st;
	st.push (first);
	vi res;
    vi used(edges.size());
    vi it(n);
	while (!st.empty())
	{
		int v = st.top();
		for (; it[v] < gr[v].size(); ++it[v])
			if (used[gre[v][it[v]]] == 0)
				break;
		if (it[v] == gr[v].size())
		{
			res.push_back (v);
			st.pop();
		}
		else
		{
            used[gre[v][it[v]]] = 1;
			st.push (gr[v][it[v]]);
		}
	}
    return res;
}

int main() {
	int n, m;
    scanf("%d%d", &n, &m);
    vii edges(m);
    vi deg(n);
    for (int i = 0; i < m; ++i) {
        int a,b;
        scanf("%d%d", &a, &b);
        --a; --b;
        edges[i] = pii(a, b);
        ++deg[a]; ++deg[b];
    }
    int prev = -1;
    for (int i = 0; i < n; ++i) if (deg[i] % 2) {
        if (prev == -1) prev = i;
        else {
            ++deg[i];
            ++deg[prev];
            edges.push_back(pii(i, prev));
            prev = -1;
            ++m;
        }
    }
    if (m % 2) {
        edges.push_back(pii(0,0));
        ++m;
    }
    vi res = euler(edges, n);
    printf ("%d\n", (int)res.size() - 1);
    for (size_t i=0; i+1<res.size(); ++i) {
        if (i % 2) printf ("%d %d\n", res[i]+1, res[i+1] + 1);
        else printf ("%d %d\n", res[i+1]+1, res[i] + 1);
    }
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <complex>
#include <map>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<pii> vii;
typedef vector<string> vs;

int main() {
	int n, m;
    scanf("%d%d", &n, &m);
	vector < vector<int> > gr (n);
	vector < vector<int> > gre (n);
    vvi e;
    vector<int> deg (n);
    vi t(4);
    for (int i = 0; i < m; ++i) {
        int a,b;
        scanf("%d%d", &a, &b);
        --a; --b;
        t[0] = a; t[1] = b; t[2] = deg[a]; t[3] = deg[b];
        if (a == b) ++t[3];
        e.push_back(t);
        ++deg[a];
        ++deg[b];
        gr[a].push_back(b);
        gr[b].push_back(a);
        gre[a].push_back(e.size() - 1);
        gre[b].push_back(e.size() - 1);
    }
    int prev = -1;
    for (int i = 0; i < n; ++i) if (deg[i] % 2) {
        if (prev == -1) prev = i;
        else {
            t[0] = i; t[1] = prev; t[2] = deg[i]; t[3] = deg[prev];
            e.push_back(t);
            ++deg[i];
            ++deg[prev];
            gr[i].push_back(prev);
            gr[prev].push_back(i);
            gre[i].push_back(e.size() - 1);
            gre[prev].push_back(e.size() - 1);
            prev = -1;
            ++m;
        }
    }
    if (m % 2) {
        t[0] = 0; t[1] = 0; t[2] = deg[0]; t[3] = deg[0] + 1;
        e.push_back(t);
        deg[0] += 2;
        gre[0].push_back(e.size() - 1);
        gre[0].push_back(e.size() - 1);
        gr[0].push_back(0);
        gr[0].push_back(0);
        ++m;
    }
	int first = 0;
	stack<int> st;
	st.push (first);
	vector<int> res;
    vvi was(n);
    vi it(n);
    for (int i = 0; i < n; ++i) was[i].assign(deg[i], 0);
	while (!st.empty())
	{
		int v = st.top();
		for (; it[v] < deg[v]; ++it[v])
			if (was[v][it[v]] == 0)
				break;
		if (it[v] == deg[v])
		{
			res.push_back (v);
			st.pop();
		}
		else
		{
            int ei = gre[v][it[v]];
            for (int t = 0; t < 2; ++t) {
                was[e[ei][t]][e[ei][t+2]] = 1;
            }
            assert(was[v][it[v]]);
			st.push (gr[v][it[v]]);
		}
	}

    printf ("%d\n", (int)res.size() - 1);
    for (size_t i=0; i+1<res.size(); ++i) {
        if (i % 2) printf ("%d %d\n", res[i]+1, res[i+1] + 1);
        else printf ("%d %d\n", res[i+1]+1, res[i] + 1);
    }
    return 0;
}


//#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <string>
#include <cmath>
#include <cassert>
#include <ctime>
#include <algorithm>
#include <sstream>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <iterator>
#include <functional>
#include <bitset>
#define mp make_pair
#define pb push_back

#ifdef LOCAL
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#else
#define eprintf(...)
#endif

#define TIMESTAMP(x) eprintf("["#x"] Time : %.3lf s.\n", clock()*1.0/CLOCKS_PER_SEC)
#define TIMESTAMPf(x,...) eprintf("[" x "] Time : %.3lf s.\n", __VA_ARGS__, clock()*1.0/CLOCKS_PER_SEC)

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define LLD "%I64d"
#else
    #define LLD "%lld"
#endif

using namespace std;

#define TASKNAME "C"

#ifdef LOCAL
static struct __timestamper {
    string what;
    __timestamper(const char* what) : what(what){};
    __timestamper(const string& what) : what(what){};
    ~__timestamper(){
        TIMESTAMPf("%s", what.data());
    }
} __TIMESTAMPER("end");
#else
struct __timestamper {};
#endif

typedef long long ll;
typedef long double ld;

const int MAXN = 210000;

vector<int> g[MAXN];
int loopscnt[MAXN];
vector<int> used;
int degin[MAXN];
int degout[MAXN];

void fix(int v, int u){
  if (degout[v] % 2 == 1){
    swap(u, v);
  }
  printf("%d %d\n", u + 1, v + 1);
  degin[v]++;
  degout[u]++;
}

void dfs(int v){
  int up = -1;
  used[v] = 1;
  for (auto u : g[v]){
    if (used[u] == 0){
      dfs(u);
      continue;
    }
    if (used[u] == 1){
      if (up == -1){
        up = u;
        continue;
      }
      fix(v, u);
    }
  }
  if (up != -1){
    fix(v, up);
  }
  assert(degin[v] % 2 == 0);
  assert(degout[v] % 2 == 0);
  used[v] = 2;
}

int main(){
  #ifdef LOCAL
    assert(freopen(TASKNAME".in","r",stdin));
    assert(freopen(TASKNAME".out","w",stdout));
  #endif

  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;
    if (a == b){
      loopscnt[a]++;
    } else {
      g[a].pb(b);
      g[b].pb(a);
    }
  }

  int last = -1;
  for (int i = 0; i < n; i++){
    if (g[i].size() % 2 == 1){
      if (last == -1) last = i;
      else {
        g[last].pb(i);
        g[i].pb(last);
        m++;
        last = -1;
      }
    }
  }
  assert(last == -1);
  if (m % 2 == 1){
    loopscnt[0]++;
    m++;
  }
  printf("%d\n", m);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < loopscnt[i]; j++){
      printf("%d %d\n", i + 1, i + 1);
      degin[i]++;
      degout[i]++;
    }
  used.resize(n);
  dfs(0);
  return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>

using namespace std;

typedef pair<int, int> PP;
typedef long long LL;
#define pb push_back
#define fr first
#define sc second

int m, n;
int tot;
int cnt = 0;

multiset<int> s[100010];
stack<int> q;
vector<int> p;
int d[100010];

void f(int x) {
    if (s[x].empty()) {
        p.pb(x);
        if (q.empty()) return;
        int pre = q.top(); q.pop();
        f(pre);
    }
    else {
        q.push(x);
        int nxt = *s[x].begin();
        s[x].erase(s[x].find(nxt));
        if (nxt != x) s[nxt].erase(s[nxt].find(x));
        f(nxt);
    }
}

int main() {
    #ifdef _TEST_
    freopen("input.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    #endif
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i ++) {
        int u, v; scanf("%d%d", &u, &v); u --; v --;
        d[u] ++; d[v] ++;
        s[u].insert(v); if (v != u) s[v].insert(u);
    }
    int last = -1;
    for (int i = 0; i < n; i ++) {
        if (d[i] & 1) {
            if (last >= 0) {
                s[i].insert(last); s[last].insert(i);
                last = -1;
            }
            else {
                last = i;
            }
        }
    }
    f(0);
    if (p.size() == 1) {
        cout << 0 << endl;
        return 0;
    }
    if ((p.size() & 1) == 0) {
        p.pb(p[0]);
    }

    cout << p.size() - 1 << endl;
    for (int i = 0; i < p.size() - 1; i ++) {
        //cout <<
        if (i & 1) cout << p[i] + 1 << ' ' << p[i + 1] + 1 << endl;
        else cout << p[i + 1] + 1 << ' ' << p[i] + 1 << endl;
    }
    return 0;

}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>

using namespace std;

typedef pair<int, int> PP;
typedef long long LL;
#define pb push_back
#define fr first
#define sc second

int m, n;
int tot;
int cnt = 0;

multiset<int> s[100010];
stack<int> q;
vector<int> p;
int d[100010];

void f(int x) {
    if (s[x].empty()) {
        p.pb(x);
        if (q.empty()) return;
        int pre = q.top(); q.pop();
        f(pre);
    }
    else {
        q.push(x);
        int nxt = *s[x].begin();
        s[x].erase(nxt);
        if (nxt != x) s[nxt].erase(x);
        f(nxt);
    }
}

int main() {
    #ifdef _TEST_
    freopen("input.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    #endif
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i ++) {
        int u, v; scanf("%d%d", &u, &v); u --; v --;
        d[u] ++; d[v] ++;
        s[u].insert(v); if (v != u) s[v].insert(u);
    }
    int last = -1;
    for (int i = 0; i < n; i ++) {
        if (d[i] & 1) {
            if (last >= 0) {
                s[i].insert(last); s[last].insert(i);
                last = -1;
            }
            else {
                last = i;
            }
        }
    }
    f(0);
    if (p.size() == 1) {
        cout << 0 << endl;
        return 0;
    }
    if ((p.size() & 1) == 0) {
        p.pb(p[0]);
    }

    cout << p.size() - 1 << endl;
    for (int i = 0; i < p.size() - 1; i ++) {
        //cout <<
        if (i & 1) cout << p[i] + 1 << ' ' << p[i + 1] + 1 << endl;
        else cout << p[i + 1] + 1 << ' ' << p[i] + 1 << endl;
    }
    return 0;

}


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

const int N = 100100, M = 200100;
int n, m;
multiset<int> G[N];
vector<int> circuit;

void dfs(int node)
{
  while(G[node].size() > 0) {
    int next = *G[node].begin();
    G[node].erase(G[node].begin());
    G[next].erase(G[next].find(node));
    dfs(next);
  }
  circuit.push_back(node);
}

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m;
  for(int i=0; i<m; i++)  {
    int u, v;
    cin >> u >> v;
    --u; --v;
    G[u].insert(v);
    G[v].insert(u);
  }
  vector<int> a, b;
  int cnt = 0;
  for(int i=0; i<n; i++)  {
    if(G[i].size() % 2) {
      if(cnt % 2) {
        b.push_back(i);
      } else  {
        a.push_back(i);
      }
      cnt++;
    }
  }
  cnt = 0;
  for(int i=0; i<a.size(); i++) {
    int u = a[i], v = b[i];
    G[u].insert(v);
    G[v].insert(u);
    cnt++;
  }
  if((m + cnt) % 2) {
    G[0].insert(0);
    G[0].insert(0);
    cnt++;
  }
  cout << m + cnt << "\n";
  dfs(0);
  reverse(circuit.begin(), circuit.end());
  for(int i=0; i<circuit.size() - 1; i++) {
    if(i % 2 == 0) {
      cout << circuit[i] + 1 << " " << circuit[i+1] + 1 << "\n";
    } else  {
      cout << circuit[i+1] + 1 << " " << circuit[i] + 1 << "\n";
    }
  }
}


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

const int N = 100100, M = 200100;
int n, m;
multiset<int> G[N];
vector<int> circuit;

void dfs(int node)
{
  while(G[node].size() > 0) {
    int next = *G[node].begin();
    G[node].erase(G[node].begin());
    G[next].erase(G[next].find(node));
    dfs(next);
  }
  circuit.push_back(node);
}

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m;
  for(int i=0; i<m; i++)  {
    int u, v;
    cin >> u >> v;
    --u; --v;
    G[u].insert(v);
    G[v].insert(u);
  }
  int cnt = 0, a;
  for(int i=0; i<n; i++)  {
    if(G[i].size() % 2) {
      if(cnt % 2) {
        G[i].insert(a);
        G[a].insert(i);
      } else  {
        a = i;
      }
      cnt++;
    }
  }
  cnt /= 2;
  if((m + cnt) % 2) {
    G[0].insert(0);
    G[0].insert(0);
    cnt++;
  }
  cout << m + cnt << "\n";
  dfs(0);
  for(int i=0; i<circuit.size() - 1; i++) {
    if(i % 2 == 0) {
      cout << circuit[i] + 1 << " " << circuit[i+1] + 1 << "\n";
    } else  {
      cout << circuit[i+1] + 1 << " " << circuit[i] + 1 << "\n";
    }
  }
}


#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <deque>
#include <queue>
#include <algorithm>
#include <cassert>
#include <cmath>
#include <ctime>
#include <sstream>
#include <unordered_set>
#include <unordered_map>
#include <functional>
#include <bitset>
#include <valarray>
#include <utility>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

#ifdef LOCAL_RUN
#define debug(x) cerr << #x << ": "  << (x) << "\n";
#else
#define debug(x) ;
#endif

#define all(v) (v).begin(), (v).end()
#define MP make_pair

template<class T>
class IsIterable__ {static void f(...); template<class U> static typename U::const_iterator f(const U&);
public:const static bool value = !std::is_same<void, decltype(f(std::declval<T>()))>::value;};

template <class F, class S> ostream& operator << (ostream& o, const pair<F,S>& p) {
return o << "(" << p.first << ", " << p.second << ")";}

template<class C>void O__(ostream& o, const C& c) {
bool f = 1; for(const auto& x: c) {if (!f) o << ", "; if (IsIterable__<decltype(x)>::value) o << "\n"; f = 0; o << x;}}

template <class T>
ostream& operator << (ostream& o, const vector<T>& v) {o << "[";O__(o, v);o << "]";return o;}

template <class T, class V>
ostream& operator << (ostream& o, const map<T, V>& v) {o << "{";O__(o, v);o << "}"; return o;}

template <class T>
ostream& operator << (ostream& o, const set<T>& v) {o << "{";O__(o, v);o << "}";return o;}

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<vii> viii;

const double PI = 3.1415926535897932384626433832795;
const double EPS = 1e-9;
const int INF = std::numeric_limits<int>::max();
const long long LLINF = std::numeric_limits<ll>::max();

#if GCC_VERSION > 40900
// supports find_by_order(int) and order_of_key(Key)
template<class Key, class Value>
using MapWithOrderStatistics = tree<Key, Value,
      std::less<Key>, rb_tree_tag /*splay_tree_tag*/,
      tree_order_statistics_node_update>;
#endif

void euler(int v, vector<multiset<int>>& al, vi& cycle) {
    stack<int> s;
    s.push(v);
    while (!s.empty()) {
        int v = s.top();
        if (al[v].empty()) {
            s.pop();
            cycle.push_back(v);
        } else {
            auto it = al[v].begin();
            int v2 = *it;
            al[v].erase(it);
            //if (v2 != v) {
            auto it2 = (al[v2].find(v));
            assert(it2 != al[v2].end());
            al[v2].erase(it2);
            s.push(v2);
        }
    }
}

int main() {
    std::ios_base::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    vi deg(n);
    vector<multiset<int>> al(n);
    for (int i = 0; i < m; ++i) {
        int x,y;
        cin >> x >> y;
        --x;
        --y;
        ++deg[x];
        al[x].insert(y);
        //if (x != y) {
            ++deg[y];
            al[y].insert(x);
        //}
    }
    vi odd;
    for (int i = 0; i < n; ++i)
        if (deg[i] & 1)
            odd.push_back(i);
    debug(odd);
    for (int i = 0; i < odd.size(); ++i) {
        int x = odd[i];
        ++i;
        int y = odd[i];
        al[x].insert(y);
        al[y].insert(x);
    }
    vi cycle;
    euler(0, al, cycle);
    if (cycle.size() & 1)
        cycle.pop_back();
    debug(cycle);
    cout << cycle.size() << "\n";
    vi in(n);
    vi out(n);
    for (int i = 0; i < cycle.size(); ++i) {
        int x = cycle[i];
        int y = cycle[(i + 1) % cycle.size()];
        ++x, ++y;
        if (i & 1) {
            ++out[x - 1];
            ++in[y - 1];
            cout << y << " " << x << "\n";
        } else {
            ++out[y - 1];
            ++in[x - 1];
            cout << x << " " << y << "\n";
        }
    }
    for (int i = 0; i < n; ++i) {
        assert(out[i] % 2 == 0);
        assert(in[i] % 2 == 0);
    }
    return 0;
}


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

struct edge{
	int x, y;
} edges[3*MAXN];

vector<int> G[MAXN];
int deg[MAXN];
int cnt_in[MAXN], cnt_out[MAXN];
bool used_edges[3*MAXN];
bool used_vertex[MAXN];

int get_second_end(int v, int edge_id){
	if (v == edges[edge_id].x)
		return edges[edge_id].y;
	else return edges[edge_id].x;
}

void compute_with_vertex(int v, queue<int>& Q){
	random_shuffle(G[v].begin(),G[v].end());
	for (int it = 0; it<G[v].size(); it++){
		int id = G[v][it];
		if (!used_edges[id]){
			used_edges[id] = true;
			int next = get_second_end(v, id);
			if (!used_vertex[next]){
				Q.push(next);
				used_vertex[next] = true;
			}
			if (cnt_in[v] % 2){
				cnt_in[v]++;
				//int x = edges[id].x, y = edges[id].y;
				if (edges[id].x == v){
					swap(edges[id].x, edges[id].y);
				}
				cnt_out[edges[id].x]++;
			}else if (cnt_out[v]%2){
				cnt_out[v]++;
				if (edges[id].x != v){
					swap(edges[id].x, edges[id].y);
				}
				cnt_in[edges[id].y]++;
			}else{
				if (rand()%2){
					cnt_in[v]++;
					//int x = edges[id].x, y = edges[id].y;
					if (edges[id].x == v){
						swap(edges[id].x, edges[id].y);
					}
					cnt_out[edges[id].x]++;
				}else{
					cnt_out[v]++;
					if (edges[id].x != v){
						swap(edges[id].x, edges[id].y);
					}
					cnt_in[edges[id].y]++;
				}
			}
		}
	}

}

void repair(int n, int start, int finish){
	vector<bool> used(n+1, false);
	vector<int> path(n+1, -1);
	queue<int> Q; Q.push(start);
	used[start]=true;
	bool found = false;
	while (!Q.empty() && !found){
		int v = Q.front(); Q.pop();
		for (auto it = G[v].begin(); it!=G[v].end(); it++){
			int next = get_second_end(v, *it);
			if (!used[next]){
				path[next] = *it;
				used[next] = true;
				if (next == finish){
					found = true; break;
				}
				Q.push(next);
			}
		}
	}
	while (path[finish]!=-1){
		int id = path[finish];
		swap(edges[id].x, edges[id].y);
		finish = get_second_end(finish, id);
	}
}

void find_broken_vertexes(int n, vector<int>& ret){
	for (int i = 1; i<=n; i++)
		if (cnt_in[i]%2) ret.push_back(i);
}

void solve(){
	vector<int> odds(0);
	int simple_even = -1;
	int cnt_simple_even = 0;
	int n, m; cin >> n >> m;
	queue<int> Q;
	for (int i = 0; i<m; i++){
		int x, y; cin >> x >> y;
		edges[i] = {x,y};
		if (x!=y){
			G[x].push_back(i); G[y].push_back(i);
		}else{
			if (!used_vertex[x]) Q.push(x);
			used_vertex[x]=true;
			cnt_in[x]++;
			cnt_out[x]++;
		}
		deg[x]++;
		deg[y]++;
	}

	for (int i = 1; i<=n; i++){
		if (deg[i]%2){
			odds.push_back(i);
		}else{
			if (deg[i]%4){
				simple_even = i;
				cnt_simple_even++;
			}
		}
	}
	for (int i = 0; i<odds.size()/2; i++){
		int x = odds[i*2], y = odds[i*2+1];
		edges[m] = {x,y};
		G[x].push_back(m); G[y].push_back(m); m++;
		deg[x]++; deg[y]++;
		if (deg[x] % 4){
			simple_even = x;
			cnt_simple_even++;
		}
		if (deg[y] % 4){
			simple_even = y;
			cnt_simple_even++;
		}
	}
	if (m%2) {
		edges[m] = {1, 1};
		m++;
		deg[1]+=2;
		cnt_in[1]++;
		cnt_out[1]++;
		if (!used_vertex[1]){
			Q.push(1);
			used_vertex[1] = true;
		}
	}
	cout << m << endl;

	if (Q.empty()){
		used_vertex[1]=true;
		Q.push(1);
	}
	while (!Q.empty()){
		int v = Q.front(); Q.pop();
		compute_with_vertex(v,Q);
	}

	vector<int> broken(0);
	find_broken_vertexes(n,broken);
	for (int i = 0; i<broken.size()/2; i++){
			int s = broken[2*i], t = broken[2*i+1];
			repair(n,s,t);
	}

	for (int i = 0; i<m; i++){
		cout << edges[i].x << ' ' << edges[i].y << endl;
	}

		//cout << broken.size();
}

int main(){
#ifdef NEKROLM
    long long start = clock();
    freopen("input.txt","r", stdin);
    freopen("output.txt","w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    srand(time(NULL));
    solve();
#ifdef NEKROLM
    fflush(stdout);
    printf("\nwork time: %.4f ms\n",float(clock()-start)/CLOCKS_PER_SEC * 1000);
#endif
    return 0;
}


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

struct edge{
	int x, y;
} edges[3*MAXN];

set<int> G[MAXN];
int deg[MAXN];

bool used_edges[3*MAXN];

int get_second_end(int v, int edge_id){
	if (v == edges[edge_id].x)
		return edges[edge_id].y;
	else return edges[edge_id].x;
}

vector<int> euler_cycle(0);

void Euler_cycle(int v){

	while (G[v].size()){
		int id = *G[v].begin();
		G[v].erase(id);

		if (!used_edges[id]){
			 used_edges[id]=true;
			 Euler_cycle(get_second_end(v, id));
		}
	}
	euler_cycle.push_back(v);
}

void print_ans(){
	bool flip = false;
	for (int i = 0; i<euler_cycle.size()-1; i++){
		int x = euler_cycle[i], y = euler_cycle[i+1];
		if (flip) swap(x,y);
		cout << x << ' ' << y << endl;
		flip = !flip;
	}
}

void solve(){
	vector<int> odds(0);
	int n, m; cin >> n >> m;
	queue<int> Q;
	for (int i = 0; i<m; i++){
		int x, y; cin >> x >> y;
		edges[i] = {x,y};
		G[x].insert(i); G[y].insert(i);
		deg[x]++;
		deg[y]++;
	}

	for (int i = 1; i<=n; i++){
		if (deg[i]%2){
			odds.push_back(i);
		}
	}
	for (int i = 0; i<odds.size()/2; i++){
		int x = odds[i*2], y = odds[i*2+1];
		edges[m] = {x,y};
		G[x].insert(m); G[y].insert(m); m++;
		deg[x]++; deg[y]++;
	}
	if (m%2){
		deg[1]+=2;
		edges[m]={1,1};
		G[1].insert(m++);
	}
	cout << m << endl;

	Euler_cycle(1);
	print_ans();
}

int main(){
#ifdef NEKROLM
    long long start = clock();
    freopen("input.txt","r", stdin);
    freopen("output.txt","w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    srand(time(NULL));
    solve();
#ifdef NEKROLM
    fflush(stdout);
    printf("\nwork time: %.4f ms\n",float(clock()-start)/CLOCKS_PER_SEC * 1000);
#endif
    return 0;
}


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

struct edge{
	int x, y;
} edges[3*MAXN];

set<int> G[MAXN];
int deg[MAXN];

bool used_edges[3*MAXN];

int get_second_end(int v, int edge_id){
	if (v == edges[edge_id].x)
		return edges[edge_id].y;
	else return edges[edge_id].x;
}

vector<int> euler_cycle(0);

void Euler_cycle(int v){
	euler_cycle.push_back(v);
	while (G[v].size()){
		int id = *G[v].begin();
		G[v].erase(id);

		if (!used_edges[id]){
			 used_edges[id]=true;
			 Euler_cycle(get_second_end(v, id));
		}
	}
}

void print_ans(){
	bool flip = false;
	for (int i = 0; i<euler_cycle.size()-1; i++){
		int x = euler_cycle[i], y = euler_cycle[i+1];
		if (flip) swap(x,y);
		cout << x << ' ' << y << endl;
		flip = !flip;
	}
}

void solve(){
	vector<int> odds(0);
	int n, m; cin >> n >> m;
	queue<int> Q;
	for (int i = 0; i<m; i++){
		int x, y; cin >> x >> y;
		edges[i] = {x,y};
		G[x].insert(i); G[y].insert(i);
		deg[x]++;
		deg[y]++;
	}

	for (int i = 1; i<=n; i++){
		if (deg[i]%2){
			odds.push_back(i);
		}
	}
	for (int i = 0; i<odds.size()/2; i++){
		int x = odds[i*2], y = odds[i*2+1];
		edges[m] = {x,y};
		G[x].insert(m); G[y].insert(m); m++;
		deg[x]++; deg[y]++;
	}
	if (m%2){
		deg[1]+=2;
		edges[m]={1,1};
		G[1].insert(m++);
	}
	cout << m << endl;

	Euler_cycle(1);
	print_ans();
}

int main(){
#ifdef NEKROLM
    long long start = clock();
    freopen("input.txt","r", stdin);
    freopen("output.txt","w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    srand(time(NULL));
    solve();
#ifdef NEKROLM
    fflush(stdout);
    printf("\nwork time: %.4f ms\n",float(clock()-start)/CLOCKS_PER_SEC * 1000);
#endif
    return 0;
}


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

struct edge{
	int x, y;
} edges[3*MAXN];

set<int> G[MAXN];
int deg[MAXN];
int cnt_in[MAXN], cnt_out[MAXN];
bool used_edges[3*MAXN];
bool used_vertex[MAXN];

int get_second_end(int v, int edge_id){
	if (v == edges[edge_id].x)
		return edges[edge_id].y;
	else return edges[edge_id].x;
}

void compute_with_vertex(int v, queue<int>& Q){
	set<int> tmp;
	while (G[v].size()){
		int id = *G[v].begin();
		if (!used_edges[id]){
			used_edges[id] = true;
			int next = get_second_end(v, id);
			if (!used_vertex[next]){
				Q.push(next);
				used_vertex[next] = true;
			}
			if (cnt_in[v] % 2){
				cnt_in[v]++;
				//int x = edges[id].x, y = edges[id].y;
				if (edges[id].x == v){
					swap(edges[id].x, edges[id].y);
				}
				cnt_out[edges[id].x]++;
			}else{
				cnt_out[v]++;
				if (edges[id].x != v){
					swap(edges[id].x, edges[id].y);
				}
				cnt_in[edges[id].y]++;
			}
		}
		tmp.insert(id);
		G[v].erase(id);
	}
	G[v]=tmp;
}

void repair(int n, int start, int finish){
	vector<bool> used(n+1, false);
	vector<int> path(n+1, -1);
	queue<int> Q; Q.push(start);
	used[start]=true;
	bool found = false;
	while (!Q.empty() && !found){
		int v = Q.front(); Q.pop();
		for (auto it = G[v].begin(); it!=G[v].end(); it++){
			int next = get_second_end(v, *it);
			if (!used[next]){
				path[next] = *it;
				used[next] = true;
				if (next == finish){
					found = true; break;
				}
				Q.push(next);
			}
		}
	}
	while (path[finish]!=-1){
		int id = path[finish];
		swap(edges[id].x, edges[id].y);
		finish = get_second_end(finish, id);
	}
}

void find_broken_vertexes(int n, vector<int>& ret){
	for (int i = 1; i<=n; i++)
		if (cnt_in[i]%2) ret.push_back(i);
}

void delete_loops(int n, queue<int>& Q){
	for (int i = 1; i<=n; i++){
		vector<int> loops(0);
		for (auto it = G[i].begin(); it!=G[i].end(); it++){
			int id = *it;
			if (edges[id].x == edges[id].y){
				loops.push_back(id);
				cnt_in[i]++;
				cnt_out[i]++;
			}
		}
		for (int j = 0; j<loops.size(); j++)
			G[i].erase(loops[j]);
		if (cnt_in[i]%2){
			used_vertex[i] = true;
			Q.push(i);
		}
	}

}

void solve(){
	vector<int> odds(0);
	int simple_even = -1;
	int cnt_simple_even = 0;
	int n, m; cin >> n >> m;
	for (int i = 0; i<m; i++){
		int x, y; cin >> x >> y;
		edges[i] = {x,y};
		G[x].insert(i); G[y].insert(i);
		deg[x]++;
		deg[y]++;
	}
	for (int i = 1; i<=n; i++){
		if (deg[i]%2){
			odds.push_back(i);
		}else{
			if (deg[i]%4){
				simple_even = i;
				cnt_simple_even++;
			}
		}
	}
	for (int i = 0; i<odds.size()/2; i++){
		int x = odds[i*2], y = odds[i*2+1];
		edges[m] = {x,y};
		G[x].insert(m); G[y].insert(m); m++;
		deg[x]++; deg[y]++;
		if (deg[x] % 4){
			simple_even = x;
			cnt_simple_even++;
		}
		if (deg[y] % 4){
			simple_even = y;
			cnt_simple_even++;
		}
	}
	if (cnt_simple_even % 2){
		edges[m] = {simple_even, simple_even};
		G[simple_even].insert(m); m++;
		deg[simple_even]+=2;
	}
	cout << m << endl;
	queue<int> Q;
	delete_loops(n, Q);
	if (Q.empty()){
		used_vertex[1]=true;
		Q.push(1);
	}
	while (!Q.empty()){
		int v = Q.front(); Q.pop();
		compute_with_vertex(v,Q);
	}

	vector<int> broken(0);
	find_broken_vertexes(n,broken);
	for (int i = 0; i<broken.size()/2; i++){
			int s = broken[2*i], t = broken[2*i+1];
			repair(n,s,t);
	}

	for (int i = 0; i<m; i++){
		cout << edges[i].x << ' ' << edges[i].y << endl;
	}

		//cout << broken.size();
}

int main(){
#ifdef NEKROLM
    long long start = clock();
    freopen("input.txt","r", stdin);
    freopen("output.txt","w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    srand(time(NULL));
    solve();
#ifdef NEKROLM
    fflush(stdout);
    printf("\nwork time: %.4f ms\n",float(clock()-start)/CLOCKS_PER_SEC * 1000);
#endif
    return 0;
}


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

struct edge{
	int x, y;
} edges[3*MAXN];

vector<int> G[MAXN];
int deg[MAXN];
int cnt_in[MAXN], cnt_out[MAXN];
bool used_edges[3*MAXN];
bool used_vertex[MAXN];

int get_second_end(int v, int edge_id){
	if (v == edges[edge_id].x)
		return edges[edge_id].y;
	else return edges[edge_id].x;
}

void compute_with_vertex(int v, queue<int>& Q){
	for (int it = 0; it<G[v].size(); it++){
		int id = G[v][it];
		if (!used_edges[id]){
			used_edges[id] = true;
			int next = get_second_end(v, id);
			if (!used_vertex[next]){
				Q.push(next);
				used_vertex[next] = true;
			}
			if (cnt_in[v] % 2){
				cnt_in[v]++;
				//int x = edges[id].x, y = edges[id].y;
				if (edges[id].x == v){
					swap(edges[id].x, edges[id].y);
				}
				cnt_out[edges[id].x]++;
			}else{
				cnt_out[v]++;
				if (edges[id].x != v){
					swap(edges[id].x, edges[id].y);
				}
				cnt_in[edges[id].y]++;
			}
		}
	}

}

void repair(int n, int start, int finish){
	vector<bool> used(n+1, false);
	vector<int> path(n+1, -1);
	queue<int> Q; Q.push(start);
	used[start]=true;
	bool found = false;
	while (!Q.empty() && !found){
		int v = Q.front(); Q.pop();
		for (auto it = G[v].begin(); it!=G[v].end(); it++){
			int next = get_second_end(v, *it);
			if (!used[next]){
				path[next] = *it;
				used[next] = true;
				if (next == finish){
					found = true; break;
				}
				Q.push(next);
			}
		}
	}
	while (path[finish]!=-1){
		int id = path[finish];
		swap(edges[id].x, edges[id].y);
		finish = get_second_end(finish, id);
	}
}

void find_broken_vertexes(int n, vector<int>& ret){
	for (int i = 1; i<=n; i++)
		if (cnt_in[i]%2) ret.push_back(i);
}

void solve(){
	vector<int> odds(0);
	int simple_even = -1;
	int cnt_simple_even = 0;
	int n, m; cin >> n >> m;
	queue<int> Q;
	for (int i = 0; i<m; i++){
		int x, y; cin >> x >> y;
		edges[i] = {x,y};
		if (x!=y){
			G[x].push_back(i); G[y].push_back(i);
		}else{
			if (!used_vertex[x]) Q.push(x);
			used_vertex[x]=true;
			cnt_in[x]++;
			cnt_out[x]++;
		}
		deg[x]++;
		deg[y]++;
	}

	for (int i = 1; i<=n; i++){
		if (deg[i]%2){
			odds.push_back(i);
		}else{
			if (deg[i]%4){
				simple_even = i;
				cnt_simple_even++;
			}
		}
	}
	for (int i = 0; i<odds.size()/2; i++){
		int x = odds[i*2], y = odds[i*2+1];
		edges[m] = {x,y};
		G[x].push_back(m); G[y].push_back(m); m++;
		deg[x]++; deg[y]++;
		if (deg[x] % 4){
			simple_even = x;
			cnt_simple_even++;
		}
		if (deg[y] % 4){
			simple_even = y;
			cnt_simple_even++;
		}
	}
	if (cnt_simple_even % 2){
		edges[m] = {simple_even, simple_even};
		m++;
		deg[simple_even]+=2;
		cnt_in[simple_even]++;
		cnt_out[simple_even]++;
		if (!used_vertex[simple_even]){
			Q.push(simple_even);
			used_vertex[simple_even] = true;
		}
	}
	cout << m << endl;

	if (Q.empty()){
		used_vertex[1]=true;
		Q.push(1);
	}
	while (!Q.empty()){
		int v = Q.front(); Q.pop();
		compute_with_vertex(v,Q);
	}

	vector<int> broken(0);
	find_broken_vertexes(n,broken);
	for (int i = 0; i<broken.size()/2; i++){
			int s = broken[2*i], t = broken[2*i+1];
			repair(n,s,t);
	}

	for (int i = 0; i<m; i++){
		cout << edges[i].x << ' ' << edges[i].y << endl;
	}

		//cout << broken.size();
}

int main(){
#ifdef NEKROLM
    long long start = clock();
    freopen("input.txt","r", stdin);
    freopen("output.txt","w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    srand(time(NULL));
    solve();
#ifdef NEKROLM
    fflush(stdout);
    printf("\nwork time: %.4f ms\n",float(clock()-start)/CLOCKS_PER_SEC * 1000);
#endif
    return 0;
}


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

struct edge{
	int x, y;
} edges[3*MAXN];

vector<int> G[MAXN];
int deg[MAXN];
int cnt_in[MAXN], cnt_out[MAXN];
bool used_edges[3*MAXN];
bool used_vertex[MAXN];

int get_second_end(int v, int edge_id){
	if (v == edges[edge_id].x)
		return edges[edge_id].y;
	else return edges[edge_id].x;
}

void compute_with_vertex(int v, queue<int>& Q){
	random_shuffle(G[v].begin(),G[v].end());
	for (int it = 0; it<G[v].size(); it++){
		int id = G[v][it];
		if (!used_edges[id]){
			used_edges[id] = true;
			int next = get_second_end(v, id);
			if (!used_vertex[next]){
				Q.push(next);
				used_vertex[next] = true;
			}
			if (cnt_in[v] % 2){
				cnt_in[v]++;
				//int x = edges[id].x, y = edges[id].y;
				if (edges[id].x == v){
					swap(edges[id].x, edges[id].y);
				}
				cnt_out[edges[id].x]++;
			}else if (cnt_out[v]%2){
				cnt_out[v]++;
				if (edges[id].x != v){
					swap(edges[id].x, edges[id].y);
				}
				cnt_in[edges[id].y]++;
			}else{
				if (rand()%2){
					cnt_in[v]++;
					//int x = edges[id].x, y = edges[id].y;
					if (edges[id].x == v){
						swap(edges[id].x, edges[id].y);
					}
					cnt_out[edges[id].x]++;
				}else{
					cnt_out[v]++;
					if (edges[id].x != v){
						swap(edges[id].x, edges[id].y);
					}
					cnt_in[edges[id].y]++;
				}
			}
		}
	}

}

void repair(int n, int start, int finish){
	vector<bool> used(n+1, false);
	vector<int> path(n+1, -1);
	queue<int> Q; Q.push(start);
	used[start]=true;
	bool found = false;
	while (!Q.empty() && !found){
		int v = Q.front(); Q.pop();
		for (auto it = G[v].begin(); it!=G[v].end(); it++){
			int next = get_second_end(v, *it);
			if (!used[next]){
				path[next] = *it;
				used[next] = true;
				if (next == finish){
					found = true; break;
				}
				Q.push(next);
			}
		}
	}
	while (path[finish]!=-1){
		int id = path[finish];
		swap(edges[id].x, edges[id].y);
		finish = get_second_end(finish, id);
	}
}

void find_broken_vertexes(int n, vector<int>& ret){
	for (int i = 1; i<=n; i++)
		if (cnt_in[i]%2) ret.push_back(i);
}

void solve(){
	vector<int> odds(0);
	int simple_even = -1;
	int cnt_simple_even = 0;
	int n, m; cin >> n >> m;
	queue<int> Q;
	for (int i = 0; i<m; i++){
		int x, y; cin >> x >> y;
		edges[i] = {x,y};
		if (x!=y){
			G[x].push_back(i); G[y].push_back(i);
		}else{
			if (!used_vertex[x]) Q.push(x);
			used_vertex[x]=true;
			cnt_in[x]++;
			cnt_out[x]++;
		}
		deg[x]++;
		deg[y]++;
	}

	for (int i = 1; i<=n; i++){
		if (deg[i]%2){
			odds.push_back(i);
		}else{
			if (deg[i]%4){
				simple_even = i;
				cnt_simple_even++;
			}
		}
	}
	for (int i = 0; i<odds.size()/2; i++){
		int x = odds[i*2], y = odds[i*2+1];
		edges[m] = {x,y};
		G[x].push_back(m); G[y].push_back(m); m++;
		deg[x]++; deg[y]++;
		if (deg[x] % 4){
			simple_even = x;
			cnt_simple_even++;
		}
		if (deg[y] % 4){
			simple_even = y;
			cnt_simple_even++;
		}
	}
	if (cnt_simple_even % 2){
		edges[m] = {simple_even, simple_even};
		m++;
		deg[simple_even]+=2;
		cnt_in[simple_even]++;
		cnt_out[simple_even]++;
		if (!used_vertex[simple_even]){
			Q.push(simple_even);
			used_vertex[simple_even] = true;
		}
	}
	cout << m << endl;

	if (Q.empty()){
		used_vertex[1]=true;
		Q.push(1);
	}
	while (!Q.empty()){
		int v = Q.front(); Q.pop();
		compute_with_vertex(v,Q);
	}

	vector<int> broken(0);
	find_broken_vertexes(n,broken);
	for (int i = 0; i<broken.size()/2; i++){
			int s = broken[2*i], t = broken[2*i+1];
			repair(n,s,t);
	}

	for (int i = 0; i<m; i++){
		cout << edges[i].x << ' ' << edges[i].y << endl;
	}

		//cout << broken.size();
}

int main(){
#ifdef NEKROLM
    long long start = clock();
    freopen("input.txt","r", stdin);
    freopen("output.txt","w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    srand(time(NULL));
    solve();
#ifdef NEKROLM
    fflush(stdout);
    printf("\nwork time: %.4f ms\n",float(clock()-start)/CLOCKS_PER_SEC * 1000);
#endif
    return 0;
}