#include <bits/stdc++.h>
const int MAX_N = 4e5 + 7;
int N, M;
std::array<std::vector<std::pair<int, int>>, MAX_N> graph;
std::vector<std::pair<int, int>> edges, directed_edges;
std::array<int, MAX_N> low, height;
std::vector<int> stack;
int answer = 0, root;
int dfs(int u, int parent, bool compute_answer = true) {
  stack.push_back(u);
  height[u] = height[parent] + 1;
  low[u] = height[u];
  for (auto [v, _] : graph[u]) {
    if (height[v] == -1) {
      low[u] = std::min(low[u], dfs(v, u));
    } else if (v != parent) {
      low[u] = std::min(low[u], height[v]);
    }
  }
  if (compute_answer) {
    if (low[u] == height[u]) {
      int partial_answer = 1;
      while (stack.back() != u) {
        stack.pop_back();
        partial_answer++;
      }
      stack.pop_back();
      if (answer < partial_answer) {
        answer = partial_answer;
        root = u;
      }
    }
  }
  return low[u];
}
void direct_edges(int u) {
  for (auto [v, edge_id] : graph[u]) {
    if (directed_edges[edge_id] == std::pair<int, int>{0, 0}) {
      directed_edges[edge_id] = {u, v};
      if (height[u] + 1 == low[v]) {
        directed_edges[edge_id] = {v, u};
      }
      direct_edges(v);
    }
  }
}
int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(NULL);
  std::cin >> N >> M;
  for (int i = 0; i < M; ++i) {
    int a, b;
    std::cin >> a >> b;
    graph[a].push_back({b, i});
    graph[b].push_back({a, i});
    edges.push_back({a, b});
  }
  std::fill_n(height.begin(), N + 1, -1);
  dfs(1, 0);
  std::fill_n(height.begin(), N + 1, -1);
  directed_edges.resize(M, {0, 0});
  dfs(root, 0, false);
  direct_edges(root);
  std::cout << answer << "\n";
  for (auto [u, v] : directed_edges) {
    std::cout << u << " " << v << "\n";
  }
  return 0;
}
