#include <bits/stdc++.h>
using namespace std;
vector<vector<pair<int, int> > > v(400005);
int parent[400005], low[400005], disc[400005], TIME;
bool visited[400005], road[400005];
set<int> bridge;
int SIZE;
pair<int, int> EDGE[400005];
void dfs(int a) {
  TIME++;
  visited[a] = true;
  disc[a] = TIME, low[a] = TIME;
  for (int i = 0; i < v[a].size(); i++) {
    if (!visited[v[a][i].first]) {
      parent[v[a][i].first] = a;
      dfs(v[a][i].first);
      low[a] = min(low[a], low[v[a][i].first]);
      if (low[v[a][i].first] > disc[a]) bridge.insert(v[a][i].second);
    } else if (v[a][i].first != parent[a])
      low[a] = min(low[a], disc[v[a][i].first]);
  }
}
void dfs2(int a) {
  visited[a] = true;
  SIZE++;
  for (int i = 0; i < v[a].size(); i++)
    if (bridge.count(v[a][i].second) == 0 and !visited[v[a][i].first])
      dfs2(v[a][i].first);
}
void solve(int a) {
  for (int i = 0; i < v[a].size(); i++) {
    if (!road[v[a][i].second]) {
      road[v[a][i].second] = true;
      if (bridge.count(v[a][i].second) == 0)
        EDGE[v[a][i].second] = make_pair(a, v[a][i].first);
      else
        EDGE[v[a][i].second] = make_pair(v[a][i].first, a);
      solve(v[a][i].first);
    }
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  int MAXSIZE = 0, NODE;
  for (int i = 0; i < m; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    v[x].push_back(make_pair(y, i)), v[y].push_back(make_pair(x, i));
  }
  dfs(1);
  memset(visited, false, sizeof(visited));
  for (int i = 0; i < n; i++) {
    SIZE = 0;
    if (!visited[i + 1]) dfs2(i + 1);
    if (SIZE > MAXSIZE) MAXSIZE = SIZE, NODE = i + 1;
  }
  solve(NODE);
  cout << MAXSIZE << endl;
  for (int i = 0; i < m; i++)
    cout << EDGE[i].first << " " << EDGE[i].second << endl;
}
