#include <fstream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
ifstream cin("ctc.in");
ofstream cout("ctc.out");
int n, m;
vector<vector<int>> gr(100100);
vector<vector<int>> inv(100100);
vector<bool> used(100100);
vector<int> order;
vector<int> comp;
vector<vector<int>> ans;
void dfs1(int node) {
used[node] = true;
for (int neighbor : gr[node]) {
if (!used[neighbor]) {
dfs1(neighbor);
}
}
order.push_back(node);
}
void dfs2(int node, vector<bool>& visited) {
visited[node] = true;
comp.push_back(node);
for (int neighbor : inv[node]) {
if (!visited[neighbor]) {
dfs2(neighbor, visited);
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
gr[a].push_back(b);
inv[b].push_back(a);
}
for (int i = 1; i <= n; i++) {
if (!used[i]) {
dfs1(i);
}
}
vector<bool> visited(100100, false);
reverse(order.begin(), order.end());
for (int node : order) {
if (!visited[node]) {
comp.clear();
dfs2(node, visited);
sort(comp.begin(), comp.end());
ans.push_back(comp);
}
}
cout << ans.size() << '\n';
for (const auto& component : ans) {
for (int node : component) {
cout << node << " ";
}
cout << '\n';
}
return 0;
}