#include <bits/stdc++.h>
using namespace std;
const int Maxn = 4e5 + 5;
struct edge {
  int v, nx;
} e[Maxn << 1];
int n, m, ne = 1, f[Maxn], dfn[Maxn], low[Maxn], scc[Maxn];
int rt, tot, cnt, top, st[Maxn];
int ans, cu[Maxn], cv[Maxn], nx[Maxn], ansu[Maxn], ansv[Maxn];
bool vis[Maxn];
void read(int u, int v) {
  e[++ne].v = v;
  e[ne].nx = f[u];
  f[u] = ne;
}
void Tarjan(int u, int fa) {
  dfn[u] = low[u] = ++tot;
  vis[u] = 1;
  st[++top] = u;
  for (int i = f[u]; i; i = e[i].nx) {
    int v = e[i].v;
    if (v == fa) continue;
    if (!dfn[v]) {
      Tarjan(v, u);
      low[u] = min(low[u], low[v]);
    } else if (vis[v])
      low[u] = min(low[u], low[v]);
  }
  if (dfn[u] == low[u]) {
    cnt++;
    int x, sz = 0;
    do {
      x = st[top];
      top--;
      sz++;
      scc[x] = cnt;
      vis[x] = 0;
    } while (x != u);
    if (sz > ans) ans = sz, rt = u;
  }
}
void dfs2(int u) {
  vis[u] = 1;
  for (int i = f[u]; i; i = e[i].nx) {
    int v = e[i].v;
    if (vis[v]) {
      ansu[i >> 1] = u;
      ansv[i >> 1] = v;
      continue;
    }
    if (low[v] != low[u]) {
      ansu[i >> 1] = v;
      ansv[i >> 1] = u;
    } else {
      ansu[i >> 1] = u;
      ansv[i >> 1] = v;
    }
    dfs2(v);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    read(u, v);
    read(v, u);
  }
  Tarjan(1, 0);
  ne = 0;
  printf("%d\n", ans);
  dfs2(rt);
  for (int i = 1; i <= m; i++) printf("%d %d\n", ansu[i], ansv[i]);
  return 0;
}
