#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
namespace flow {
const int N = 100 * 1000;
struct Edge {
  int v, cap, flow;
  int back_ind;
  Edge* back;
  Edge(int vi, int ci) : v(vi), cap(ci) {}
};
int n, s, t;
int e[N], h[N];
vector<Edge> g[N];
vector<Edge>::iterator cur[N];
void bfs(int start, int start_h) {
  queue<int> q;
  h[start] = start_h;
  for (q.push(start); !q.empty(); q.pop()) {
    int u = q.front();
    for (__typeof((g[u]).begin()) i = (g[u]).begin(); i != (g[u]).end(); ++i)
      if (i->back->flow < i->back->cap && h[i->v] > h[u] + 1) {
        h[i->v] = h[u] + 1;
        q.push(i->v);
      }
  }
}
int compute_flow() {
  queue<int> q;
  for (int i = 0; i < (n); ++i) {
    for (__typeof((g[i]).begin()) j = (g[i]).begin(); j != (g[i]).end(); ++j) {
      j->flow = 0;
      j->back = &g[j->v][j->back_ind];
    }
    cur[i] = g[i].begin();
    h[i] = e[i] = 0;
  }
  for (__typeof((g[s]).begin()) i = (g[s]).begin(); i != (g[s]).end(); ++i) {
    i->flow = i->cap;
    i->back->flow = -i->flow;
    if (e[i->v] == 0 && i->v != t) q.push(i->v);
    e[i->v] += i->flow;
  }
  h[s] = n;
  int relabel_counter = 0;
  for (; !q.empty(); q.pop()) {
    int u = q.front();
    while (e[u] > 0) {
      if (cur[u] == g[u].end()) {
        relabel_counter++;
        h[u] = 2 * n + 1;
        for (__typeof((g[u]).begin()) i = (g[u]).begin(); i != (g[u]).end();
             ++i)
          if (i->flow < i->cap) h[u] = min(h[u], 1 + h[i->v]);
        cur[u] = g[u].begin();
        continue;
      }
      if (cur[u]->flow < cur[u]->cap && h[u] == h[cur[u]->v] + 1) {
        int d = min(e[u], cur[u]->cap - cur[u]->flow);
        cur[u]->flow += d;
        cur[u]->back->flow -= d;
        e[u] -= d;
        e[cur[u]->v] += d;
        if (e[cur[u]->v] == d && cur[u]->v != t && cur[u]->v != s)
          q.push(cur[u]->v);
      } else
        cur[u]++;
    }
    if (relabel_counter >= n) {
      for (int i = 0; i < (n); ++i) h[i] = 2 * n + 1;
      bfs(t, 0);
      bfs(s, n);
      relabel_counter = 0;
    }
  }
  return e[t];
}
void add_edge(int a, int b, int c, int c_back = 0) {
  assert(a != b);
  g[a].push_back(Edge(b, c));
  g[b].push_back(Edge(a, c_back));
  g[a].back().back_ind = g[b].size() - 1;
  g[b].back().back_ind = g[a].size() - 1;
}
}  // namespace flow
int N, M;
vector<pair<int, int> > edges;
bool can(int K) {
  flow::n = N + M + 2;
  flow::s = N + M, flow::t = N + M + 1;
  for (int i = 0; i < (flow::n); ++i) flow::g[i].clear();
  for (int i = 0; i < (M); ++i) {
    flow::add_edge(flow::s, i, 1);
    flow::add_edge(i, M + edges[i].first, 1);
    flow::add_edge(i, M + edges[i].second, 1);
  }
  for (int i = 0; i < (N); ++i) {
    flow::add_edge(M + i, flow::t, K);
  }
  int f = flow::compute_flow();
  return f == M;
}
int main() {
  scanf("%d%d", &N, &M);
  for (int i = 0; i < (M); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    edges.push_back({a, b});
  }
  int L = 0, R = 2501;
  while (L < R) {
    int S = (L + R) / 2;
    if (can(S))
      R = S;
    else
      L = S + 1;
  }
  can(L);
  printf("%d\n", L);
  for (int i = 0; i < (M); ++i)
    for (auto& e : flow::g[i])
      if (e.flow > 0) {
        printf("%d %d\n", 1 + e.v - M,
               (edges[i].first + edges[i].second - (e.v - M)) + 1);
      }
}
