#include <bits/stdc++.h>
using namespace std;
const int N = 1000001;
int eu[N], ev[N];
vector<pair<int, int> > g[N];
bool vis[N];
bool be[N];
int dfn[N], low[N], vbel[N], ebel[N], dfc, ebcc;
int sz[N];
int dfs_ebcc(int u, int f) {
  static int s[N], t;
  s[++t] = u;
  dfn[u] = low[u] = ++dfc;
  for (pair<int, int> p : g[u]) {
    int v = p.first, i = p.second;
    if (vis[i]) continue;
    vis[i] = 1;
    s[++t] = -i;
    if (!dfn[v]) {
      if (eu[i] != u) swap(eu[i], ev[i]);
      low[u] = min(low[u], dfs_ebcc(v, i));
    } else {
      if (low[v] < low[u] && eu[i] != u) swap(eu[i], ev[i]);
      low[u] = min(low[u], low[v]);
    }
  }
  if (dfn[u] == low[u]) {
    for (++ebcc; s[t] != -f; --t)
      s[t] > 0 ? vbel[s[t]] = ebcc : ebel[-s[t]] = ebcc;
    if (t) --t;
  }
  return low[u];
}
vector<pair<int, int> > gt[N];
void dfs_dir(int u, int f) {
  for (pair<int, int> p : gt[u]) {
    int v = p.first, i = p.second;
    if (v == f) continue;
    if (vbel[eu[i]] == u) swap(eu[i], ev[i]);
    dfs_dir(v, u);
  }
}
int tarjan_ebcc(int n, int m) {
  dfc = ebcc = 0;
  fill_n(vis + 1, m, 0);
  fill_n(ebel + 1, m, 0);
  fill_n(dfn + 1, n, 0);
  for (int u = 1; u <= n; ++u)
    if (!dfn[u]) dfs_ebcc(u, 0);
  for (int i = 1; i <= n; ++i) sz[vbel[i]]++;
  for (int i = 1; i <= m; ++i) {
    if (ebel[i]) continue;
    gt[vbel[eu[i]]].emplace_back(vbel[ev[i]], i);
    gt[vbel[ev[i]]].emplace_back(vbel[eu[i]], i);
  }
  int r = max_element(sz + 1, sz + ebcc + 1) - sz;
  dfs_dir(r, 0);
  return sz[r];
}
int main(void) {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    eu[i] = u;
    ev[i] = v;
    g[u].emplace_back(v, i);
    g[v].emplace_back(u, i);
  }
  int ans = tarjan_ebcc(n, m);
  printf("%d\n", ans);
  for (int i = 1; i <= m; ++i) printf("%d %d\n", eu[i], ev[i]);
  return 0;
}
