import sys

readline = sys.stdin.readline

#非再帰

import sys

def scc(Edge):

    N = len(Edge)

    Edgeinv = [[] for _ in range(N)]

    for vn in range(N):

        for vf in Edge[vn]:

            Edgeinv[vf].append(vn)

    

    used = [False]*N

    dim = [len(Edge[i]) for i in range(N)]

    order = []

    for st in range(N):

        if not used[st]:

            stack = [st, 0]

            while stack:

                vn, i = stack[-2], stack[-1]   

                if not i and used[vn]:

                    stack.pop()

                    stack.pop()

                else:

                    used[vn] = True

                    if i < dim[vn]:

                        stack[-1] += 1

                        stack.append(Edge[vn][i])

                        stack.append(0)

                    else:

                        stack.pop()

                        order.append(stack.pop())

    res = [None]*N

    used = [False]*N

    cnt = -1

    for st in order[::-1]:

        if not used[st]:

            cnt += 1

            stack = [st]

            res[st] = cnt

            used[st] = True

            while stack:

                vn = stack.pop()

                for vf in Edgeinv[vn]:

                    if not used[vf]:

                        used[vf] = True

                        res[vf] = cnt

                        stack.append(vf)

    M = cnt+1

    components = [[] for _ in range(M)]

    for i in range(N):

        components[res[i]].append(i)

    tEdge = [[] for _ in range(M)]

    """

    teset = set()

    for vn in range(N):

        tn = res[vn]

        for vf in Edge[vn]:

            tf = res[vf]

            if tn != tf and tn*M + tf not in teset:

                teset.add(tn*M + tf)

                tEdge[tn].append(tf)

    """

    return res, components, tEdge

        

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

Edge = [[] for _ in range(N)]

for _ in range(M):

    a, b = list(map(int, readline().split()))

    Edge[a].append(b)



R, comp, tE = scc(Edge)

Ans = [str(len(comp))]



for c in comp:

    Ans.append(f'{len(c)} ' + ' '.join(map(str, c)))



print(('\n'.join(Ans)))



import sys

readline = sys.stdin.readline

#非再帰

import sys

def scc(Edge):

    N = len(Edge)

    Edgeinv = [[] for _ in range(N)]

    for vn in range(N):

        for vf in Edge[vn]:

            Edgeinv[vf].append(vn)

    

    used = [0]*N

    order = []

    for st in range(N):

        if used[st]:

            continue

        stack = [~st, st]

        while stack:

            vn = stack.pop()

            if vn >= 0:

                if used[vn]:

                    continue

                used[vn] = 1

                for vf in Edge[vn]:

                    if used[vf]:

                        continue

                    stack.append(~vf)

                    stack.append(vf)

            else:

                if used[~vn] != 2:

                    used[~vn] = 2

                    order.append(~vn)





    res = [None]*N

    used = [False]*N

    cnt = -1

    for st in order[::-1]:

        if not used[st]:

            cnt += 1

            stack = [st]

            res[st] = cnt

            used[st] = True

            while stack:

                vn = stack.pop()

                for vf in Edgeinv[vn]:

                    if not used[vf]:

                        used[vf] = True

                        res[vf] = cnt

                        stack.append(vf)

    M = cnt+1

    components = [[] for _ in range(M)]

    for i in range(N):

        components[res[i]].append(i)

    """

    tEdge = [[] for _ in range(M)]

    teset = set()

    for vn in range(N):

        tn = res[vn]

        for vf in Edge[vn]:

            tf = res[vf]

            if tn != tf and tn*M + tf not in teset:

                teset.add(tn*M + tf)

                tEdge[tn].append(tf)

    """

    return res, components





        

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

Edge = [[] for _ in range(N)]

for _ in range(M):

    a, b = list(map(int, readline().split()))

    Edge[a].append(b)



R, comp = scc(Edge)

Ans = [str(len(comp))]



for c in comp:

    Ans.append(f'{len(c)} ' + ' '.join(map(str, c)))



print(('\n'.join(Ans)))









import sys

readline = sys.stdin.readline
# 非再帰
import sys


def scc(Edge):
    N = len(Edge)
    Edgeinv = [[] for _ in range(N)]
    for vn in range(N):
        for vf in Edge[vn]:
            Edgeinv[vf].append(vn)
    used = [False] * N
    dim = [len(Edge[i]) for i in range(N)]
    order = []
    for st in range(N):
        if not used[st]:
            stack = [st, 0]
            while stack:
                vn, i = stack[-2], stack[-1]
                if not i and used[vn]:
                    stack.pop()
                    stack.pop()
                else:
                    used[vn] = True
                    if i < dim[vn]:
                        stack[-1] += 1
                        stack.append(Edge[vn][i])
                        stack.append(0)
                    else:
                        stack.pop()
                        order.append(stack.pop())
    res = [None] * N
    used = [False] * N
    cnt = -1
    for st in order[::-1]:
        if not used[st]:
            cnt += 1
            stack = [st]
            res[st] = cnt
            used[st] = True
            while stack:
                vn = stack.pop()
                for vf in Edgeinv[vn]:
                    if not used[vf]:
                        used[vf] = True
                        res[vf] = cnt
                        stack.append(vf)
    M = cnt + 1
    components = [[] for _ in range(M)]
    for i in range(N):
        components[res[i]].append(i)
    tEdge = [[] for _ in range(M)]
    """
    teset = set()
    for vn in range(N):
        tn = res[vn]
        for vf in Edge[vn]:
            tf = res[vf]
            if tn != tf and tn*M + tf not in teset:
                teset.add(tn*M + tf)
                tEdge[tn].append(tf)
    """
    return res, components, tEdge


N, M = list(map(int, readline().split()))
Edge = [[] for _ in range(N)]
for _ in range(M):
    a, b = list(map(int, readline().split()))
    Edge[a].append(b)
R, comp, tE = scc(Edge)
Ans = [str(len(comp))]
for c in comp:
    Ans.append(f"{len(c)} " + " ".join(map(str, c)))
print(("\n".join(Ans)))

import sys

readline = sys.stdin.readline
# 非再帰
import sys


def scc(Edge):
    N = len(Edge)
    Edgeinv = [[] for _ in range(N)]
    for vn in range(N):
        for vf in Edge[vn]:
            Edgeinv[vf].append(vn)
    used = [0] * N
    order = []
    for st in range(N):
        if used[st]:
            continue
        stack = [~st, st]
        while stack:
            vn = stack.pop()
            if vn >= 0:
                if used[vn]:
                    continue
                used[vn] = 1
                for vf in Edge[vn]:
                    if used[vf]:
                        continue
                    stack.append(~vf)
                    stack.append(vf)
            else:
                if used[~vn] != 2:
                    used[~vn] = 2
                    order.append(~vn)
    res = [None] * N
    used = [False] * N
    cnt = -1
    for st in order[::-1]:
        if not used[st]:
            cnt += 1
            stack = [st]
            res[st] = cnt
            used[st] = True
            while stack:
                vn = stack.pop()
                for vf in Edgeinv[vn]:
                    if not used[vf]:
                        used[vf] = True
                        res[vf] = cnt
                        stack.append(vf)
    M = cnt + 1
    components = [[] for _ in range(M)]
    for i in range(N):
        components[res[i]].append(i)
    """
    tEdge = [[] for _ in range(M)]
    teset = set()
    for vn in range(N):
        tn = res[vn]
        for vf in Edge[vn]:
            tf = res[vf]
            if tn != tf and tn*M + tf not in teset:
                teset.add(tn*M + tf)
                tEdge[tn].append(tf)
    """
    return res, components


N, M = list(map(int, readline().split()))
Edge = [[] for _ in range(N)]
for _ in range(M):
    a, b = list(map(int, readline().split()))
    Edge[a].append(b)
R, comp = scc(Edge)
Ans = [str(len(comp))]
for c in comp:
    Ans.append(f"{len(c)} " + " ".join(map(str, c)))
print(("\n".join(Ans)))

-    used = [False] * N -    dim = [len(Edge[i]) for i in range(N)] +    used = [0] * N -        if not used[st]: -            stack = [st, 0] -            while stack: -                vn, i = stack[-2], stack[-1] -                if not i and used[vn]: -                    stack.pop() -                    stack.pop() -                else: -                    used[vn] = True -                    if i < dim[vn]: -                        stack[-1] += 1 -                        stack.append(Edge[vn][i]) -                        stack.append(0) -                    else: -                        stack.pop() -                        order.append(stack.pop()) +        if used[st]: +            continue +        stack = [~st, st] +        while stack: +            vn = stack.pop() +            if vn >= 0: +                if used[vn]: +                    continue +                used[vn] = 1 +                for vf in Edge[vn]: +                    if used[vf]: +                        continue +                    stack.append(~vf) +                    stack.append(vf) +            else: +                if used[~vn] != 2: +                    used[~vn] = 2 +                    order.append(~vn) +    """ -    """ -    return res, components, tEdge +    return res, components -R, comp, tE = scc(Edge) +R, comp = scc(Edge)