#include <bits/stdc++.h>
using namespace std;
struct node {
  int u, v, next;
  bool is;
} edge[400005 << 1];
int head[400005], cnt;
int n, m;
int dfs_clock, low[400005], pre[400005];
int ans[400005][2];
void add_edge(int u, int v) {
  edge[cnt].is = 0;
  edge[cnt].u = u, edge[cnt].v = v, edge[cnt].next = head[u], head[u] = cnt++;
}
void find_cut(int u, int father) {
  pre[u] = low[u] = ++dfs_clock;
  for (int i = head[u]; i + 1; i = edge[i].next) {
    int v = edge[i].v;
    if (v == father) continue;
    if (!pre[v]) {
      find_cut(v, u);
      if (low[v] <= pre[u]) {
      } else {
        edge[i].is = edge[i ^ 1].is = 1;
      }
      low[u] = min(low[u], low[v]);
    } else {
      low[u] = min(low[u], pre[v]);
    }
  }
}
int cc;
void dfs(int u, int father) {
  cc++;
  pre[u] = 1;
  for (int i = head[u]; i + 1; i = edge[i].next) {
    int v = edge[i].v;
    if (edge[i].is) continue;
    ans[i >> 1][0] = u, ans[i >> 1][1] = v;
    if (!pre[v]) dfs(v, u);
  }
}
void bfs(int s) {
  queue<int> gg;
  while (!gg.empty()) gg.pop();
  memset(pre, 0, sizeof pre);
  gg.push(s);
  pre[s] = 1;
  while (!gg.empty()) {
    int u = gg.front();
    gg.pop();
    for (int i = head[u]; i + 1; i = edge[i].next) {
      int v = edge[i].v;
      if (pre[v]) continue;
      if (edge[i].is) {
        ans[i >> 1][0] = v, ans[i >> 1][1] = u;
      }
      gg.push(v);
      pre[v] = 1;
    }
  }
}
void solve() {
  memset(pre, 0, sizeof pre);
  int Max = 0, from;
  for (int i = 1; i <= n; i++)
    if (!pre[i]) {
      cc = 0;
      dfs(i, 0);
      if (cc > Max) {
        Max = cc, from = i;
      }
    }
  bfs(from);
  cout << Max << endl;
  for (int i = 0; i < m; i++) {
    cout << ans[i][0] << " " << ans[i][1] << endl;
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> m;
  memset(head, -1, sizeof head);
  cnt = 0;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    add_edge(u, v);
    add_edge(v, u);
  }
  dfs_clock = 0;
  find_cut(1, 0);
  solve();
  return 0;
}
