#include <bits/stdc++.h>
using namespace std;
inline int QuickPow(int x, int y) {
  int Res = 1, Temp = x;
  while (y) {
    if (y & 1) Res = Res * Temp % 1000000007;
    Temp = Temp * Temp % 1000000007;
    y /= 2;
  }
  return Res;
}
inline void Swap(int &x, int &y) {
  int Temp = x;
  x = y;
  y = Temp;
}
inline int Max(int x, int y) { return x > y ? x : y; }
inline int Min(int x, int y) { return x < y ? x : y; }
inline void read(int &x) {
  x = 0;
  int f = 1;
  char s = getchar();
  while (s < '0' || s > '9') {
    if (s == '-') f = -1;
    s = getchar();
  }
  while (s >= '0' && s <= '9') {
    x = (x << 3) + (x << 1) + (s ^ 48);
    s = getchar();
  }
  x *= f;
}
struct node {
  int v, Index;
  node() {}
  node(int V, int INDEX) {
    v = V;
    Index = INDEX;
  }
};
stack<int> S;
vector<node> G[400005];
int Dfn[400005], Low[400005], Bel[400005], Cnt, Col, Size[400005], Maxx, Root;
bool InStack[400005];
void Tarjan(int x, int Pre) {
  Dfn[x] = Low[x] = ++Cnt;
  S.push(x);
  InStack[x] = 1;
  int l = G[x].size();
  for (register int i = 0; i < l; ++i) {
    int to = G[x][i].v;
    if (to == Pre) continue;
    if (!Dfn[to]) {
      Tarjan(to, x);
      Low[x] = Min(Low[x], Low[to]);
    } else if (InStack[to])
      Low[x] = Min(Low[x], Dfn[to]);
  }
  if (Dfn[x] == Low[x]) {
    Col++;
    int u;
    do {
      Size[Col]++;
      u = S.top();
      S.pop();
      InStack[u] = 0;
      Bel[u] = Col;
    } while (u != x);
    if (Size[Col] > Maxx) Maxx = Size[Col], Root = x;
  }
}
bool Pan[400005];
int From[400005 * 2], To[400005 * 2];
void Dfs(int x) {
  Pan[x] = 1;
  int l = G[x].size();
  for (register int i = 0; i < l; ++i) {
    int to = G[x][i].v, Id = G[x][i].Index;
    if (Pan[to]) {
      From[Id] = x, To[Id] = to;
      continue;
    }
    if (Low[to] != Low[x])
      From[Id] = to, To[Id] = x;
    else
      From[Id] = x, To[Id] = to;
    Dfs(to);
  }
}
int main() {
  int n, m;
  read(n);
  read(m);
  for (register int i = 1; i <= m; ++i) {
    int u, v;
    read(u);
    read(v);
    G[u].push_back(node(v, i));
    G[v].push_back(node(u, i));
  }
  for (register int i = 1; i <= n; ++i)
    if (!Dfn[i]) Tarjan(i, i);
  printf("%d\n", Maxx);
  Dfs(Root);
  for (register int i = 1; i <= m; ++i) printf("%d %d\n", From[i], To[i]);
  return 0;
}
