import sys

sys.setrecursionlimit(2*10**5)





def dfs(v, graph, memo):

    if memo[v] != -1:

        return memo[v]

    ret = 0

    for c in graph[v]:

        ret = max(ret, dfs(c, graph, memo) + 1)

    memo[v] = ret

    return ret





def main():

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

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

    for _ in range(M):

        x, y = list(map(int, input().split()))

        x, y = x - 1, y - 1

        graph[x].append(y)

    memo = [-1] * N

    ans = 0

    for i in range(N):

        ans = max(ans, dfs(i, graph, memo))

    print(ans)





if __name__ == '__main__':

    main()

import numpy as np

from scipy.sparse import csr_matrix

from scipy.sparse.csgraph import connected_components





def create_graph(V: int, edges: np.array, dtype=None):

    """csr_matrix を作成する



    もし精度が足りない場合は dtype=object にする。

    """

    return csr_matrix((edges[:, 2], (edges[:, 0], edges[:, 1])),

                      shape=(V, V), dtype=dtype)





def main() -> None:

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

    edges = []

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

    for _ in range(M):

        x, y = list(map(int, input().split()))

        edges.append([x-1, y-1, 1])

        adj_list[x-1].append(y-1)

    graph = create_graph(N, np.asarray(edges))

    _, labels = connected_components(

        csgraph=graph, directed=True,

        connection="strong", return_labels=True)

    order = [(x, i) for i, x in enumerate(labels)]

    order.sort(reverse=True)

    dp = [0] * N

    for _, i in order:

        for v in adj_list[i]:

            dp[v] = max(dp[v], dp[i] + 1)

    print((max(dp)))





if __name__ == '__main__':

    main()

import sys

sys.setrecursionlimit(2 * 10**5)


def dfs(v, graph, memo):
    if memo[v] != -1:
        return memo[v]
    ret = 0
    for c in graph[v]:
        ret = max(ret, dfs(c, graph, memo) + 1)
    memo[v] = ret
    return ret


def main():
    N, M = list(map(int, input().split()))
    graph = [[] for _ in range(N)]
    for _ in range(M):
        x, y = list(map(int, input().split()))
        x, y = x - 1, y - 1
        graph[x].append(y)
    memo = [-1] * N
    ans = 0
    for i in range(N):
        ans = max(ans, dfs(i, graph, memo))
    print(ans)


if __name__ == "__main__":
    main()

import numpy as np
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import connected_components


def create_graph(V: int, edges: np.array, dtype=None):
    """csr_matrix を作成する
    もし精度が足りない場合は dtype=object にする。
    """
    return csr_matrix(
        (edges[:, 2], (edges[:, 0], edges[:, 1])), shape=(V, V), dtype=dtype
    )


def main() -> None:
    N, M = list(map(int, input().split()))
    edges = []
    adj_list = [[] for _ in range(N)]
    for _ in range(M):
        x, y = list(map(int, input().split()))
        edges.append([x - 1, y - 1, 1])
        adj_list[x - 1].append(y - 1)
    graph = create_graph(N, np.asarray(edges))
    _, labels = connected_components(
        csgraph=graph, directed=True, connection="strong", return_labels=True
    )
    order = [(x, i) for i, x in enumerate(labels)]
    order.sort(reverse=True)
    dp = [0] * N
    for _, i in order:
        for v in adj_list[i]:
            dp[v] = max(dp[v], dp[i] + 1)
    print((max(dp)))


if __name__ == "__main__":
    main()

-import sys - -sys.setrecursionlimit(2 * 10**5) +import numpy as np +from scipy.sparse import csr_matrix +from scipy.sparse.csgraph import connected_components -def dfs(v, graph, memo): -    if memo[v] != -1: -        return memo[v] -    ret = 0 -    for c in graph[v]: -        ret = max(ret, dfs(c, graph, memo) + 1) -    memo[v] = ret -    return ret +def create_graph(V: int, edges: np.array, dtype=None): +    """csr_matrix を作成する +    もし精度が足りない場合は dtype=object にする。 +    """ +    return csr_matrix( +        (edges[:, 2], (edges[:, 0], edges[:, 1])), shape=(V, V), dtype=dtype +    ) -def main(): +def main() -> None: -    graph = [[] for _ in range(N)] +    edges = [] +    adj_list = [[] for _ in range(N)] -        x, y = x - 1, y - 1 -        graph[x].append(y) -    memo = [-1] * N -    ans = 0 -    for i in range(N): -        ans = max(ans, dfs(i, graph, memo)) -    print(ans) +        edges.append([x - 1, y - 1, 1]) +        adj_list[x - 1].append(y - 1) +    graph = create_graph(N, np.asarray(edges)) +    _, labels = connected_components( +        csgraph=graph, directed=True, connection="strong", return_labels=True +    ) +    order = [(x, i) for i, x in enumerate(labels)] +    order.sort(reverse=True) +    dp = [0] * N +    for _, i in order: +        for v in adj_list[i]: +            dp[v] = max(dp[v], dp[i] + 1) +    print((max(dp)))