#include <bits/stdc++.h>
using namespace std;
template <class T>
struct rge {
  T b, e;
};
template <class T>
rge<T> range(T i, T j) {
  return rge<T>{i, j};
}
template <class T>
auto dud(T *x) -> decltype(cerr << *x, 0);
template <class T>
char dud(...);
struct debug {
  template <class T>
  debug &operator<<(const T &) {
    return *this;
  }
};
const int N = 4e5 + 5;
struct dsu {
  vector<int> pr, tot;
  dsu(int n = 0) : pr(n + 5), tot(n + 5, 1) { iota(pr.begin(), pr.end(), 0); }
  int find(int u) { return pr[u] == u ? u : pr[u] = find(pr[u]); }
  void unite(int u, int v) {
    u = find(u), v = find(v);
    if (u != v) {
      pr[v] = u;
      tot[u] += tot[v];
    }
  }
  int reached(int u) { return tot[find(u)]; }
};
vector<int> graph[N];
vector<pair<int, int> > edges;
map<pair<int, int>, pair<int, int> > dir;
bool vis[N];
int tin[N], fup[N];
dsu dg(N);
int timer = 0;
int n, m;
void bridges(int u, int pr = 0) {
  tin[u] = fup[u] = ++timer;
  for (int v : graph[u])
    if (v != pr) {
      if (!tin[v]) {
        bridges(v, u);
        fup[u] = min(fup[u], fup[v]);
        if (fup[v] > tin[u])
          debug() << "bridge"
                     " "
                  << "u"
                     ": "
                  << (u)
                  << " "
                     "->"
                     " "
                  << "v"
                     ": "
                  << (v) << " ";
        else {
          dir[{u, v}] = dir[{v, u}] = {u, v};
          dg.unite(u, v);
        }
      }
      fup[u] = min(fup[u], tin[v]);
      if (tin[v] < tin[u]) dir[{u, v}] = dir[{v, u}] = {u, v};
    }
}
void dfs(int u, int pr = 0) {
  vis[u] = 1;
  for (int v : graph[u])
    if (!vis[v]) {
      if (!dir.count({u, v})) dir[{u, v}] = dir[{v, u}] = {v, u};
      dfs(v, u);
    }
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (auto i = (0) - ((0) > (m)); i != m - ((0) > (m));
       i += 1 - 2 * ((0) > (m))) {
    int u, v;
    cin >> u >> v;
    graph[u].push_back(v);
    graph[v].push_back(u);
    edges.push_back({u, v});
  }
  bridges(1);
  int z = 1;
  for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
       u += 1 - 2 * ((1) > (n + 1)))
    if (dg.reached(u) > dg.reached(z)) z = u;
  debug() << " "
          << "z"
             ": "
          << (z)
          << " "
             " "
          << "dg.reached(z)"
             ": "
          << (dg.reached(z)) << " ";
  dfs(z);
  cout << dg.reached(z) << '\n';
  for (auto &[u, v] : edges) {
    auto it = dir[{u, v}];
    cout << it.first << " " << it.second << '\n';
  }
  return 0;
}
