#include <bits/stdc++.h>
using namespace std;
const int MAXN = 400050, MAXM = 400050;
int n, m, head[MAXN], newhead[MAXN], cnt = 1;
int dfn[MAXN], low[MAXN], evis[MAXM * 2], cut[MAXM * 2], sz[MAXN], clr[MAXN],
    stk[MAXN], sign[MAXM * 2];
int dfncnt = 0, clrcnt = 0, stkcnt = 0;
int ecnt[MAXM * 2];
struct EDGE {
  int fr, to, nxt;
} edge[MAXM * 2];
void add_edge(int iu, int iv) {
  edge[++cnt] = ((EDGE){iu, iv, head[iu]});
  newhead[iu] = head[iu] = cnt;
}
void tarjan(int u) {
  dfn[u] = low[u] = ++dfncnt;
  for (int i = head[u]; i; i = edge[i].nxt) {
    if (evis[i] == 1) continue;
    evis[i] = evis[i ^ 1] = 1;
    int v = edge[i].to;
    if (!dfn[v]) {
      tarjan(v);
      low[u] = min(low[u], low[v]);
      if (low[v] > dfn[u]) {
        cut[i] = cut[i ^ 1] = 1;
      }
    } else {
      low[u] = min(low[u], dfn[v]);
    }
  }
}
void ebcc(int u) {
  if (!clr[u]) {
    stk[++stkcnt] = u;
    clr[u] = clrcnt;
  }
  for (int &i = newhead[u]; i; i = edge[i].nxt) {
    if (evis[i] || cut[i]) {
      continue;
    }
    evis[i] = evis[i ^ 1] = 1;
    ebcc(edge[i].to);
  }
  sz[clrcnt] = stkcnt;
}
void dir(int u) {
  for (int &i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (sign[i] || sign[i ^ 1]) continue;
    sign[i] = 1;
    dir(v);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int inp1, inp2;
    scanf("%d%d", &inp1, &inp2);
    add_edge(inp1, inp2);
    add_edge(inp2, inp1);
  }
  for (int i = 1; i <= n; i++) {
    if (!dfn[i]) {
      tarjan(i);
    }
  }
  memset(evis, 0, sizeof evis);
  for (int i = 1; i <= n; i++) {
    if (!clr[i]) {
      ++clrcnt;
      stkcnt = 0;
      ebcc(i);
    }
  }
  int stt = 1;
  for (int i = 1; i <= n; i++) {
    if (sz[clr[i]] > sz[clr[stt]]) {
      stt = i;
    }
  }
  dir(stt);
  printf("%d\n", sz[clr[stt]]);
  for (int i = 2; i <= 2 * m + 1; i += 2) {
    if (sign[i ^ 1]) {
      printf("%d %d\n", edge[i].fr, edge[i].to);
    } else {
      printf("%d %d\n", edge[i ^ 1].fr, edge[i ^ 1].to);
    }
  }
  return 0;
}
