#include <bits/stdc++.h>
using namespace std;
class Solution {
 public:
  map<vector<int>, int> id;
  int getId(int a, int b) {
    if (id.count({a, b})) return id[{a, b}];
    return id[{b, a}];
  }
  int time = 0;
  vector<int> low, tin;
  vector<vector<int>> G;
  vector<vector<int>> edges;
  set<int> bridges;
  void dfs(int v, int from) {
    tin[v] = low[v] = time++;
    for (auto ch : G[v]) {
      if (ch == from) continue;
      if (tin[ch] == -1) {
        dfs(ch, v);
        low[v] = min(low[ch], low[v]);
        if (low[ch] > tin[v]) {
          int idx = getId(v, ch);
          bridges.insert(idx);
        }
      } else {
        low[v] = min(low[v], tin[ch]);
      }
    }
  }
  vector<vector<int>> nG;
  vector<int> used;
  set<pair<int, int>> usedEdges;
  int dfsCount(int v, int from) {
    int cnt = 1;
    for (auto ch : nG[v]) {
      if (ch == from) continue;
      int a = min(ch, v), b = max(ch, v);
      if (usedEdges.count({a, b})) continue;
      usedEdges.insert({a, b});
      int idx = getId(v, ch);
      if (edges[idx][0] != v + 1) swap(edges[idx][0], edges[idx][1]);
      if (used[ch]) continue;
      used[ch] = used[v];
      cnt += dfsCount(ch, v);
    }
    return cnt;
  }
  void dfsMark(int v, int from) {
    used[v] = 1;
    for (auto ch : G[v]) {
      if (ch == from || used[ch]) continue;
      dfsMark(ch, v);
      int idx = getId(v, ch);
      if (bridges.count(idx)) {
        edges[idx][0] = ch + 1;
        edges[idx][1] = v + 1;
      }
    }
  }
  void solve(int num, std::istream& in, std::ostream& out) {
    int n, m;
    in >> n >> m;
    low.resize(n, -1);
    G.resize(n);
    tin.resize(n, -1);
    for (int i = 0; i < m; i++) {
      int u, v;
      in >> u >> v;
      edges.push_back({u, v});
      u--, v--;
      id[{u, v}] = i;
      G[u].push_back(v);
      G[v].push_back(u);
    }
    dfs(0, -1);
    nG.resize(n);
    for (int i = 0; i < m; i++) {
      if (bridges.count(i)) continue;
      int a = edges[i][0] - 1, b = edges[i][1] - 1;
      nG[a].push_back(b);
      nG[b].push_back(a);
    }
    used.resize(n);
    int mn = 1, mc = 1;
    int c = 0;
    for (int i = 0; i < n; i++) {
      if (used[i]) continue;
      c++;
      used[i] = c;
      int cnt = dfsCount(i, -1);
      if (mn < cnt) {
        mn = cnt;
        mc = c;
      }
    }
    int st = -1;
    for (int i = 0; i < n; i++) {
      if (used[i] == mc) {
        st = i;
      }
      used[i] = 0;
    }
    dfsMark(st, -1);
    out << mn << endl;
    for (auto edge : edges) {
      out << edge[0] << " " << edge[1] << endl;
    }
  }
};
void solve(std::istream& in, std::ostream& out) {
  out << std::setprecision(12);
  Solution solution;
  solution.solve(0, in, out);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  istream& in = cin;
  ostream& out = cout;
  solve(in, out);
  return 0;
}
