Problem:
Score : 100 points

Problem Statement

There is a directed graph G with N vertices and M edges.
The vertices are numbered 1, 2, \ldots, N, and for each i (1 \leq i \leq M), the i-th directed edge goes from Vertex x_i to y_i.
G does not contain directed cycles.

Find the length of the longest directed path in G.
Here, the length of a directed path is the number of edges in it.

Constraints

All values in input are integers.

2 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq x_i, y_i \leq N

All pairs (x_i, y_i) are distinct.

G does not contain directed cycles.

Input

Input is given from Standard Input in the following format:

N M
x_1 y_1
x_2 y_2
:
x_M y_M

Output

Print the length of the longest directed path in G.

Sample Input 1

4 5
1 2
1 3
3 2
2 4
3 4

Sample Output 1

3

The red directed path in the following figure is the longest:

Sample Input 2

6 3
2 3
4 5
5 6

Sample Output 2

2

The red directed path in the following figure is the longest:

Sample Input 3

5 8
5 3
2 3
2 4
5 2
5 1
1 4
4 3
1 3

Sample Output 3

3

The red directed path in the following figure is one of the longest:

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;

public class S
{

    private const long DP_INIT_MINUS1 = -1;

    private static long[] dp;
    private static List<long>[] paths;


    public static void Main()
	{
		/*
        var input = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
        var N = input[0];
        var M = input[1];
        */
        var input = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
        var N = input[0];
        var M = input[1];

        solver(N,M);
    }

    public static void solver(long nodeCount, long pathCount){

        /*
            dp[nodeCount]


            // メモか再帰らしい
        
         */

        dp = new long[nodeCount+1];
        paths = new List<long>[nodeCount+1];

        long[] input;

        for(int i = 0; i <= nodeCount; i++){
            dp[i] = DP_INIT_MINUS1;
            paths[i] = new List<long>();
        }

        for(int i = 0; i < pathCount; i++){
            input = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
            paths[input[0]].Add(input[1]);
        }

        for(int i = 0; i < nodeCount; i++){
            explore(i+1);
        }

        


        Console.WriteLine(dp.Max());
		/*
		foreach(var tgt in dp){
			Console.WriteLine(tgt);	
		}
		*/


    }

    private static long explore(long from){

        if(dp[from] != DP_INIT_MINUS1){
            return dp[from];
        }

        if(paths[from].Count == 0){
            dp[from] = 0;
            return 0;  // 閉路を含まないなら必ずいきどまりがある。
        }

        dp[from] = paths[from].Select(x => explore(x)).Max() + 1;
        return dp[from];

    }

}