#include <bits/stdc++.h>
using namespace std;
template <typename T>
void print(T x) {
  cout << x << '\n';
}
template <typename T1, typename T2>
void print2(T1 x, T2 y) {
  cout << x << " " << y << '\n';
}
template <typename T1, typename T2, typename T3>
void print3(T1 x, T2 y, T3 z) {
  cout << x << " " << y << " " << z << '\n';
}
void chandan1() {
  int y = 1;
  return;
}
void chandan2() {
  for (long long int i = 0; i < 10; i++) {
    long long int x = 1;
  }
  return (chandan1());
}
long long int timer = 0;
vector<long long int> adj[400050];
set<long long int> st[400050];
int vis[400050];
long long int in_time[400050], low[400050];
vector<pair<long long int, long long int> > bridges;
map<pair<long long int, long long int>, long long int> mp;
pair<long long int, long long int> ans_edges[400050];
bool contain_bridge = false;
void Assign_orientation(long long int node, long long int parent) {
  vis[node] = 1;
  in_time[node] = low[node] = timer;
  timer++;
  for (auto child : adj[node]) {
    if (child == parent) continue;
    long long int edge_num = mp[{min(child, node), max(child, node)}];
    if (vis[child]) {
      if (in_time[node] > in_time[child]) ans_edges[edge_num] = {node, child};
      low[node] = min(low[node], in_time[child]);
    } else {
      Assign_orientation(child, node);
      if (low[child] > in_time[node])
        ans_edges[edge_num] = {child, node};
      else
        ans_edges[edge_num] = {node, child};
      low[node] = min(low[node], low[child]);
    }
  }
}
void PUSH_BRIDGES(long long int node, long long int parent) {
  vis[node] = 1;
  in_time[node] = low[node] = timer;
  timer++;
  for (auto child : adj[node]) {
    if (child == parent) continue;
    if (vis[child]) {
      low[node] = min(low[node], in_time[child]);
    } else {
      PUSH_BRIDGES(child, node);
      if (low[child] > in_time[node]) bridges.push_back({child, node});
      low[node] = min(low[node], low[child]);
    }
  }
}
long long int cnt = 0;
void bfs(long long int src) {
  vis[src] = 1;
  queue<long long int> q;
  q.push(src);
  while (!q.empty()) {
    long long int u = q.front();
    q.pop();
    cnt++;
    for (auto xt : st[u]) {
      if (!vis[xt]) {
        vis[xt] = 1;
        q.push(xt);
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long int t = 1;
  chandan2();
  while (t--) {
    long long int n;
    cin >> n;
    long long int m;
    cin >> m;
    for (long long int i = 1; i < m + 1; i++) {
      long long int x, y;
      cin >> x >> y;
      if (x > y) swap(x, y);
      adj[x].push_back(y);
      adj[y].push_back(x);
      st[x].insert(y);
      st[y].insert(x);
      mp[{x, y}] = i;
    }
    PUSH_BRIDGES(1, -1);
    for (auto xt : bridges) {
      st[xt.first].erase(xt.second);
      st[xt.second].erase(xt.first);
    }
    memset(vis, 0, sizeof(vis));
    long long int maxi = -1;
    long long int max_node;
    for (long long int i = 1; i < n + 1; i++) {
      if (!vis[i]) {
        cnt = 0;
        bfs(i);
        if (maxi < cnt) {
          maxi = cnt;
          max_node = i;
        }
      }
    }
    memset(vis, 0, sizeof(vis));
    memset(in_time, 0, sizeof(in_time));
    memset(low, 0, sizeof(low));
    timer = 0;
    Assign_orientation(max_node, -1);
    print(maxi);
    for (long long int i = 1; i < m + 1; i++)
      print2(ans_edges[i].first, ans_edges[i].second);
  }
  return 0;
}
