#include <bits/stdc++.h>
using namespace std;
ifstream fin("ctc.in");
ofstream fout("ctc.out");
std::vector<std::vector<int>> adj;
std::vector<int> indexes;
std::vector<bool> onStack;
std::vector<int> lowLink;
std::vector<int> stk;
std::vector<bool> visited;
std::vector<std::vector<int>> ans;
int n, m;
int idx;
void tarjan(int i) {
indexes[i] = idx;
lowLink[i] = idx;
++idx;
stk.push_back(i);
onStack[i] = true;
for (auto nod : adj[i]) {
if (indexes[nod] == -1) {
tarjan(nod);
lowLink[i] = min(lowLink[i], lowLink[nod]);
} else if (onStack[nod]) {
lowLink[i] = min(lowLink[i], indexes[nod]);
}
}
if (indexes[i] == lowLink[i]) {
std::vector<int> ans_minor;
int x;
do {
x = stk.back();
stk.pop_back();
onStack[x] = false;
ans_minor.push_back(x);
} while (x != i);
ans.push_back(std::move(ans_minor));
}
}
int main() {
fin >> n >> m;
adj.resize(n+1);
visited.resize(n+1);
indexes.resize(n+1);
for (int i = 1; i <= n; ++i) indexes[i] = -1;
onStack.resize(n+1);
lowLink.resize(n+1);
int x, y;
while (m--) {
fin >> x >> y;
adj[x].push_back(y);
}
for (int i = 1; i <= n; ++i) {
if (indexes[i] == -1) {
tarjan(i);
}
}
fout << ans.size() << '\n';
for (auto& vec : ans) {
for (auto elem : vec) {
fout << elem << ' ';
}
fout << '\n';
}
return 0;
}