#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream in ("strazi.in");
ofstream out ("strazi.out");
const int max_size = 256;
int vizitat[max_size], inc[max_size], last;
vector <int> edges[max_size], ans, st;
vector <pair <int,int>> muchii;
queue <int> coada;
void dfs (int nod)
{
vizitat[nod] = 1;
ans.push_back(nod);
if (edges[nod].size() == 0)
{
last = nod;
}
if (edges[nod].size() == 1)
{
dfs(edges[nod][0]);
}
if (edges[nod].size() > 1)
{
dfs(edges[nod][0]);
for (int i = 1; i < edges[nod].size(); i++)
{
muchii.push_back(make_pair(last, edges[nod][i]));
dfs(edges[nod][i]);
}
}
}
int main ()
{
int n, t;
in >> n >> t;
while (t--)
{
int x, y;
in >> x >> y;
edges[x].push_back(y);
inc[y] = 1;
}
for (int i = 1; i <= n; i++)
{
if (inc[i] == 0)
{
coada.push(i); /// fac DFS pt fiecare nod care nu are muchie de in
/// repr gen radacina unui subarb maxim din comp conexa din graf
}
}
/// fac o pseudo muchie pt primul subarbore
while (!coada.empty())
{
muchii.push_back(make_pair(last, coada.front()));
dfs(coada.front());
coada.pop();
}
out << muchii.size() - 1 << '\n';
for (int i = 1; i < muchii.size(); i++)
{
out << muchii[i].first << " " << muchii[i].second << '\n';
}
for (auto f : ans)
{
out << f << " ";
}
in.close();
out.close();
return 0;
}