#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define pii pair<int, int>
#define mp make_pair
#define fi first
#define se second
/*#define cin inp
ifstream inp("in6.txt");
ifstream corr("out6.txt");*/
const int maxn = 1e4;
const int maxm = 3e5;
const int inf = 1e7 + 42;
int n, m;
vector<int> g[maxn + 1];
vector<pii > ans;
bool vis0[maxn + 1];
bool done0[maxn + 1];
int S, T, F, A;
void dfs0(int x) {
vis0[x] = true;
for(int y : g[x]) {
if(!vis0[y]) {
dfs0(y);
} else if(!done0[y]) {
S = y;
}
}
done0[x] = true;
}
void GetS() {
for(int i = 1; i <= n; i++) {
if(!vis0[i]) {
dfs0(i);
}
}
}
int par[maxn + 1];
bool vis1[maxn + 1];
bool done1[maxn + 1];
int timer, low_d, high_d, backedge_cnt, leaf_cnt;
int d[maxn + 1];
int by_d[maxn + 1];
pii special_edge;
bool leaf[maxn + 1];
void dfs1(int x, int p) {
timer++;
d[x] = timer;
vis1[x] = true;
par[x] = p;
for(int y : g[x]) {
if(!vis1[y]) {
// gyerek
dfs1(y, x);
} else if(!done1[y]) {
// vissza-el
if(!leaf[x]) {
leaf_cnt++;
}
leaf[x] = true;
low_d = min(low_d, d[y]);
high_d = max(high_d, d[y]);
backedge_cnt++;
special_edge = mp(x, y);
} else {
// kereszt-el vagy elore-el
//
}
}
done1[x] = true;
}
void GetTF() {
low_d = inf;
high_d = 0;
dfs1(S, -1);
if(backedge_cnt == 1) {
ans.pb(special_edge); // edge case 1
}
for(int i = 1; i <= n; i++) {
if(d[i] == low_d) {
T = i;
}
if(d[i] == high_d) {
F = i;
}
}
for(int i = 1; i <= n; i++) {
by_d[d[i]] = i;
}
}
bool vis2[maxn + 1];
int dfs2(int x) {
vis2[x] = true;
int res = leaf[x];
for(int y : g[x]) {
if(!vis2[y]) {
res += dfs2(y);
}
}
if(res == leaf_cnt && !A) {
A = x;
}
return res;
}
void GetA() {
dfs2(S);
}
bool on_path[maxn + 1];
vector<int> path;
void GetPath1() {
int x = A;
while(x != F) {
on_path[x] = true;
x = par[x];
}
on_path[x] = true;
reverse(path.begin(), path.end());
}
void GetPath2() {
int x = A;
while(x != T) {
path.pb(x);
x = par[x];
}
path.pb(x);
reverse(path.begin(), path.end());
}
int f[maxn + 1];
bool vis3[maxn + 1];
void dfs3(int x, int val) {
vis3[x] = true;
f[x] = val;
for(int y : g[x]) {
if(!vis3[y] && !(par[y] == x && on_path[x] && on_path[y])) {
dfs3(y, val);
}
}
}
void CalcF() {
for(int i = 1; i <= n; i++) {
f[i] = inf;
}
for(int x : path) {
if(!vis3[x]) {
dfs3(x, d[x]);
}
}
}
vector<int> top;
bool vis4[maxn + 1];
void dfs4(int x) {
vis4[x] = true;
for(int y : g[x]) {
if(!vis4[y] && par[y] == x) {
dfs4(y);
}
}
top.pb(x);
}
void CalcTop() {
dfs4(F);
}
bool go[maxn + 1];
void GoBack() {
for(int x : top) {
if(x == F || (!leaf[x] && !go[x])) {
continue;
}
if(f[x] != inf && by_d[f[x]] == x && on_path[x] && on_path[par[x]]) {
ans.pb(mp(par[x], x));
}
f[par[x]] = min(f[par[x]], f[x]);
go[par[x]] = true;
}
}
void Answer() {
cout << (int) ans.size() << "\n";
for(pii p : ans) {
cout << p.fi << " " << p.se << "\n";
}
}
void solve() {
cin >> n >> m;
for(int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
g[a].pb(b);
}
GetS();
GetTF();
GetA();
GetPath1();
GetPath2();
CalcF();
CalcTop();
GoBack();
//
Answer();
}
bool benne(vector<pii > v, pii p) {
for(pii q : v) {
if(p == q) {
return true;
}
}
return false;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
solve();
/*int tmp;
corr >> tmp;
vector<pii > v(tmp);
for(pii &p : v) {
corr >> p.fi >> p.se;
}
cout << "Joban benne de nem irom ki:\n";
for(pii p : v) {
if(!benne(ans, p)) {
cout << p.fi << " " << p.se << "\n";
}
}
cout << "Kiirom de nem kellene:\n";
for(pii p : ans) {
if(!benne(v, p)) {
cout << p.fi << " " << p.se << "\n";
}
}*/
/*cout << (int) v.size() << "\n";
for(int i = 0; i < tmp; i++) {
cout << v[i].fi << " " << v[i].se << "\n";
}*/
return 0;
}
/*
Edge case-ek:
[X] csak egy visszaél van
- ...
*/