#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("avx")
using namespace std;
int n;
int m;
int low[400002];
int ord[400002];
bool use[400002];
vector<pair<int, int> > v[400002];
set<pair<int, int> > v2[400002];
bool ng[400002];
inline void dfs(int b, int &siz, int pr = -1) {
  use[b] = true;
  ord[b] = siz;
  low[b] = siz;
  siz++;
  for (int i = 0; i < v[b].size(); i++) {
    int &go = v[b][i].first;
    if (go == pr) continue;
    if (use[go]) {
      ng[v[b][i].second] = true;
      low[b] = min(low[b], ord[v[b][i].first]);
      continue;
    }
    dfs(go, siz, b);
    low[b] = min(low[b], low[go]);
    if (ord[b] > low[go]) {
      ng[v[b][i].second] = true;
    }
  }
}
vector<pair<int, int> > ed;
int belong[400002];
int cnt[400002];
inline int root(int b) {
  if (belong[b] == -1) {
    return b;
  }
  belong[b] = root(belong[b]);
  return belong[b];
}
void merge(int a, int b) {
  a = root(a);
  b = root(b);
  if (a == b) return;
  belong[a] = b;
  cnt[b] += cnt[a];
}
bool vis[400002];
inline void dfs4(int b, int target) {
  if (vis[b]) return;
  vis[b] = true;
  for (int i = 0; i < v[b].size(); i++) {
    if (vis[v[b][i].first] == false) {
      if (root(v[b][i].first) != target) {
        auto tmp = v[b][i];
        if (ed[tmp.second].first == b) {
          swap(ed[tmp.second].first, ed[tmp.second].second);
        }
        dfs4(v[b][i].first, target);
      }
    }
  }
}
inline void dfs3(int b) {
  if (vis[b]) return;
  vis[b] = true;
  while (v2[b].size()) {
    auto tmp = (*v2[b].begin());
    v2[b].erase(tmp);
    if (use[tmp.second]) continue;
    if (root(tmp.first) != root(b)) {
      if (ed[tmp.second].first == b) {
        swap(ed[tmp.second].first, ed[tmp.second].second);
      }
      dfs4(tmp.first, root(b));
      continue;
    }
    use[tmp.second] = true;
    if (ed[tmp.second].first != b) {
      swap(ed[tmp.second].first, ed[tmp.second].second);
    }
    dfs3(tmp.first);
  }
}
int main() {
  memset(belong, -1, sizeof(belong));
  for (int i = 0; i < 400002; i++) cnt[i] = 1;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, vv;
    scanf("%d%d", &u, &vv);
    u--;
    vv--;
    v[u].push_back(make_pair(vv, i));
    v[vv].push_back(make_pair(u, i));
    v2[u].insert(make_pair(vv, i));
    v2[vv].insert(make_pair(u, i));
    ed.push_back(make_pair(u, vv));
  }
  int SIZ = 0;
  dfs(0, SIZ);
  int cntt = 0;
  for (int i = 0; i < m; i++) {
    if (ng[i]) {
      cntt++;
    }
  }
  if (cnt == 0) {
    puts("1");
    for (int i = 0; i < m; i++) {
      printf("%d %d\n", ed[i].first + 1, ed[i].second + 1);
    }
    return 0;
  }
  for (int i = 0; i < m; i++) {
    if (ng[i]) {
      merge(ed[i].first, ed[i].second);
    }
  }
  int MAXX = 0;
  int be = -1;
  for (int i = 0; i < n; i++) {
    MAXX = max(MAXX, cnt[root(i)]);
    if (MAXX == cnt[root(i)]) {
      be = root(i);
    }
  }
  memset(use, false, sizeof(use));
  dfs3(be);
  cout << MAXX << endl;
  for (int i = 0; i < ed.size(); i++) {
    printf("%d %d\n", ed[i].first + 1, ed[i].second + 1);
  }
  return 0;
}
