#include <bits/stdc++.h>
int read() {
  char k = getchar();
  int x = 0;
  while (k < '0' || k > '9') k = getchar();
  while (k >= '0' && k <= '9') x = x * 10 + k - '0', k = getchar();
  return x;
}
const int MX = 4e5 + 23;
int n, m;
int head[MX], tot = 1;
struct edge {
  int node, next, w;
} h[MX << 1];
void addedge(int u, int v, int flg = 1) {
  h[++tot] = (edge){v, head[u], 0}, head[u] = tot;
  if (flg) addedge(v, u, false);
}
int DFN[MX], low[MX], cnt, stk[MX], top, ans, mxfr;
void tarjan(int x, int las) {
  DFN[x] = low[x] = ++cnt, stk[++top] = x;
  for (int i = head[x], d; i; i = h[i].next) {
    if (i == (las ^ 1)) continue;
    if (!DFN[d = h[i].node]) {
      h[i].w = 1;
      tarjan(d, i);
      low[x] = std::min(low[x], low[d]);
    } else if (DFN[d] < low[x]) {
      if (!h[i ^ 1].w) h[i].w = 1;
      low[x] = DFN[d];
    }
  }
  if (DFN[x] == low[x]) {
    int sz = 0, j = 0;
    while (j != x) {
      j = stk[top--];
      ++sz;
    }
    ans = std::max(ans, sz);
    if (ans == sz) {
      mxfr = x;
    }
  }
}
int main() {
  n = read(), m = read();
  for (int i = 1, u, v; i <= m; ++i) {
    u = read(), v = read();
    addedge(u, v);
  }
  tarjan(1, 0);
  for (int i = 0; i <= tot; ++i) {
    h[i].w = 0;
  }
  memset(DFN, 0, sizeof DFN);
  cnt = 0;
  printf("%d\n", ans);
  tarjan(mxfr, 0);
  for (int i = 1; i <= m; ++i) {
    int v = h[i << 1].node, u = h[i << 1 | 1].node;
    if (h[i << 1].w == 0) std::swap(u, v);
    printf("%d %d\n", v, u);
  }
  return 0;
}
