#include <bits/stdc++.h>
using namespace std;
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
namespace Dinic {
const int MAXV = int(1e5) + 10, MAXE = int(2e5) + 10;
const long long int INF = 1e18;
long long int cap[MAXE];
int V, E, last[MAXV];
int dist[MAXV], curr[MAXV], next[MAXE], adj[MAXE];
void init(int n) {
  V = n;
  E = 0;
  for (int i = (0); i < (V); ++i) last[i] = -1;
}
int AddEdge(int x, int y, long long int c1, long long int c2) {
  adj[E] = y;
  cap[E] = c1;
  next[E] = last[x];
  last[x] = E++;
  adj[E] = x;
  cap[E] = c2;
  next[E] = last[y];
  last[y] = E++;
  return E - 2;
}
long long int push(int x, int sink, long long int flow) {
  if (x == sink) return flow;
  for (int& e = curr[x]; e != -1; e = next[e]) {
    int y = adj[e];
    if (cap[e] && dist[x] + 1 == dist[y])
      if (long long int f = push(y, sink, min(flow, cap[e])))
        return cap[e] -= f, cap[e ^ 1] += f, f;
  }
  return 0;
}
long long int run(int src, int sink) {
  long long int ret = 0;
  while (1) {
    for (int i = (0); i < (V); ++i) curr[i] = last[i], dist[i] = -1;
    queue<int> Q;
    Q.push(src), dist[src] = 0;
    while (!Q.empty()) {
      int x = Q.front();
      Q.pop();
      for (int e = last[x]; e != -1; e = next[e]) {
        int y = adj[e];
        if (cap[e] && dist[y] == -1) Q.push(y), dist[y] = dist[x] + 1;
      }
    }
    if (dist[sink] == -1) break;
    while (long long int f = push(src, sink, INF)) ret += f;
  }
  return ret;
}
}  // namespace Dinic
const int N = 5001;
int n, m, U[N], V[N], L[N], R[N], from[N], to[N];
vector<pair<int, pair<int, int>>> edges;
bool ok(int val) {
  int len = 0;
  int s = len++, t = len++;
  for (int i = 1; i <= n; i++) L[i] = len++;
  for (int i = 1; i <= m; i++) R[i] = len++;
  Dinic::init(len + 1);
  for (int i = 1; i <= n; i++) Dinic::AddEdge(s, L[i], val, 0);
  for (int i = 1; i <= m; i++) Dinic::AddEdge(R[i], t, 1, 0);
  edges.clear();
  for (int i = 1; i <= m; i++) {
    edges.push_back({Dinic::AddEdge(L[U[i]], R[i], 1, 0), {U[i], i}});
    edges.push_back({Dinic::AddEdge(L[V[i]], R[i], 1, 0), {V[i], i}});
  }
  return Dinic::run(s, t) == m;
}
int main() {
  scanf("%d", &n);
  scanf("%d", &m);
  for (int i = 1; i <= m; i++) scanf("%d %d", U + i, V + i);
  int l = 0, h = N, ans = -1;
  while (l <= h) {
    int mid = (l + h) >> 1;
    if (ok(mid)) {
      ans = mid;
      h = mid - 1;
    } else
      l = mid + 1;
  }
  ok(ans);
  for (auto e : edges) {
    if (Dinic::cap[e.first]) continue;
    assert(!from[e.second.second] && !to[e.second.second]);
    from[e.second.second] = e.second.first;
    to[e.second.second] =
        U[e.second.second] ^ V[e.second.second] ^ from[e.second.second];
  }
  for (int i = 1; i <= m; i++) assert(from[i] && to[i]);
  printf("%d\n", ans);
  for (int i = 1; i <= m; i++) printf("%d %d\n", from[i], to[i]);
  return 0;
}
