#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5004;
const int MAXNN = MAXN * 2 + 10;
const int INF = 0x3f3f3f3f;
struct Edge {
  int u, v, f, cap;
  Edge() { f = 0; }
  Edge(int uu, int vv, int cc) : u(uu), v(vv), f(0), cap(cc) {}
  inline int other(int w) { return w == u ? v : u; }
  inline int flow(int from) { return from == u ? cap - f : f; }
  inline void augment(int from, int val) {
    if (from == u)
      f += val;
    else
      f -= val;
  }
};
struct Dinic {
  int N;
  vector<int> par, L, pt, eIdx;
  vector<Edge> E;
  vector<vector<int>> a;
  Dinic(int n) : N(n), par(n), L(n), pt(n), eIdx(n), a(n) {}
  Dinic() : N(0) {}
  void addEdge(int u, int v, int c) {
    if (u != v) {
      E.emplace_back(u, v, c);
      a[u].push_back(E.size() - 1);
      a[v].push_back(E.size() - 1);
    }
  }
  void clearFlow() {
    for (Edge &e : E) e.f = 0;
  }
  bool BFS(int source, int target) {
    const int INF = 0x3f3f3f3f;
    queue<int> Q;
    fill(L.begin(), L.end(), INF);
    L[source] = 0;
    Q.push(source);
    while (Q.size()) {
      int u = Q.front();
      Q.pop();
      for (int ei : a[u]) {
        Edge &e = E[ei];
        int v = e.other(u);
        if (L[v] > L[u] + 1 && e.flow(u)) {
          L[v] = L[u] + 1;
          if (v == target) return true;
          Q.push(v);
        }
      }
    }
    return false;
  }
  int DFS(int source, int target) {
    stack<int> S;
    int ans = 0;
    S.push(source);
    while (S.size()) {
      int u = S.top();
      if (u == target) {
        int f = 1e9, bottleneck = -1;
        for (int cur = target; cur != source; cur = par[cur])
          f = min(f, E[eIdx[cur]].flow(par[cur]));
        for (int cur = target; cur != source; cur = par[cur]) {
          Edge &e = E[eIdx[cur]];
          e.augment(par[cur], f);
          if (!e.flow(par[cur])) bottleneck = par[cur];
        }
        ans += f;
        while (S.top() != bottleneck) S.pop();
      } else {
        if (pt[u]) {
          int &i = pt[u];
          while (--i >= 0) {
            int ei = a[u][i];
            Edge &e = E[ei];
            int v = e.other(u);
            if (pt[v] > 0 && L[u] + 1 == L[v] && e.flow(u)) {
              par[v] = u;
              eIdx[v] = ei;
              S.push(v);
              break;
            }
          }
        }
        if (S.top() == u) {
          pt[u] = 0;
          S.pop();
        }
      }
    }
    return ans;
  }
  int maxFlow(int source, int target) {
    int mf = 0, f;
    clearFlow();
    while (BFS(source, target)) {
      for (int i = 0; i < N; ++i) pt[i] = (int)a[i].size();
      while (pt[source]) {
        f = DFS(source, target);
        if (!f) break;
        mf += f;
      }
    }
    return mf;
  }
};
bool vis[MAXNN];
int n, m, S, T;
inline void init(Dinic &F, int val) {
  for (int ei : F.a[T]) {
    F.E[ei].cap = val;
  }
}
void bs(Dinic &F) {
  int hi = n, lo = 0, ans = 0, mid;
  while (hi >= lo) {
    mid = (hi + lo) >> 1;
    init(F, mid);
    if (F.maxFlow(S, T) == m) {
      ans = mid;
      hi = mid - 1;
    } else {
      lo = mid + 1;
    }
  }
  init(F, ans);
  F.maxFlow(S, T);
  printf("%d\n", ans);
  for (int i = 1, from = -1, to = -1; i <= m; ++i) {
    for (int ei : F.a[i]) {
      Edge &e = F.E[ei];
      if (e.other(i) == S) continue;
      if (e.flow(i))
        to = e.other(i);
      else
        from = e.other(i);
    }
    printf("%d %d\n", from - m, to - m);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  S = 0;
  T = n + m + 1;
  Dinic F(T + 1);
  for (int i = 1, x, y; i <= m; ++i) {
    scanf("%d%d", &x, &y);
    F.addEdge(i, m + x, 1);
    F.addEdge(i, m + y, 1);
    F.addEdge(S, i, 1);
  }
  for (int i = 1; i <= n; ++i) F.addEdge(m + i, T, MAXN);
  bs(F);
  return 0;
}
