import os

import sys



import numpy as np





def solve(inp):

    def dfs(links, s, checked, postorder):

        stack = [0, s]

        while stack:

            i, v = stack[-2:]

            if i == 0 and checked[v]:

                stack.pop()

                stack.pop()

                continue

            checked[v] = 1

            l = len(links[v])

            while i < l and checked[links[v][i]] == 1:

                i += 1

            if i == l:

                postorder.append(v)

                stack.pop()

                stack.pop()

                continue

            stack[-2] = i + 1

            stack.append(0)

            stack.append(links[v][i])



    def dfs2(rev_links, s, checked):

        q = [s]

        checked[s] = 1

        scc = [s]

        while q:

            v = q.pop()

            for u in rev_links[v]:

                if checked[u] == 0:

                    q.append(u)

                    checked[u] = 1

                    scc.append(u)

        return scc



    n = inp[0]

    m = inp[1]

    aaa = inp[2::2]

    bbb = inp[3::2]



    int_list = [0]

    int_list.clear()

    links = [int_list.copy() for _ in range(n)]

    rev_links = [int_list.copy() for _ in range(n)]



    for i in range(m):

        a = aaa[i]

        b = bbb[i]

        if a != b:

            links[a].append(b)

            rev_links[b].append(a)



    checked = np.zeros(n, np.int8)

    postorder = []



    for v in range(n):

        if checked[v]:

            continue

        dfs(links, v, checked, postorder)



    postorder.reverse()

    checked = np.zeros(n, np.int8)

    sccs = []



    for v in postorder:

        if checked[v]:

            continue

        sccs.append(dfs2(rev_links, v, checked))



    return sccs





if sys.argv[-1] == 'ONLINE_JUDGE':

    from numba.pycc import CC



    cc = CC('my_module')

    cc.export('solve', '(i8[:],)')(solve)

    cc.compile()

    exit()



if os.name == 'posix':

    # noinspection PyUnresolvedReferences

    from my_module import solve

else:

    from numba import njit



    solve = njit('(i8[:],)', cache=True)(solve)

    print('compiled', file=sys.stderr)



inp = np.fromstring(sys.stdin.read(), dtype=np.int64, sep=' ')

ans = solve(inp)

print(len(ans))

for scc in ans:

    print(len(scc), *scc)

import os

import sys



import numpy as np





def solve(inp):

    def scc_dfs1(links, s, stack, checked, postorder, pi):

        stack[0] = 0

        stack[1] = s

        si = 2

        while si > 0:

            i = stack[si - 2]

            v = stack[si - 1]

            if i == 0 and checked[v]:

                si -= 2

                continue

            checked[v] = 1

            l = len(links[v])

            while i < l and checked[links[v][i]] == 1:

                i += 1

            if i == l:

                postorder[pi] = v

                pi += 1

                si -= 2

                continue

            stack[si - 2] = i + 1

            stack[si] = 0

            stack[si + 1] = links[v][i]

            si += 2

        return pi



    def scc_dfs2(rev_links, s, stack, checked):

        stack[0] = s

        si = 1

        checked[s] = 1

        scc = [s]

        while si > 0:

            si -= 1

            v = stack[si]

            for u in rev_links[v]:

                if checked[u] == 0:

                    checked[u] = 1

                    stack[si] = u

                    si += 1

                    scc.append(u)

        return scc



    def scc(n, links, rev_links):

        stack = np.zeros(n * 5, np.int64)

        checked = np.zeros(n, np.int8)

        postorder = np.zeros(n, np.int64)

        pi = 0



        for v in range(n):

            if checked[v]:

                continue

            pi = scc_dfs1(links, v, stack, checked, postorder, pi)



        postorder = postorder[::-1]

        checked = np.zeros(n, np.int8)

        sccs = []



        for v in postorder:

            if checked[v]:

                continue

            sccs.append(scc_dfs2(rev_links, v, stack, checked))



        return sccs



    n = inp[0]

    m = inp[1]

    aaa = inp[2::2]

    bbb = inp[3::2]



    int_list = [0]

    int_list.clear()

    links = [int_list.copy() for _ in range(n)]

    rev_links = [int_list.copy() for _ in range(n)]



    for i in range(m):

        a = aaa[i]

        b = bbb[i]

        if a != b:

            links[a].append(b)

            rev_links[b].append(a)



    return scc(n, links, rev_links)





if sys.argv[-1] == 'ONLINE_JUDGE':

    from numba.pycc import CC



    cc = CC('my_module')

    cc.export('solve', '(i8[:],)')(solve)

    cc.compile()

    exit()



if os.name == 'posix':

    # noinspection PyUnresolvedReferences

    from my_module import solve

else:

    from numba import njit



    solve = njit('(i8[:],)', cache=True)(solve)

    print('compiled', file=sys.stderr)



inp = np.fromstring(sys.stdin.read(), dtype=np.int64, sep=' ')

ans = solve(inp)

print(len(ans))

for scc in ans:

    print(len(scc), *scc)

import os
import sys
import numpy as np


def solve(inp):
    def dfs(links, s, checked, postorder):
        stack = [0, s]
        while stack:
            i, v = stack[-2:]
            if i == 0 and checked[v]:
                stack.pop()
                stack.pop()
                continue
            checked[v] = 1
            l = len(links[v])
            while i < l and checked[links[v][i]] == 1:
                i += 1
            if i == l:
                postorder.append(v)
                stack.pop()
                stack.pop()
                continue
            stack[-2] = i + 1
            stack.append(0)
            stack.append(links[v][i])

    def dfs2(rev_links, s, checked):
        q = [s]
        checked[s] = 1
        scc = [s]
        while q:
            v = q.pop()
            for u in rev_links[v]:
                if checked[u] == 0:
                    q.append(u)
                    checked[u] = 1
                    scc.append(u)
        return scc

    n = inp[0]
    m = inp[1]
    aaa = inp[2::2]
    bbb = inp[3::2]
    int_list = [0]
    int_list.clear()
    links = [int_list.copy() for _ in range(n)]
    rev_links = [int_list.copy() for _ in range(n)]
    for i in range(m):
        a = aaa[i]
        b = bbb[i]
        if a != b:
            links[a].append(b)
            rev_links[b].append(a)
    checked = np.zeros(n, np.int8)
    postorder = []
    for v in range(n):
        if checked[v]:
            continue
        dfs(links, v, checked, postorder)
    postorder.reverse()
    checked = np.zeros(n, np.int8)
    sccs = []
    for v in postorder:
        if checked[v]:
            continue
        sccs.append(dfs2(rev_links, v, checked))
    return sccs


if sys.argv[-1] == "ONLINE_JUDGE":
    from numba.pycc import CC

    cc = CC("my_module")
    cc.export("solve", "(i8[:],)")(solve)
    cc.compile()
    exit()
if os.name == "posix":
    # noinspection PyUnresolvedReferences
    from my_module import solve
else:
    from numba import njit

    solve = njit("(i8[:],)", cache=True)(solve)
    print("compiled", file=sys.stderr)
inp = np.fromstring(sys.stdin.read(), dtype=np.int64, sep=" ")
ans = solve(inp)
print(len(ans))
for scc in ans:
    print(len(scc), *scc)

import os
import sys
import numpy as np


def solve(inp):
    def scc_dfs1(links, s, stack, checked, postorder, pi):
        stack[0] = 0
        stack[1] = s
        si = 2
        while si > 0:
            i = stack[si - 2]
            v = stack[si - 1]
            if i == 0 and checked[v]:
                si -= 2
                continue
            checked[v] = 1
            l = len(links[v])
            while i < l and checked[links[v][i]] == 1:
                i += 1
            if i == l:
                postorder[pi] = v
                pi += 1
                si -= 2
                continue
            stack[si - 2] = i + 1
            stack[si] = 0
            stack[si + 1] = links[v][i]
            si += 2
        return pi

    def scc_dfs2(rev_links, s, stack, checked):
        stack[0] = s
        si = 1
        checked[s] = 1
        scc = [s]
        while si > 0:
            si -= 1
            v = stack[si]
            for u in rev_links[v]:
                if checked[u] == 0:
                    checked[u] = 1
                    stack[si] = u
                    si += 1
                    scc.append(u)
        return scc

    def scc(n, links, rev_links):
        stack = np.zeros(n * 5, np.int64)
        checked = np.zeros(n, np.int8)
        postorder = np.zeros(n, np.int64)
        pi = 0
        for v in range(n):
            if checked[v]:
                continue
            pi = scc_dfs1(links, v, stack, checked, postorder, pi)
        postorder = postorder[::-1]
        checked = np.zeros(n, np.int8)
        sccs = []
        for v in postorder:
            if checked[v]:
                continue
            sccs.append(scc_dfs2(rev_links, v, stack, checked))
        return sccs

    n = inp[0]
    m = inp[1]
    aaa = inp[2::2]
    bbb = inp[3::2]
    int_list = [0]
    int_list.clear()
    links = [int_list.copy() for _ in range(n)]
    rev_links = [int_list.copy() for _ in range(n)]
    for i in range(m):
        a = aaa[i]
        b = bbb[i]
        if a != b:
            links[a].append(b)
            rev_links[b].append(a)
    return scc(n, links, rev_links)


if sys.argv[-1] == "ONLINE_JUDGE":
    from numba.pycc import CC

    cc = CC("my_module")
    cc.export("solve", "(i8[:],)")(solve)
    cc.compile()
    exit()
if os.name == "posix":
    # noinspection PyUnresolvedReferences
    from my_module import solve
else:
    from numba import njit

    solve = njit("(i8[:],)", cache=True)(solve)
    print("compiled", file=sys.stderr)
inp = np.fromstring(sys.stdin.read(), dtype=np.int64, sep=" ")
ans = solve(inp)
print(len(ans))
for scc in ans:
    print(len(scc), *scc)

-    def dfs(links, s, checked, postorder): -        stack = [0, s] -        while stack: -            i, v = stack[-2:] +    def scc_dfs1(links, s, stack, checked, postorder, pi): +        stack[0] = 0 +        stack[1] = s +        si = 2 +        while si > 0: +            i = stack[si - 2] +            v = stack[si - 1] -                stack.pop() -                stack.pop() +                si -= 2 -                postorder.append(v) -                stack.pop() -                stack.pop() +                postorder[pi] = v +                pi += 1 +                si -= 2 -            stack[-2] = i + 1 -            stack.append(0) -            stack.append(links[v][i]) +            stack[si - 2] = i + 1 +            stack[si] = 0 +            stack[si + 1] = links[v][i] +            si += 2 +        return pi -    def dfs2(rev_links, s, checked): -        q = [s] +    def scc_dfs2(rev_links, s, stack, checked): +        stack[0] = s +        si = 1 -        while q: -            v = q.pop() +        while si > 0: +            si -= 1 +            v = stack[si] -                    q.append(u) +                    stack[si] = u +                    si += 1 + +    def scc(n, links, rev_links): +        stack = np.zeros(n * 5, np.int64) +        checked = np.zeros(n, np.int8) +        postorder = np.zeros(n, np.int64) +        pi = 0 +        for v in range(n): +            if checked[v]: +                continue +            pi = scc_dfs1(links, v, stack, checked, postorder, pi) +        postorder = postorder[::-1] +        checked = np.zeros(n, np.int8) +        sccs = [] +        for v in postorder: +            if checked[v]: +                continue +            sccs.append(scc_dfs2(rev_links, v, stack, checked)) +        return sccs -    checked = np.zeros(n, np.int8) -    postorder = [] -    for v in range(n): -        if checked[v]: -            continue -        dfs(links, v, checked, postorder) -    postorder.reverse() -    checked = np.zeros(n, np.int8) -    sccs = [] -    for v in postorder: -        if checked[v]: -            continue -        sccs.append(dfs2(rev_links, v, checked)) -    return sccs +    return scc(n, links, rev_links)