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.2897481990742128x):
#include<bits/stdc++.h>

using namespace::std;



const int N = 100000 + 5;



int n;

int m;

bool vis[N];

int memo[N];

vector<int> G[N];



int DP(int u){

	if(vis[u]) return memo[u];

	int ans = 0;

	for(int v : G[u]){

		ans = max(ans, 1 + DP(v));

	}

	vis[u] = true;

	return memo[u] = ans;

}



int main(){

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

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

		int u, v;

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

		G[u].emplace_back(v);

	}

	int ans = 0;

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

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

	}

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

	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.1254457751917477x):
#include<bits/stdc++.h>

using namespace::std;



const int N = 100000 + 5;



int n;

int m;

bool vis[N];

int memo[N];

vector<int> G[N];



int DP(int u){

	if(vis[u]) return memo[u];

	int ans = 0;

	for(int v : G[u]){

		ans = max(ans, 1 + DP(v));

	}

	vis[u] = true;

	return memo[u] = ans;

}



int main(){

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

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

		int u, v;

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

		G[u].emplace_back(v);

	}

	int ans = 0;

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

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

	}

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

	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.1262213376150974x):
#include<bits/stdc++.h>

using namespace::std;



const int N = 100000 + 5;



int n;

int m;

bool vis[N];

int memo[N];

vector<int> G[N];



int DP(int u){

	if(vis[u]) return memo[u];

	int ans = 0;

	for(int v : G[u]){

		ans = max(ans, 1 + DP(v));

	}

	vis[u] = true;

	return memo[u] = ans;

}



int main(){

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

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

		int u, v;

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

		G[u].emplace_back(v);

	}

	int ans = 0;

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

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

	}

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

	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.5241857943631392x):
#include <bits/stdc++.h>

#define N 100007

using namespace std;

vector <int> adj[N];

int mem[N];

int dp(int i)

{

    if(mem[i] != -1)

        return mem[i];

    int ans = 0;

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

    {

        int k = dp(adj[i][j]);

        ans = max(ans, k);

    }

    ans += 1;

    mem[i] = ans;

    return ans;

}

int main()

{

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

    //freopen("output.txt", "w", stdout);

    int n, m;

    cin >> n >> m;

    memset(mem, -1, sizeof(mem));

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

    {

        int a, b;

        cin >> a >> b;

        adj[a].push_back(b);

    }

    int mx = 0;

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

    {

        int k = dp(i);

        if(k > mx)

            mx = k;

    }

    cout << mx-1 << endl;

    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: 1.7520184993172316x):
#include <bits/stdc++.h>

#define N 100007

using namespace std;

vector <int> adj[N];

int mem[N];

int dp(int i)

{

    if(mem[i] != -1)

        return mem[i];

    int ans = 0;

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

    {

        int k = dp(adj[i][j]);

        ans = max(ans, k);

    }

    ans += 1;

    mem[i] = ans;

    return ans;

}

int main()

{

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

    //freopen("output.txt", "w", stdout);

    int n, m;

    cin >> n >> m;

    memset(mem, -1, sizeof(mem));

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

    {

        int a, b;

        cin >> a >> b;

        adj[a].push_back(b);

    }

    int mx = 0;

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

    {

        int k = dp(i);

        if(k > mx)

            mx = k;

    }

    cout << mx-1 << endl;

    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.5999627449348506x):
#include <bits/stdc++.h>



#define Fast cin.tie(0), ios::sync_with_stdio(0)

#define All(x) x.begin(), x.end()

#define louisfghbvc int t; cin >> t; while(t--)

#define sz(x) (int)(x).size()

using namespace std;

typedef long long LL;

typedef pair<LL, LL> ii;

typedef vector<LL> vi;



template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep = ""; for(const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }

template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }



void dbg_out() { cerr << "\n"; }

template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }



const int N = 1e5+5;

vector<int> g[N];

bool vis[N];

int dp[N];



void dfs(int u){

    for(int v: g[u]){

        if(!vis[v]){

            vis[v] = 1;

            dfs(v);

        }

        dp[u] = max(dp[u], dp[v]+1);

    }

}



void solve(){

    int n, m;

    cin >> n >> m;

    for(int i = 1; i <= n; ++i) g[i].clear();

    memset(dp, 0, sizeof dp);

    memset(vis, 0, sizeof vis);



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

        int a, b;

        cin >> a >> b;

        g[a].push_back(b);

    }



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

        if(!vis[i]){

            vis[i] = 1;

            dfs(i);

        }

    }



    cout << *max_element(dp+1, dp+n+1) << "\n";

}



int main()

{

    Fast;

    //louisfghbvc{

        solve();

    //}

    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: 1.8391224598150129x):
#include <bits/stdc++.h>



#define Fast cin.tie(0), ios::sync_with_stdio(0)

#define All(x) x.begin(), x.end()

#define louisfghbvc int t; cin >> t; while(t--)

#define sz(x) (int)(x).size()

using namespace std;

typedef long long LL;

typedef pair<LL, LL> ii;

typedef vector<LL> vi;



template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep = ""; for(const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }

template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }



void dbg_out() { cerr << "\n"; }

template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }



const int N = 1e5+5;

vector<int> g[N];

bool vis[N];

int dp[N];



void dfs(int u){

    for(int v: g[u]){

        if(!vis[v]){

            vis[v] = 1;

            dfs(v);

        }

        dp[u] = max(dp[u], dp[v]+1);

    }

}



void solve(){

    int n, m;

    cin >> n >> m;

    for(int i = 1; i <= n; ++i) g[i].clear();

    memset(dp, 0, sizeof dp);

    memset(vis, 0, sizeof vis);



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

        int a, b;

        cin >> a >> b;

        g[a].push_back(b);

    }



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

        if(!vis[i]){

            vis[i] = 1;

            dfs(i);

        }

    }



    cout << *max_element(dp+1, dp+n+1) << "\n";

}



int main()

{

    Fast;

    //louisfghbvc{

        solve();

    //}

    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: 1.1497457483495819x):
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

using ii = pair<int,int>;



const int mx = 2e5+5;



int dist[mx];

int n, m, vis[mx];

vector<int> g[mx], tp;



void dfs(int u){

    vis[u] = 1;

    for(int v : g[u])

        if(!vis[v])

            dfs(v);

    tp.push_back(u);

}



int main(){

    cin.tie(nullptr);

    ios_base::sync_with_stdio(0);



    cin >> n >> m;

    while(m--){

        int u, v; cin >> u >> v;

        g[u].push_back(v);

    }



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

        dist[i] = 1;

        if(!vis[i]) dfs(i);

    }



    reverse(tp.begin(), tp.end());

    for(int u : tp)

        for(int v : g[u])

            dist[v] = max(dist[v], 1+dist[u]);

    cout << *max_element(dist, dist+n+1)-1 << "\n";



    return 0;

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

بسم الله الرحمن الرحيم

اللهم ما صلّ على سيدنا محمد

اذكر الله

واتقوا يوما ترجعون فيه إلى الله ثم توفى كل نفس ما كسبت وهم لا يظلمون

****/



#include <bits/stdc++.h>

#define ll long long

#define endl "\n"

#define shalaby ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);cerr.tie(0);



using namespace std;



inline int D()

{

    int t;

    scanf("%d",&t);

    return t;

}

inline ll llD()

{

    ll t;

    scanf("%lld",&t);

    return t;

}



const ll OO=-1e18;

int xt[4]= {1,0,0,-1};

int yt[4]= {0,1,-1,0};

////////////////////////////////////////////////////////////////////////////////////

const int N = 1e6+1;

int mem[200005],n,m,mod=1e9+7,cnt;

bool valid(int x,int y)

{

    return x>-1 && y>-1 && x<n && y<m;

}

void init()

{

    memset(mem,-1,sizeof mem);

}

bool visited[200005];

vector <int> adj[200005];

int dfs(int s)

{

    int &ret=mem[s];

    if(~ret)return ret;

       ret=0;

      /// visited[s] = true;



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

    {

        if(visited[adj[s][i]] == false)

        {

            ret= max(ret, dfs(adj[s][i])+1);

        }

    }

    return ret;

}

int main()

{

    init();

    int x,y;

    cin >> n;

    cin >> m;

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

    {

        cin >> x >> y;

        adj[x].push_back(y);

    }

    int mx=0,mn=2000006;

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

    {

            cnt= dfs(i);

            mx=max(cnt,mx);

        }



    cout<<mx;

}






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

using namespace std;

using ll = long long;

using ii = pair<int,int>;



const int mx = 2e5+5;



int dist[mx];

int n, m, vis[mx];

vector<int> g[mx], tp;



void dfs(int u){

    vis[u] = 1;

    for(int v : g[u])

        if(!vis[v])

            dfs(v);

    tp.push_back(u);

}



int main(){

    cin.tie(nullptr);

    ios_base::sync_with_stdio(0);



    cin >> n >> m;

    while(m--){

        int u, v; cin >> u >> v;

        g[u].push_back(v);

    }



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

        dist[i] = 1;

        if(!vis[i]) dfs(i);

    }



    reverse(tp.begin(), tp.end());

    for(int u : tp)

        for(int v : g[u])

            dist[v] = max(dist[v], 1+dist[u]);

    cout << *max_element(dist, dist+n+1)-1 << "\n";



    return 0;

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

using namespace std;

constexpr int MAXN = 1e5 + 7;



vector<int> from[MAXN];

int dp[MAXN];

int ans;



void dfs(int u)

{

    if (dp[u])

        return;

    for (int v : from[u]) {

        dfs(v);

        dp[u] = max(dp[u], 1 + dp[v]);

    }

    if (dp[u] > ans)

        ans = dp[u];

}



int main()

{

    int n, m;

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

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

        int u, v;

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

        from[u].push_back(v);

    }

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

        if (!dp[i])

            dfs(i);

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

}

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

using namespace std;

constexpr int MAXN = 1e5 + 7;

constexpr int MAXM = 1e5 + 7;



int u[MAXN], nxt[MAXM], v[MAXM];

int dp[MAXN];



int dfs(int x)

{

    if (!dp[x])

        for (int i = u[x]; i; i = nxt[i])

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

    return dp[x];

}



int main()

{

    int n, m;

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

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

        int a, b;

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

        nxt[i] = u[a], v[i] = b;

        u[a] = i;

    }

    int ans = 0;

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

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

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

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

#include<map>

#include<vector>

#include<math.h>

#define ll long long

using namespace std;



int dp[100001];

void fillarray()

{

	int i;

	for(i=0;i<=100000;i++)

	dp[i] = -1;

}



int dfs(vector<int> g[] , int i)

{

	if(dp[i] >= 0)

	return dp[i];

	

	//cout<<"Current vertex = "<<i<<endl;

	if(g[i].size() == 0)

	{

		dp[i] = 0;

		return 0;

	}

	

	int size = g[i].size();

	int j,k,len,maxm = 0;

	for(j=0;j<size;j++)

	{

		

		k = g[i][j];

		//cout<<"Child = "<<k<<endl;

		len = 1 + dfs(g , k);

		maxm = max(len , maxm);

	}

	

	dp[i] = maxm;

	return maxm;

	

}





main()

{

	int n,m;

	cin>>n>>m;

	int i,j;

	

	vector<int> g[n+1];

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

	{

		int u,v;

		cin>>u>>v;

		g[u].push_back(v);

	}

	

	fillarray();

	

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

	{

		if(g[i].size() > 0)

		dfs(g , i);

	}

	

	int maxm = 0;

	int index;

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

	{

		//cout<<"node = "<<i<<" :: "<<dp[i]<<endl;

		if(maxm < dp[i])

		{

			maxm = dp[i];

			index = i;

		}

	}

	//cout<<endl<<maxm<<"is maximum d : node = "<<index;

	cout<<maxm;

	

	

}

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

#include<vector>

#include<map>

#include<algorithm>

#include<math.h>



#define ll long long

using namespace std;



int dfs(vector<int> g[] , bool visited[] , int maxd[] , int i)

{

	if(visited[i])

	{

		return maxd[i];

	}

	//cout<<"visited : "<<i<<endl;

	

	visited[i] = true;

	int j,k;

	int size = g[i].size();

	int h = -1;

	for(j=0;j<size;j++)

	{

		k = g[i][j];

		h = max(h , dfs(g , visited , maxd , k));	

	}

	

	maxd[i] = 1 + h;

	//cout<<"maxd for i = "<<i<<" is "<<maxd[i]<<endl;

	return maxd[i];

}



main()

{

	int n,m;

	cin>>n>>m;

	int i,j;

	

	vector<int> g[n+1];

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

	{

		int u,v;

		cin>>u>>v;

		

		g[u].push_back(v);	

	}	

	

	bool visited[n+1] = {0};

	int maxd[n+1] = {0};

	int maxm = 0;

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

	{

		if(!visited[i])

		maxm = max(maxm , dfs(g , visited , maxd , i));

	}

	

	cout<<maxm;

}