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++14 (GCC 5.4.1) (judge verdict: Accepted)

/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define pll pair<ll , ll >
#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back

using namespace std;
const int maxn = 1000*100+5 ;
const ll inf = 9223372036854775807 ;

int  mark[maxn] , n , m , h[maxn] , ans , outd[maxn] , dp[maxn]; 
vec<int> adj[maxn] , sink[maxn]; 
void dfs(int root)
{
	mark[root] = 1 ; 
	for(auto u : adj[root])
	{
		if(mark[u] == 0)
		{
			h[u] = h[root] + 1 ; 
			dfs(u) ; 
		}
	}
}

int pd(int v)
{
//	cout<<v<<" " ;
	if(dp[v] == -1)
	{
		for(auto u : adj[v])
		{
			if(pd(u) + 1 > dp[v])
			{
			//	cout<<" dp u was bigger "<< u << " dp u = "<<pd(u) << endl ; 
				dp[v] = pd(u) + 1 ;
			//	cout<<"dp "<< v<< " become  "<< dp[v] << endl ; 
			}
		}
	}
	//	cout<<endl<<v << " dp = "<<dp[v] << endl ; 	
	return dp[v] ;
 
}
int main()
{
	migmig ;
	cin>>n>>m ; 
	for(int i = 1 ; i <= m ; i ++ )
	{
		int u , v ; 
		cin>>u>>v; 
		adj[u].pb(v)  ;
		outd[u] ++ ; 
	}
	for(int i = 1 ; i <= n ; i ++ )
	{
		dp[i] = -1 ; 
		if(outd[i] == 0) 
		{
		//	cout<<i<<" - > sink" << endl ; 
			dp[i] = 0 ; 
		}
	}
	
	for(int i = 1 ; i <= n ; i ++ )
	{
		ans = max(ans , pd(i)) ;
	//	cout<<"dp["<<i << "] = "<< dp[i] << endl ;  
	}
	//pd(1) ; 
	cout<<ans ; 
	
}
//////
////////
///////////