stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<iostream>

#include<algorithm>

#include<iomanip>

#include<cmath>

#include<vector>

#include<queue>

#include<stack>

#include<set>

#include <cstdio>

#include<map>

#include<string>

#include<assert.h>

#include<unordered_map>

#include <cstring>//memset();

#define Amr_Abdelazim ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

#define pb push_back

#define pp pop_back

#define ll long long

#define ld long double

#define pll pair<ll,ll> 

#define vll vector<ll> 

#define vvll vector<vector<ll> >  

#define vpll vector<pair<ll,ll> > 

#define all(v) v.begin(),v.end()

#define rep(i,n)   for(int i=0;i<n;i++)

#define repp(s,i,n)   for(int i=s;i<n;i++)

#define print(v) for(auto i:v)cout<<i<<" ";cout<<"\n"; 

#define mkp make_pair

#define clr(ar,v) memset(ar,v,sizeof(ar));

#define TC ll t;cin>>t;while(t--)

#define in_vec ll n;cin>>n;vll v(n);rep(i,n)cin >> v[i];

#define EPS 1e-9

using namespace std;

const int mod = 1000000007;

const int N = 1000005;

class cmp{

public:

	bool operator() (pair<ll, pll> &A, pair<ll, pll> &B){

		return A > B;

	}

};

bool by_sec(pll &A, pll &B){

	return A.second < B.second;

}

bool is(pll a, pll b){

	return !((a.first > b.second&&a.second > b.second) || (a.first < b.first&&a.second < b.first));

}

ld dist(pll p1, pll p2){

	return (ld)sqrt((ld)(p1.first - p2.first)*(p1.first - p2.first) + (ld)(p1.second - p2.second)*(p1.second - p2.second));

}

vvll vv(100000+9);

ll dp[100000 + 9];

ll path(ll n){

	if (vv[n].size() == 0)return 0;

	if (dp[n] == -1){

		ll mx = -1;

		rep(i, vv[n].size())mx = max(mx, path(vv[n][i])+1);

		dp[n] = mx;

	}

	return dp[n];

}

int main()

{

	Amr_Abdelazim

		clr(dp, -1);

		ll n, m,ans=0;

	cin >> n >> m;

	while (m--){

		ll a, b;

		cin >> a >> b;

		vv[a].push_back(b);

	}

	repp(1, i, n + 1)

		ans = max(ans, path(i));

	cout << ans << "\n";

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1451995766706058x):
#include <bits/stdc++.h>

using namespace std;

#define ll long long

#define ull unsigned long long

#define PII pair<int,int>

#define PSI pair<string,int>

#define PIII pair< int, pair<int,int> >

const int MaxN = 1e5+5;

vector<int> g[MaxN];

int dp[MaxN];

int N;



int dfs(int node){



    auto &ret = dp[node];

    if(ret!=-1) return ret;

    

    ret = 0;

    for(auto i: g[node])

        ret = max(ret, dfs(i)+1 );



    return ret;

}



void read(){



    int edge;

    memset(dp, -1, sizeof dp);

    cin>>N>>edge;



    for(int i=0; i<edge; i++){

        int u,v;

        cin>>u>>v;

        g[u].push_back(v);

    }

}



void solve(){



    read();

    int res = 0;

    for(int i=1; i<=N; i++)

        res = max(res, dfs(i) );



    cout<< res << "\n";

}





int main(){



    //freopen("input.txt","r",stdin);

    ios_base::sync_with_stdio(false);

    cin.tie(nullptr);

    solve();



    return 0;

}
// Slower C++ solution:
/*

	Author: Luis Manuel D�az Bar�n (LUISMO)

	Problem:

	Online Judge:

	Idea:

*/

#include<bits/stdc++.h>

// Types

#define ll long long

#define ull unsigned long long

// IO

#define sf scanf

#define pf printf

#define mkp make_pair

#define fi first

#define se second

#define endl "\n"



using namespace std;



typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

const ll inf = 1e16 + 3;

const int mod = 1e9 + 7;

const int lim = 2e5 + 2;



int N, M;

vector<int> adj[lim];



int dp[lim];

bool mark[lim];



int DFS(int idx)

{

    if(mark[idx])

        return dp[idx];

    // for each adjacent

    for(int i = 0; i < adj[idx].size(); i++)

    {

        int nxt = adj[idx][i];

        int aux = DFS(nxt);

        dp[idx] = max(dp[idx], 1 + aux);

    }

    mark[idx] = true;

    return dp[idx];

}



void solve()

{

    cin >> N >> M;

    // reading edges

    for (int i = 0; i < M; i++)

    {

        int xi, yi;

        cin >> xi >> yi;

        adj[xi].push_back(yi);

    }

    

    int answ = 0;



    for(int i = 1; i <= N; i++)

    {

        int aux = DFS(i);

        answ = max(answ, aux);

    }



    cout << answ;

}



void fastIO()

{

	cin.sync_with_stdio(false);

	cin.tie(0);

}



void IO()

{

	if(fopen("d:\\lmo.in","r") != NULL)

	{

		freopen("d:\\lmo.in","r",stdin);

	}

	else if(fopen("/media/Beijing/lmo.in","r") != NULL)

	{

		freopen("/media/Beijing/lmo.in", "r", stdin);

	}

}



int main()

{

	IO();



	fastIO();



	solve();

}


// Faster C++ solution for the same problem (measured speedup: 1.843495458680746x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

	int n, m; scanf("%d %d", &n, &m);

	int u, v;

	for(int i = 1; i <= m; i++){

		scanf("%d %d", &u, &v);

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

	printf("%d\n",ans-1);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <climits>

#include <cstring>

#include <vector>

using namespace std;

typedef long long int ll;

const ll inf = 1000000000000;

const ll maxn = 100010;

vector <ll> adj[maxn];

ll dp[maxn];



ll dfs(ll p){

    if(dp[p] != -1) return dp[p];

    ll maxpath = 0;

    for(auto x: adj[p]){

        maxpath = max(maxpath,1+dfs(x));

    }

    return dp[p] = maxpath;

}

int main(){

    memset(dp,-1,sizeof dp);



    ll n,k;



    scanf("%lld %lld",&n,&k);



    for(ll i = 0; i < k; i++){

        ll a,b;

        scanf("%lld %lld",&a,&b);

        adj[a].push_back(b);

    }

    ll ans = -1;

    for(ll i = 1; i <= n; i++){

        ans = max(ans,dfs(i));

    }

    printf("%lld\n",ans);

}


// Faster C++ solution for the same problem (measured speedup: 1.235857554032127x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

	int n, m; scanf("%d %d", &n, &m);

	int u, v;

	for(int i = 1; i <= m; i++){

		scanf("%d %d", &u, &v);

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

	printf("%d\n",ans-1);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <queue>



using namespace std;

struct snod

{

    vector <int> v;

    int len,leg;

} nod[100005];

int n,m,i,x,y,maxi;

queue <int> q;

int main()

{

    cin>>n>>m;

    for(i=1;i<=m;i++)

    {

        cin>>x>>y;

        nod[x].v.push_back(y);

        nod[y].leg++;

    }

    for(i=1;i<=n;i++)

        if(!nod[i].leg)

        {

            q.push(i);

        }



    while(!q.empty())

    {

        int poz=q.front();

        for(int it : nod[poz].v)

        {

            nod[it].len=max(nod[it].len, nod[poz].len+1);

            nod[it].leg--;

            if(!nod[it].leg)

                q.push(it);

        }

        q.pop();

    }

    for(i=1;i<=n;i++)

    {

        maxi=max(maxi, nod[i].len);

    }

    cout<<maxi;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.2328671030558873x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

	int n, m; scanf("%d %d", &n, &m);

	int u, v;

	for(int i = 1; i <= m; i++){

		scanf("%d %d", &u, &v);

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

	printf("%d\n",ans-1);

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

int n , m;

vector<vector<int>>vi(200005);

map<int,int>mp;

int mem[200005];

bool ok[200005];

int dfs(int node){

	if(mem[node])

		return mem[node];

	for(auto it : vi[node]){

		mem[node] = max(dfs(it) + 1 , mem[node]);

	}

	return mem[node];

}

int main() {

	memset(mem,0,sizeof(mem));

	cin>>n>>m;

	for(int i = 0 ; i < m ; i++){

		int x , y ; cin>>x>>y;

		vi[x].push_back(y);

		mp[y]++;

	}

	for(int i  = 1 ; i <= n ; i++){

		if(!mp[i]){

			dfs(i);

		}

	}

	int ans = 0;

	for(int i = 1 ; i <=  n; i++)

		ans = max(ans,mem[i]);

	cout<<ans;

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 2.1190580301698176x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

	int n, m; scanf("%d %d", &n, &m);

	int u, v;

	for(int i = 1; i <= m; i++){

		scanf("%d %d", &u, &v);

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

	printf("%d\n",ans-1);

	return 0;

}
// Slower C++ solution:
/******

author :- Mahmoud Tarek.

*******/



#include<bits/stdc++.h>



using namespace std ;



#define rg register

#define dbg(v) cerr << #v << " " << v ;

typedef long long ll ;



const int N = 1e5 + 5 ;

vector<int> adj[N] ;

int n, m, a, b ;

int dp[N] ;



int solve(int i){



   if(i != 0 && !adj[i].size()){

     return 0 ;

   }



   int & ret = dp[i] ;

   if(~ret) return ret ;

   ret = 0 ;

   if(i == 0){

      for(int j = 1 ; j <= n ; j++)

        ret = max(ret, solve(j)) ;

   }



   for(auto j: adj[i]){

      ret = max(ret, 1 + solve(j)) ;

   }



   return ret ;

}



int main() {

//  freopen("in.txt", "r", stdin) ;



    cin >> n >> m ;

    for(int i = 0 ; i < m ; i++){

        cin >> a >> b ;

        adj[a].push_back(b) ;

    }



    memset(dp, -1, sizeof dp) ;

    cout << solve(0) ;



}





/*

  Empty set of troubles.

*/




// Faster C++ solution for the same problem (measured speedup: 1.1155265740566138x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

	int n, m; scanf("%d %d", &n, &m);

	int u, v;

	for(int i = 1; i <= m; i++){

		scanf("%d %d", &u, &v);

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

	printf("%d\n",ans-1);

	return 0;

}
// Slower C++ solution:
#include<iostream>

#include<algorithm>

#include<iomanip>

#include<cmath>

#include<vector>

#include<queue>

#include<stack>

#include<set>

#include <cstdio>

#include<map>

#include<string>

#include<assert.h>

#include<unordered_map>

#include <cstring>//memset();

#define Amr_Abdelazim ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

#define pb push_back

#define pp pop_back

#define ll long long

#define ld long double

#define pll pair<ll,ll> 

#define vll vector<ll> 

#define vvll vector<vector<ll> >  

#define vpll vector<pair<ll,ll> > 

#define all(v) v.begin(),v.end()

#define rep(i,n)   for(int i=0;i<n;i++)

#define repp(s,i,n)   for(int i=s;i<n;i++)

#define print(v) for(auto i:v)cout<<i<<" ";cout<<"\n"; 

#define mkp make_pair

#define clr(ar,v) memset(ar,v,sizeof(ar));

#define TC ll t;cin>>t;while(t--)

#define in_vec ll n;cin>>n;vll v(n);rep(i,n)cin >> v[i];

#define EPS 1e-9

using namespace std;

const int mod = 1000000007;

const int N = 1000005;

class cmp{

public:

	bool operator() (pair<ll, pll> &A, pair<ll, pll> &B){

		return A > B;

	}

};

bool by_sec(pll &A, pll &B){

	return A.second < B.second;

}

bool is(pll a, pll b){

	return !((a.first > b.second&&a.second > b.second) || (a.first < b.first&&a.second < b.first));

}

ld dist(pll p1, pll p2){

	return (ld)sqrt((ld)(p1.first - p2.first)*(p1.first - p2.first) + (ld)(p1.second - p2.second)*(p1.second - p2.second));

}

vvll vv(100000+9);

ll dp[100000 + 9];

ll path(ll n){

	if (vv[n].size() == 0)return 0;

	if (dp[n] == -1){

		ll mx = -1;

		rep(i, vv[n].size())mx = max(mx, path(vv[n][i])+1);

		dp[n] = mx;

	}

	return dp[n];

}

int main()

{

	Amr_Abdelazim

		clr(dp, -1);

		ll n, m,ans=0;

	cin >> n >> m;

	while (m--){

		ll a, b;

		cin >> a >> b;

		vv[a].push_back(b);

	}

	repp(1, i, n + 1)

		ans = max(ans, path(i));

	cout << ans << "\n";

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.2864556411707249x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

	int n, m; scanf("%d %d", &n, &m);

	int u, v;

	for(int i = 1; i <= m; i++){

		scanf("%d %d", &u, &v);

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

	printf("%d\n",ans-1);

	return 0;

}
// Slower C++ solution:


#include <bits/stdc++.h>

#define inf INFINITY

#define file freopen( "input.txt" , "r" , stdin) ; freopen( "output.txt" , "w" , stdout) ;

#define Gamed ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

#define _3102_ main()

#define endl '\n'

typedef long long ll;

typedef unsigned long long ull;

typedef long double ld;

using namespace std;

const int N = 1e5 + 100;

const ll MX = 1e18;

const ll mod = 1e9 + 7;

const double eps = 1e-9 ;

int n , m , dp[N] ;

vector < int > adj[N] ; 



int solve( int node ){

    //cout << node << endl ; 

    if ( dp[node] != -1 ) return dp[node] ;

    int maxi = 0 ; 

    for ( auto j : adj[node]){

        maxi = max ( maxi , solve(j) + 1 ) ;

    }

    return dp[node] = maxi ; 

} 



int _3102_{

	Gamed

    cin >> n >> m ; 

    for ( int i = 0 ; i < m ; i ++){

        int u , v ; 

        cin >> u >> v ;

        adj[v].push_back(u) ; 

    }

    //for ( int i = 1 ; i <= n ; i ++){

    //    cout << i << ": " ; 

    //    for ( auto j : adj[i] ){

    //        cout << j << " " ;

    //    }

    //    cout << endl ; 

    //}

    memset ( dp , -1 , sizeof dp ) ;

 

    for ( int i = 1 ; i <= n ; i ++){

        if ( dp[i] == -1 ){

            //cout << "--" << i << "--" << endl  ;

            solve (i) ;

            //cout << "------\n";

            //for ( int j = 1 ; j <= n ; j ++ ) cout << dp[j] << " " ;

            //cout << "\n------\n" ;  

        }  

    }

    int ans= 0 ; 

    for ( int i = 1 ; i <= n ; i ++ ){

        ans = max ( ans , dp[i]) ;

    }

    cout << ans << endl ; 

    return 0;

}




// Faster C++ solution for the same problem (measured speedup: 1.1225726598156498x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

	int n, m; scanf("%d %d", &n, &m);

	int u, v;

	for(int i = 1; i <= m; i++){

		scanf("%d %d", &u, &v);

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

	printf("%d\n",ans-1);

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define ll long long

#define ull unsigned long long

#define PII pair<int,int>

#define PSI pair<string,int>

#define PIII pair< int, pair<int,int> >

const int MaxN = 1e5+5;

vector<int> g[MaxN];

int dp[MaxN];

int N;



int dfs(int node){



    auto &ret = dp[node];

    if(ret!=-1) return ret;

    

    ret = 0;

    for(auto i: g[node])

        ret = max(ret, dfs(i)+1 );



    return ret;

}



void read(){



    int edge;

    memset(dp, -1, sizeof dp);

    cin>>N>>edge;



    for(int i=0; i<edge; i++){

        int u,v;

        cin>>u>>v;

        g[u].push_back(v);

    }

}



void solve(){



    read();

    int res = 0;

    for(int i=1; i<=N; i++)

        res = max(res, dfs(i) );



    cout<< res << "\n";

}





int main(){



    //freopen("input.txt","r",stdin);

    ios_base::sync_with_stdio(false);

    cin.tie(nullptr);

    solve();



    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.1233462423299065x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

	int n, m; scanf("%d %d", &n, &m);

	int u, v;

	for(int i = 1; i <= m; i++){

		scanf("%d %d", &u, &v);

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

	printf("%d\n",ans-1);

	return 0;

}
// Slower C++ solution:
/*

	Author: Luis Manuel D�az Bar�n (LUISMO)

	Problem:

	Online Judge:

	Idea:

*/

#include<bits/stdc++.h>

// Types

#define ll long long

#define ull unsigned long long

// IO

#define sf scanf

#define pf printf

#define mkp make_pair

#define fi first

#define se second

#define endl "\n"



using namespace std;



typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

const ll inf = 1e16 + 3;

const int mod = 1e9 + 7;

const int lim = 2e5 + 2;



int N, M;

vector<int> adj[lim];



int dp[lim];

bool mark[lim];



int DFS(int idx)

{

    if(mark[idx])

        return dp[idx];

    // for each adjacent

    for(int i = 0; i < adj[idx].size(); i++)

    {

        int nxt = adj[idx][i];

        int aux = DFS(nxt);

        dp[idx] = max(dp[idx], 1 + aux);

    }

    mark[idx] = true;

    return dp[idx];

}



void solve()

{

    cin >> N >> M;

    // reading edges

    for (int i = 0; i < M; i++)

    {

        int xi, yi;

        cin >> xi >> yi;

        adj[xi].push_back(yi);

    }

    

    int answ = 0;



    for(int i = 1; i <= N; i++)

    {

        int aux = DFS(i);

        answ = max(answ, aux);

    }



    cout << answ;

}



void fastIO()

{

	cin.sync_with_stdio(false);

	cin.tie(0);

}



void IO()

{

	if(fopen("d:\\lmo.in","r") != NULL)

	{

		freopen("d:\\lmo.in","r",stdin);

	}

	else if(fopen("/media/Beijing/lmo.in","r") != NULL)

	{

		freopen("/media/Beijing/lmo.in", "r", stdin);

	}

}



int main()

{

	IO();



	fastIO();



	solve();

}


// Faster C++ solution for the same problem (measured speedup: 1.843795020725641x):
#include <iostream>

#include <queue>

#include <vector>

#include <cstring>

#include <algorithm>

using namespace std;



const int maxn=1e5+10;

int dp[maxn],in[maxn];

vector<int > G[maxn];

int main()

{

    queue<int> q;

    int n,m,a,b,ans = 0;

	scanf("%d%d",&n,&m);

    for(int i = 1;i<=m;++i)

		scanf("%d%d",&a,&b),in[b]++,G[a].push_back(b);

    for(int i = 1;i<=n;++i)

		if(!in[i]) q.push(i);

    while(!q.empty())

    {

        int now = q.front();

        q.pop();

        int sz = G[now].size();

        for(int i = 0;i<sz;++i)

        {

            dp[G[now][i]] = max(dp[G[now][i]],dp[now]+1);

            in[G[now][i]]--;

            if(in[G[now][i]]==0) q.push(G[now][i]);

        }

    }

    for(int i=1;i<=n;++i)

		ans = max(ans,dp[i]);

    printf("%d\n",ans);

    return 0;

}