#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9 + 7;
const long long INFL = 1e18 + 123;
const double PI = atan2(0, -1);
mt19937 tw(960172);
long long rnd(long long x, long long y) {
  static uniform_int_distribution<long long> d;
  return d(tw) % (y - x + 1) + x;
}
struct edge {
  int f, c;
  edge() { f = c = 0; }
  edge(int _c) {
    f = 0;
    c = _c;
  }
};
vector<edge> edges;
vector<vector<pair<int, int>>> graph;
int add_edge(int a, int b, int c) {
  graph[a].push_back({b, ((int)(edges).size())});
  edges.push_back(edge(c));
  graph[b].push_back({a, ((int)(edges).size())});
  edges.push_back(edge());
  return 0;
}
int add_node() {
  graph.push_back({});
  return ((int)(graph).size()) - 1;
}
vector<int> dist;
vector<int> cnt;
int build_layers(int s, int t) {
  dist = vector<int>(((int)(graph).size()), INF);
  dist[s] = 0;
  queue<int> q;
  q.push(s);
  while (((int)(q).size())) {
    int v = q.front();
    q.pop();
    for (pair<int, int> to : graph[v]) {
      auto& e = edges[to.second];
      if (e.f < e.c && dist[to.first] > dist[v] + 1) {
        dist[to.first] = dist[v] + 1;
        q.push(to.first);
      }
    }
  }
  if (dist[t] == INF) {
    return 0;
  }
  return 1;
}
int push_flow(int v, int t, int f) {
  if (v == t) {
    return f;
  }
  while (cnt[v] < ((int)(graph[v]).size())) {
    pair<int, int> to = graph[v][cnt[v]];
    auto& e = edges[to.second];
    if (e.f < e.c && dist[to.first] == dist[v] + 1) {
      int tmp = push_flow(to.first, t, min(f, e.c - e.f));
      if (tmp) {
        e.f += tmp;
        edges[to.second ^ 1].f -= tmp;
        return tmp;
      }
    }
    ++cnt[v];
  }
  return 0;
}
int main() {
  cerr << fixed << setprecision(15);
  cout << fixed << setprecision(15);
  int n, m;
  scanf("%d%d", &n, &m);
  int s = add_node();
  int t = add_node();
  vector<int> index;
  vector<int> nodes;
  for (int i = 0; i < n; ++i) {
    nodes.push_back(add_node());
  }
  vector<pair<int, int>> inp;
  for (int i = 0; i < m; ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a;
    --b;
    inp.push_back({a, b});
    int tmp = add_node();
    index.push_back(((int)(edges).size()));
    add_edge(s, tmp, 1);
    add_edge(tmp, nodes[a], 1);
    add_edge(tmp, nodes[b], 1);
  }
  for (int i = 0; i < n; ++i) {
    add_edge(nodes[i], t, 0);
  }
  int l = -1, r = n + 1;
  while (r - l > 1) {
    int mid = (l + r) / 2;
    for (auto& e : edges) {
      e.f = 0;
    }
    for (int i = 0; i < n; ++i) {
      edges[((int)(edges).size()) - 2 - i * 2].c = mid;
    }
    int flow = 0;
    while (build_layers(s, t)) {
      cnt = vector<int>(((int)(graph).size()), 0);
      int tmp = 0;
      while ((tmp = push_flow(s, t, INF))) {
        flow += tmp;
      }
    }
    if (flow == m) {
      r = mid;
    } else {
      l = mid;
    }
  }
  cout << r << "\n";
  for (auto& e : edges) {
    e.f = 0;
  }
  for (int i = 0; i < n; ++i) {
    edges[((int)(edges).size()) - 2 - i * 2].c = r;
  }
  int flow = 0;
  while (build_layers(s, t)) {
    cnt = vector<int>(((int)(graph).size()), 0);
    int tmp = 0;
    while ((tmp = push_flow(s, t, INF))) {
      flow += tmp;
    }
  }
  for (int i = 0; i < m; ++i) {
    if (edges[index[i] + 2].f) {
      cout << inp[i].first + 1 << " " << inp[i].second + 1 << "\n";
    } else {
      cout << inp[i].second + 1 << " " << inp[i].first + 1 << "\n";
    }
  }
  return 0;
}
