#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e5;
const int MAXE = 3e5;
struct Ar {
  Ar(int v, int idx) : v(v), idx(idx) {}
  int v, idx;
};
int ars[MAXE], eq;
vector<int> G[MAXN];
int n, m;
list<int> path;
int used[MAXN];
bool usede[MAXN];
queue<list<int>::iterator> q;
int get(int v) {
  while (used[v] < ((int)G[v].size()) && usede[G[v][used[v]]]) used[v]++;
  return used[v];
}
void explore(int v, int r, list<int>::iterator it) {
  int ar = G[v][get(v)];
  int u = v ^ ars[ar];
  usede[ar] = true;
  list<int>::iterator it2 = path.insert(it, u);
  if (u != r) explore(u, r, it2);
  if (get(v) < ((int)G[v].size())) q.push(it);
}
void euler() {
  memset(used, 0, sizeof(used));
  memset(usede, 0, sizeof(usede));
  path.clear();
  q = queue<list<int>::iterator>();
  path.push_back(0);
  q.push(path.begin());
  while (((int)q.size())) {
    list<int>::iterator it = q.front();
    q.pop();
    if (used[*it] < ((int)G[*it].size())) explore(*it, *it, it);
  }
  reverse(path.begin(), path.end());
}
void addEdge(int u, int v) {
  G[u].push_back(eq);
  G[v].push_back(eq);
  ars[eq++] = u ^ v;
}
int main() {
  while (scanf("%d %d", &n, &m) == 2) {
    memset(G, 0, sizeof(G));
    eq = 0;
    for (int i = (0); i < (m); i++) {
      int u, v;
      scanf("%d %d", &u, &v);
      u--, v--;
      addEdge(u, v);
    }
    int ant = -1;
    for (int i = (0); i < (n); i++)
      if (((int)G[i].size()) & 1) {
        if (ant == -1)
          ant = i;
        else
          addEdge(ant, i), ant = -1, m++;
      }
    if (m & 1) addEdge(0, 0), m++;
    euler();
    printf("%d\n", m);
    vector<int> p2(path.begin(), path.end());
    for (int i = (0); i < (((int)p2.size()) - 1); i++) {
      if (i & 1)
        printf("%d %d\n", p2[i] + 1, p2[i + 1] + 1);
      else
        printf("%d %d\n", p2[i + 1] + 1, p2[i] + 1);
    }
  }
  return 0;
}
