import sys
def solve():
# --- 1. CITIRE RAPIDA ---
try:
# Citim tot continutul (inputul poate fi mare)
input_data = sys.stdin.read().split()
except Exception:
return
if not input_data:
return
iterator = iter(input_data)
try:
n = int(next(iterator))
m = int(next(iterator))
# Initializam listele de adiacenta
adj = [[] for _ in range(n + 1)]
adj_rev = [[] for _ in range(n + 1)]
for _ in range(m):
u = int(next(iterator))
v = int(next(iterator))
adj[u].append(v)
adj_rev[v].append(u)
except StopIteration:
return
# --- 2. PASUL 1: DFS Iterativ pentru ordinea de finalizare ---
# Scop: Sa umplem 'order_stack' (echivalentul lui sv/stc)
visited = [False] * (n + 1)
order_stack = []
# Pentru DFS iterativ post-order avem nevoie sa stim unde am ramas la vecini
# iter_state[u] = indexul urmatorului vecin de vizitat pentru nodul u
iter_state = [0] * (n + 1)
for i in range(1, n + 1):
if not visited[i]:
# Simulam stiva recursiva manual
stack = [i]
visited[i] = True
while stack:
u = stack[-1] # Ne uitam la nodul din varf
# Avem vecini nevizitati?
if iter_state[u] < len(adj[u]):
v = adj[u][iter_state[u]]
iter_state[u] += 1 # Avansam indexul pentru data viitoare
if not visited[v]:
visited[v] = True
stack.append(v) # Intram in recursivitate (push)
else:
# Toti vecinii au fost vizitati, terminam nodul u
stack.pop() # Iesim din recursivitate
order_stack.append(u) # Adaugam in lista de ordine (post-order)
# --- 3. PASUL 2: DFS/BFS Iterativ pe graful transpus ---
# Aici e mai simplu, nu ne trebuie post-order, doar accesibilitate
visited_rev = [False] * (n + 1)
solutie = []
# Parcurgem stiva de la coada la cap (LIFO)
while order_stack:
nod_start = order_stack.pop()
if not visited_rev[nod_start]:
componenta = []
# Facem un DFS simplu iterativ (sau BFS) pentru a colecta componenta
stiva_comp = [nod_start]
visited_rev[nod_start] = True
while stiva_comp:
u = stiva_comp.pop()
componenta.append(u)
for v in adj_rev[u]:
if not visited_rev[v]:
visited_rev[v] = True
stiva_comp.append(v)
solutie.append(componenta)
# --- 4. AFISARE ---
# Folosim stdout.write pentru viteza maxima
out = []
out.append(str(len(solutie)))
for comp in solutie:
# Convertim linia in string: "1 2 3"
out.append(" ".join(map(str, comp)))
print('\n'.join(out))
if __name__ == "__main__":
# Redirectionare intrare/iesire daca e cazul (pentru Infoarena/PbInfo sterge sau lasa comentat daca nu e nevoie)
try:
sys.stdin = open("ctc.in", "r")
sys.stdout = open("ctc.out", "w")
except FileNotFoundError:
pass
solve()