from collections import deque



class Graph():  #directed

    def __init__(self, n, edge):

        self.n = n

        self.graph = [[] for _ in range(n)]

        self.rev = [[] for _ in range(n)]

        self.deg = [0 for _ in range(n)]

        for e in edge:

            self.graph[e[0]].append(e[1])

            self.rev[e[1]].append(e[0])

            self.deg[e[1]] += 1



    def strongry_connected(self):

        group = [None for _ in range(self.n)]

        used = [0 for _ in range(self.n)]

        order = []

        for s in range(self.n):

            if not used[s]:

                stack = [s]

                used[s] = 1

                while stack:

                    node = stack.pop()

                    movable = False

                    for adj in self.graph[node]:

                        if not used[adj]:

                            movable = True

                            used[adj] = 1

                            stack.append(node)

                            stack.append(adj)

                            break

                    if not movable:

                        order.append(node)

        used = [0 for _ in range(self.n)]

        count = 0

        for s in order[::-1]:

            if not used[s]:

                stack = [s]

                group[s] = count

                while stack:

                    node = stack.pop()

                    used[node] = 1

                    for adj in self.rev[node]:

                        if not used[adj]:

                            group[adj] = count

                            stack.append(adj)

                count += 1

        return group, count



    def topological_sort(self):

        res = [i for i in range(self.n) if self.deg[i] == 0]

        queue = deque(res)

        while queue:

            node = queue.popleft()

            for adj in self.graph[node]:

                self.deg[adj] -= 1

                if self.deg[adj] == 0:

                    queue.append(adj)

                    res.append(adj)

        return res



def simplify(edge):

    res = []

    for e in edge:

        if e[0] == e[1]:

            continue

        res.append(e)

    return tuple(set(res))



import sys

input = sys.stdin.readline



N, M = list(map(int, input().split()))

edge = [tuple(map(int, input().split())) for _ in range(M)]



edge = simplify(edge)



g = Graph(N, edge)

group, count = g.strongry_connected() #node_to_group

group_to_node = [[] for _ in range(count)]



for i in range(N):

    group_to_node[group[i]].append(i)



new_edge = []



for a, b in edge:

    new_edge.append((group[a], group[b]))



new_edge = simplify(new_edge)



new_g = Graph(count, new_edge)

ts = new_g.topological_sort()



res = [[] for _ in range(count)]



for i in range(count):

    res[i].append(len(group_to_node[ts[i]]))

    res[i].extend(group_to_node[ts[i]])



print(count)

print(('\n'.join([' '.join(map(str, x)) for x in res])))
class Graph(): #directed

    def __init__(self, n, edge, indexed=1):

        self.n = n

        self.graph = [[] for _ in range(n)]

        self.rev = [[] for _ in range(n)]

        self.deg = [0 for _ in range(n)]

        for e in edge:

            self.graph[e[0] - indexed].append(e[1] - indexed)

            self.rev[e[1] - indexed].append(e[0] - indexed)

            self.deg[e[1] - indexed] += 1



    def strongry_connected(self):

        group = [None for _ in range(self.n)]

        used = [0 for _ in range(self.n)]

        order = []

        for s in range(self.n):

            if not used[s]:

                stack = [s]

                used[s] = 1

                while stack:

                    node = stack.pop()

                    movable = False

                    for adj in self.graph[node]:

                        if not used[adj]:

                            movable = True

                            used[adj] = 1

                            stack.append(node)

                            stack.append(adj)

                            break

                    if not movable:

                        order.append(node)

        used = [0 for _ in range(self.n)]

        count = 0

        for s in order[::-1]:

            if not used[s]:

                stack = [s]

                group[s] = count

                while stack:

                    node = stack.pop()

                    used[node] = 1

                    for adj in self.rev[node]:

                        if not used[adj]:

                            group[adj] = count

                            stack.append(adj)

                count += 1

        return group, count



import sys

input = sys.stdin.buffer.readline



N, M = list(map(int, input().split()))

E = [tuple(map(int, input().split())) for _ in range(M)]



g = Graph(N, E, 0)

group, count = g.strongry_connected()



res = [[] for _ in range(count)]



for i, k in enumerate(group):

    res[k].append(i)



print(count)



for r in res:

    print((len(r), *r))
from collections import deque


class Graph:  # directed
    def __init__(self, n, edge):
        self.n = n
        self.graph = [[] for _ in range(n)]
        self.rev = [[] for _ in range(n)]
        self.deg = [0 for _ in range(n)]
        for e in edge:
            self.graph[e[0]].append(e[1])
            self.rev[e[1]].append(e[0])
            self.deg[e[1]] += 1

    def strongry_connected(self):
        group = [None for _ in range(self.n)]
        used = [0 for _ in range(self.n)]
        order = []
        for s in range(self.n):
            if not used[s]:
                stack = [s]
                used[s] = 1
                while stack:
                    node = stack.pop()
                    movable = False
                    for adj in self.graph[node]:
                        if not used[adj]:
                            movable = True
                            used[adj] = 1
                            stack.append(node)
                            stack.append(adj)
                            break
                    if not movable:
                        order.append(node)
        used = [0 for _ in range(self.n)]
        count = 0
        for s in order[::-1]:
            if not used[s]:
                stack = [s]
                group[s] = count
                while stack:
                    node = stack.pop()
                    used[node] = 1
                    for adj in self.rev[node]:
                        if not used[adj]:
                            group[adj] = count
                            stack.append(adj)
                count += 1
        return group, count

    def topological_sort(self):
        res = [i for i in range(self.n) if self.deg[i] == 0]
        queue = deque(res)
        while queue:
            node = queue.popleft()
            for adj in self.graph[node]:
                self.deg[adj] -= 1
                if self.deg[adj] == 0:
                    queue.append(adj)
                    res.append(adj)
        return res


def simplify(edge):
    res = []
    for e in edge:
        if e[0] == e[1]:
            continue
        res.append(e)
    return tuple(set(res))


import sys

input = sys.stdin.readline
N, M = list(map(int, input().split()))
edge = [tuple(map(int, input().split())) for _ in range(M)]
edge = simplify(edge)
g = Graph(N, edge)
group, count = g.strongry_connected()  # node_to_group
group_to_node = [[] for _ in range(count)]
for i in range(N):
    group_to_node[group[i]].append(i)
new_edge = []
for a, b in edge:
    new_edge.append((group[a], group[b]))
new_edge = simplify(new_edge)
new_g = Graph(count, new_edge)
ts = new_g.topological_sort()
res = [[] for _ in range(count)]
for i in range(count):
    res[i].append(len(group_to_node[ts[i]]))
    res[i].extend(group_to_node[ts[i]])
print(count)
print(("\n".join([" ".join(map(str, x)) for x in res])))

class Graph:  # directed
    def __init__(self, n, edge, indexed=1):
        self.n = n
        self.graph = [[] for _ in range(n)]
        self.rev = [[] for _ in range(n)]
        self.deg = [0 for _ in range(n)]
        for e in edge:
            self.graph[e[0] - indexed].append(e[1] - indexed)
            self.rev[e[1] - indexed].append(e[0] - indexed)
            self.deg[e[1] - indexed] += 1

    def strongry_connected(self):
        group = [None for _ in range(self.n)]
        used = [0 for _ in range(self.n)]
        order = []
        for s in range(self.n):
            if not used[s]:
                stack = [s]
                used[s] = 1
                while stack:
                    node = stack.pop()
                    movable = False
                    for adj in self.graph[node]:
                        if not used[adj]:
                            movable = True
                            used[adj] = 1
                            stack.append(node)
                            stack.append(adj)
                            break
                    if not movable:
                        order.append(node)
        used = [0 for _ in range(self.n)]
        count = 0
        for s in order[::-1]:
            if not used[s]:
                stack = [s]
                group[s] = count
                while stack:
                    node = stack.pop()
                    used[node] = 1
                    for adj in self.rev[node]:
                        if not used[adj]:
                            group[adj] = count
                            stack.append(adj)
                count += 1
        return group, count


import sys

input = sys.stdin.buffer.readline
N, M = list(map(int, input().split()))
E = [tuple(map(int, input().split())) for _ in range(M)]
g = Graph(N, E, 0)
group, count = g.strongry_connected()
res = [[] for _ in range(count)]
for i, k in enumerate(group):
    res[k].append(i)
print(count)
for r in res:
    print((len(r), *r))

-from collections import deque - - -    def __init__(self, n, edge): +    def __init__(self, n, edge, indexed=1): -            self.graph[e[0]].append(e[1]) -            self.rev[e[1]].append(e[0]) -            self.deg[e[1]] += 1 +            self.graph[e[0] - indexed].append(e[1] - indexed) +            self.rev[e[1] - indexed].append(e[0] - indexed) +            self.deg[e[1] - indexed] += 1 -    def topological_sort(self): -        res = [i for i in range(self.n) if self.deg[i] == 0] -        queue = deque(res) -        while queue: -            node = queue.popleft() -            for adj in self.graph[node]: -                self.deg[adj] -= 1 -                if self.deg[adj] == 0: -                    queue.append(adj) -                    res.append(adj) -        return res - - -def simplify(edge): -    res = [] -    for e in edge: -        if e[0] == e[1]: -            continue -        res.append(e) -    return tuple(set(res)) - -input = sys.stdin.readline +input = sys.stdin.buffer.readline -edge = [tuple(map(int, input().split())) for _ in range(M)] -edge = simplify(edge) -g = Graph(N, edge) -group, count = g.strongry_connected()  # node_to_group -group_to_node = [[] for _ in range(count)] -for i in range(N): -    group_to_node[group[i]].append(i) -new_edge = [] -for a, b in edge: -    new_edge.append((group[a], group[b])) -new_edge = simplify(new_edge) -new_g = Graph(count, new_edge) -ts = new_g.topological_sort() +E = [tuple(map(int, input().split())) for _ in range(M)] +g = Graph(N, E, 0) +group, count = g.strongry_connected() -for i in range(count): -    res[i].append(len(group_to_node[ts[i]])) -    res[i].extend(group_to_node[ts[i]]) +for i, k in enumerate(group): +    res[k].append(i) -print(("\n".join([" ".join(map(str, x)) for x in res]))) +for r in res: +    print((len(r), *r))