stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#define ll long long int

#define Mx 100005

using namespace std;

ll n,m;

vector<ll>graph[Mx];

bool vis[Mx];

ll dp[Mx];

void input()

{



    cin>>n>>m;

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

    {

        ll x,y;

        cin>>x>>y;

        graph[x].push_back(y);

    }





}

void DFS(ll src)

{

    ll c=1;

    vis[src]=true;

    for(ll i=0; i<graph[src].size(); i++)

    {

        if(!vis[graph[src][i]])

        {

            DFS(graph[src][i]);

        }

        dp[src]=max(dp[src],c+dp[graph[src][i]]);

    }

}





int main()

{

    input();

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

    {

        if(!vis[i])

        {

            DFS(i);

        }

    }

    ll mx=0;

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

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

    }

    cout<<mx<<endl;





}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define ll          long long int

#define ld          long double

#define pb          push_back

#define mp          make_pair

#define ff          first

#define se          second

#define scan(n)     scanf("%lld", &n);

#define print(n)    printf("%lld\n", n);

#define fd(n)       fixed<<setprecision(n)

#define MAX         1000000000000000000

#define MAXN        100005

#define LOG         19

#define mod         1000000007

using namespace std;





int main(){

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    ll n,m,i,x,y,mx=0;

    cin>>n>>m;

    vector<ll> vi[n+1];

    ll deg[n+1];

    queue<ll> qe;

    vector<ll> vi1;

    memset(deg,0,sizeof(deg));

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

        cin>>x>>y;

        vi[x].pb(y);

        deg[y]++;

    }

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

        if(deg[i]==0){

            qe.push(i);

            vi1.pb(i);

        }

    }

    while(!qe.empty()){

        ll node=qe.front();

        qe.pop();

        for(auto x:vi[node]){

            deg[x]--;

            if(deg[x]==0){

                vi1.pb(x);

                qe.push(x);

            }

        }

    }

    ll dp[n+1];

    memset(dp,0,sizeof(dp));

    for(auto node:vi1){

        for(auto x:vi[node]){

            dp[x]=max(dp[x],dp[node]+1);

        }

    }

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

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

    }

    cout<<mx;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

 

#define f(i,a,b) for( ll i = a; i < b ; i++ )

#define af(i,a,b) for( ll i = a; i >= b ; i--)

#define rep(i,a,b,k) for(ll i = a; i < b ; i+= k )

#define arep(i,a,b,k) for( ll i = a; i >= b ; i-= k)

#define ones(x) (ll) __builtin_popcount(x)

#define fs first

#define sc second

#define pb push_back

#define po pop_back

#define mp make_pair  

#define sz(a) (ll) a.size()

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

#define sor(a) sort( a.begin(), a.end() )

#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL)

#define ller ios::sync_with_stdio(false);cin.tsie(nullptr);cout.tie(nullptr)

#define watch(x) cout << (#x) << " is #" << (x) <<"#" <<endl

#define PI 3.1415926535

using namespace std;

typedef long long ll;

typedef long double ld; 

typedef pair<ll,ll> ii ;

typedef vector<ll>  vi ;

typedef vector<ii> vii ;

const ll mod = 1e9+7;

const ll MAX = 1e5+5;

const ll inf = 1e18+7;



ll dp[MAX];

bool visited[MAX];

vi adj[MAX];



ll DP(ll u)

{

  ll &ans = dp[u];

  if(ans) return ans;

  for(auto v : adj[u]) ans = max(ans,DP(v)+1);

  return ans;

}



int main() {

  fastio;

  ll n,m,x,y;

  cin>>n>>m;

  while(m--) 

  {

     cin>>x>>y;

     visited[y]=true;

     adj[x].pb(y);

  }

  ll ans=0;

  f(i,1,n+1){

    if(!visited[i]) ans = max(ans,DP(i));

  }

  cout<<ans<<"\n";

  return 0; 

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define ll          long long int

#define ld          long double

#define pb          push_back

#define mp          make_pair

#define ff          first

#define se          second

#define scan(n)     scanf("%lld", &n);

#define print(n)    printf("%lld\n", n);

#define fd(n)       fixed<<setprecision(n)

#define MAX         1000000000000000000

#define MAXN        100005

#define LOG         19

#define mod         1000000007

using namespace std;





int main(){

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    ll n,m,i,x,y,mx=0;

    cin>>n>>m;

    vector<ll> vi[n+1];

    ll deg[n+1];

    queue<ll> qe;

    vector<ll> vi1;

    memset(deg,0,sizeof(deg));

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

        cin>>x>>y;

        vi[x].pb(y);

        deg[y]++;

    }

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

        if(deg[i]==0){

            qe.push(i);

            vi1.pb(i);

        }

    }

    while(!qe.empty()){

        ll node=qe.front();

        qe.pop();

        for(auto x:vi[node]){

            deg[x]--;

            if(deg[x]==0){

                vi1.pb(x);

                qe.push(x);

            }

        }

    }

    ll dp[n+1];

    memset(dp,0,sizeof(dp));

    for(auto node:vi1){

        for(auto x:vi[node]){

            dp[x]=max(dp[x],dp[node]+1);

        }

    }

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

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

    }

    cout<<mx;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

const int N=1e5+10;

int memo[N];

bool vis[N];

vector<int> g[N];



int dp(int u){

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

	int ans=0;

	for(auto v: g[u]){

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

	}

	vis[u]=true;

	return memo[u]=ans;

}



int main() {

    int n,m;

	cin>>n>>m;

	int a,b;

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

		cin>>a>>b;

		g[a].push_back(b);

	}

	int res=0;

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

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

	}

	cout<<res<<"\n";

	return 0;

}




// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define ll          long long int

#define ld          long double

#define pb          push_back

#define mp          make_pair

#define ff          first

#define se          second

#define scan(n)     scanf("%lld", &n);

#define print(n)    printf("%lld\n", n);

#define fd(n)       fixed<<setprecision(n)

#define MAX         1000000000000000000

#define MAXN        100005

#define LOG         19

#define mod         1000000007

using namespace std;





int main(){

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    ll n,m,i,x,y,mx=0;

    cin>>n>>m;

    vector<ll> vi[n+1];

    ll deg[n+1];

    queue<ll> qe;

    vector<ll> vi1;

    memset(deg,0,sizeof(deg));

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

        cin>>x>>y;

        vi[x].pb(y);

        deg[y]++;

    }

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

        if(deg[i]==0){

            qe.push(i);

            vi1.pb(i);

        }

    }

    while(!qe.empty()){

        ll node=qe.front();

        qe.pop();

        for(auto x:vi[node]){

            deg[x]--;

            if(deg[x]==0){

                vi1.pb(x);

                qe.push(x);

            }

        }

    }

    ll dp[n+1];

    memset(dp,0,sizeof(dp));

    for(auto node:vi1){

        for(auto x:vi[node]){

            dp[x]=max(dp[x],dp[node]+1);

        }

    }

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

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

    }

    cout<<mx;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#define PI acos(-1)

#define falcon ios_base::sync_with_stdio(false) ; cin.tie(NULL) ;

typedef long long ll ;

using namespace std ;



vector <int> g[100001] , d(100001 , -1) ;

int maxlength = INT_MIN ;



void DFS(int s)

{

    d[s] = 0 ;

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

    {

        int n = g[s][i] , length = 0 ;

        if(d[n] == -1) DFS(n) ;

        length = 1 + d[n] ;

        d[s] = max(d[s] , length) ;

    }

    maxlength = max(maxlength , d[s]) ;

}



int main()

{

    falcon ;



    int n , m ;

    cin >> n >> m ;

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

    {

        int u , v ;

        cin >> u >> v ;

        g[u].push_back(v) ;

    }

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

    cout << maxlength << "\n" ;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define ll          long long int

#define ld          long double

#define pb          push_back

#define mp          make_pair

#define ff          first

#define se          second

#define scan(n)     scanf("%lld", &n);

#define print(n)    printf("%lld\n", n);

#define fd(n)       fixed<<setprecision(n)

#define MAX         1000000000000000000

#define MAXN        100005

#define LOG         19

#define mod         1000000007

using namespace std;





int main(){

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    ll n,m,i,x,y,mx=0;

    cin>>n>>m;

    vector<ll> vi[n+1];

    ll deg[n+1];

    queue<ll> qe;

    vector<ll> vi1;

    memset(deg,0,sizeof(deg));

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

        cin>>x>>y;

        vi[x].pb(y);

        deg[y]++;

    }

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

        if(deg[i]==0){

            qe.push(i);

            vi1.pb(i);

        }

    }

    while(!qe.empty()){

        ll node=qe.front();

        qe.pop();

        for(auto x:vi[node]){

            deg[x]--;

            if(deg[x]==0){

                vi1.pb(x);

                qe.push(x);

            }

        }

    }

    ll dp[n+1];

    memset(dp,0,sizeof(dp));

    for(auto node:vi1){

        for(auto x:vi[node]){

            dp[x]=max(dp[x],dp[node]+1);

        }

    }

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

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

    }

    cout<<mx;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll bg=pow(10,9)+7;

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

#define gg1(n1) cin>>n1;

#define gg(n1,n2) cin>>n1>>n2;

#define gg3(n1,n2,n3) cin>>n1>>n2>>n3;

#define hh(n) cout<<n<<endl;

#define t top

#define p push

#define pb push_back

#define mp make_pair

map<ll,set<ll> >edges;

ll arr[100001];

ll fin(ll i)

{	 

	 if(edges.find(i)==edges.end())

     {

		arr[i]=0;

          return 0;

     }

     if(arr[i]!=-1)

	    return arr[i];

     ll maxdis=0,j;	

     set<ll>::iterator ss,kk;

	 for(ss=edges[i].begin();ss!=edges[i].end();ss++)

	     maxdis=max(maxdis,1+fin(*ss));	 

     return arr[i]=maxdis;

}

int main()

{

  ll i,j,n,k,m;

  cin>>n>>m;

  for(i=0;i<100001;i++)  arr[i]=-1;

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

  {

       ll x,y;

       cin>>x>>y;

       x--;y--;

       if(edges.find(x)==edges.end())

       {

            set<ll>set1; set1.insert(y);

            edges.insert(mp(x,set1));

       }

       else

          edges[x].insert(y);

  }

  ll ans=0;

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

  {

     if(arr[i]==-1)  

       fin(i);

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

  }

  cout<<ans<<endl;

  return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

#define ll long long 





int count(int i,vector<vector<int>> &a,int *s)

{

    int t=0;

    int j;

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

    {

        if(s[a[i][j]]==-1)

        s[a[i][j]]= 1+count(a[i][j],a,s);



        if(t<s[a[i][j]])

        t=s[a[i][j]];

    }

    return t;

}

int main()

{

  int n,m,x,y,i;

  cin>>n>>m;

  vector<vector<int>> a(n+1);

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

    {

        cin>>x>>y;

        a[x].push_back(y);

    }

  int t=0;

  int s[n+1];

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



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

  {

      if(s[i]==-1)

      {

          s[i]=1+count(i,a,s);

      }

      if(t<s[i])

      t=s[i];

  }

  cout<<t-1;

    

  return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

#define ll long long 



vector<vector<int>> a(100001);

int s[100001];

int count(int i)

{

    int t=0;

    int j;

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

    {

        if(s[a[i][j]]==-1)

        s[a[i][j]]= 1+count(a[i][j]);



        if(t<s[a[i][j]])

        t=s[a[i][j]];

    }

    return t;

}

int main()

{

  int n,m,x,y,i;

  cin>>n>>m;

  

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

    {

        cin>>x>>y;

        a[x].push_back(y);

    }

  int t=0;

  

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



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

  {

      if(s[i]==-1)

      {

          s[i]=1+count(i);

      }

      if(t<s[i])

      t=s[i];

  }

  cout<<t-1;

    

  return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

#define ll long long 





int count(int i,vector<vector<int>> &a,int *s)

{

    int t=0;

    int j;

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

    {

        if(s[a[i][j]]==-1)

        s[a[i][j]]= 1+count(a[i][j],a,s);



        if(t<s[a[i][j]])

        t=s[a[i][j]];

    }

    return t;

}

int main()

{

  int n,m,x,y,i;

  cin>>n>>m;

  vector<vector<int>> a(n+1);

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

    {

        cin>>x>>y;

        a[x].push_back(y);

    }

  int t=0;

  int s[n+1];

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



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

  {

      if(s[i]==-1)

      {

          s[i]=1+count(i,a,s);

      }

      if(t<s[i])

      t=s[i];

  }

  cout<<t-1;

    

  return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
				/*Saurav Paul*/

#include<bits/stdc++.h>

using namespace std;



using ll = long long int ;

using pii = pair<int,int >;

using vec = vector<int> ;

const int nax = 1e5 + 10;



vec indegree(nax);

vec graph[nax] ;

vector<ll> dp(nax, -1 ) ;



ll dfs(int node){

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

	ll cnt = 0;

	for(auto x : graph[node] ){

		cnt = max(dfs(x) , cnt );

	}

	return dp[node] = cnt + 1; 

}





int main()

{

	int vertex, edge ;

	scanf("%d%d",&vertex,&edge);

	

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

		int a , b; 

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

		graph[a].emplace_back(b);

		indegree[b] ++;

	}

	

	ll ans = 0;

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

		if(indegree[i] == 0 ){

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

		}

		

	}

	

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

    return 0;

}


// Optimized solution to the same problem (faster):
				/*Saurav Paul*/

#include<bits/stdc++.h>

using namespace std;



using vec = vector<int> ;

const int nax = 1e5 + 10;



vec indegree(nax);

vec graph[nax] ;

vec dp(nax, -1 ) ;



int dfs(int node){

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

	int cnt = 0;

	for(auto x : graph[node] ){

		cnt = max(dfs(x) , cnt );

	}

	return dp[node] = cnt + 1; 

}





int main()

{

	int vertex, edge ;

	scanf("%d%d",&vertex,&edge);

	

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

		int a , b; 

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

		graph[a].emplace_back(b);

		indegree[b] ++;

	}

	

	int ans = 0;

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

		if(indegree[i] == 0 ){

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

		}

		

	}

	

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

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#define ll long long

#define MOD 1000000007

using namespace std;

vector<ll>v[100004];

ll ans[100004];

ll dfs(ll i){

    //cout<<i<<"   I\n";

    if(ans[i] != -1){

        return ans[i];

    }

    ll d = 0;

    //cout<<v[i].size()<<" sizee\n";

    for(ll j = 0; j < v[i].size(); j++){

        //cout<<v[i][j]<<"  v\n";

        d = max(d,1+dfs(v[i][j]));

    }

    return ans[i] = d;

}

int main(){



    ll n,m;

    cin>>n>>m;

    memset(ans,-1,sizeof ans);

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

        ll a,b;

        cin>>a>>b;

        v[a].push_back(b);

    }

    ll maxi = 0;

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

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

    }

    cout<<maxi;

    return 0;

}









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

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

//ios::sync_with_stdio(0);cin.tie(0);


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define ll long long

#define MOD 1000000007

#define INF 0x7fffffff

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

#include <ext/pb_ds/assoc_container.hpp> // Common file

#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

using namespace __gnu_pbds;

typedef tree<int,null_type,std::less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

using namespace std;

/*

ordered_set X;

X.insert(1);

cout<<*X.find_by_order(1)<<endl; Kth largest element

cout<<X.order_of_key(-5)<<endl;  number of elemets less than K

*/

vector<ll>vv[100003];

ll dp[100003];

bool visited[100003];

ll  dfs(int u){

    visited[u] = true;

    ll z = 0;

    for(auto v : vv[u]){

        if(!visited[v])

            z = max(dfs(v),z);

        else

            z = max(z,dp[v]);

    }

    return dp[u] = z+1;

}

int main(){

    //freopen(".txt", "w", stdout

    //IO;



    ll n,m;

    cin>>n>>m;

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

        ll a,b;

        cin>>a>>b;

        vv[a] .push_back(b);

    }

    ll ans = 0;

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

        if(!visited[i])

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

    }

    cout<<ans-1;

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<string>

#include<algorithm>

#include<stack>

#include<math.h>

#include<map>

#include <unordered_map> 

#include<vector>

#include<queue>

#include <bits/stdc++.h> 

#include<string>

#define ll long long int

#define N 100005

using namespace std;

string s1,s2;

template <typename T> void max_self(T &a, T b){

	if(b>=a){

		a = b;

	}

}

int vis[N];

int dis[N];

vector<int>g[N];



void dfs(int r, int p){

    vis[r] = 1;

    int m = -1;

    for(auto v: g[r]){

        if(!vis[v])

            dfs(v,r);

        m = max(m,dis[v]);

    }

    dis[r] = m+1;

}

int main(){

	int n,m,x,y;

	cin>>n>>m;

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

	    cin>>x>>y;

	    g[x].push_back(y);

	}

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

	    g[n+1].push_back(i);

	}

	dis[0] = -1;

	dfs(n+1,0);

	int ans =0;

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

	   // cout<<i<<" "<<dis[i]<<endl;

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

	}

	cout<<ans-1;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define ll long long

using namespace std;

void dfs(vector<int> g[],int vis[],int dis[],int node){

    if(vis[node]) return ;

    vis[node] = 1;

    for(int i = 0 ; i<g[node].size() ; i++){

        if(vis[g[node][i]]){

            dis[node] = max(dis[g[node][i]]+1,dis[node]);

        }

        else{

            dfs(g,vis,dis,g[node][i]);

            dis[node] = max(dis[g[node][i]]+1,dis[node]);

        }

    }

}

int main(){

    int n,m;

    scanf(" %d",&n);

    scanf(" %d",&m);

    //cin>>n>>m;

    int vis[n+1];

    int dis[n+1];

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

        vis[i] = 0;

        dis[i] = 0;

    }

    vector<int> g[n+1];

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

        int x,y;

        scanf(" %d",&x);

    scanf(" %d",&y);

        //cin>>x>>y;

        g[x].push_back(y);

    }

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

        if(vis[i]) continue;

        dfs(g,vis,dis,i);

    }

    int maxi = 0;

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

        maxi = max(maxi,dis[i]);

    }

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

    //cout<<maxi<<endl;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

vector<int> edges[100007];

vector<int> visited(1e5+7);

vector<int> indeg(1e5+7);

vector<int> maxd(1e5+7);

void dfs(int i)

{

  visited[i]=true;

  for(int x:edges[i])

  {

    maxd[x]=max(maxd[x],maxd[i]+1);

    visited[x]=true;

    --indeg[x];

    if(indeg[x]==0)

    dfs(x);

  }

}



int main()

{ 

  int n,e;

  cin>>n>>e;

  int a,b;

  while(e--)

  {

    cin>>a>>b;

    edges[a].push_back(b);

    ++indeg[b];

  }

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

  {

    if(!visited[i]&&indeg[i]==0)

    dfs(i);

  }

  int ans=0;

  for(int x:maxd)

  {

    if(x>ans)

    ans=x;

  }

  cout<<ans<<endl;



  return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

using ll=long long;

ll mod=1e9+7;

vector<int> adj[100003];

vector<int> dp(100003,-1);

int solve(int i)

{

  if(dp[i]!=-1)

  return dp[i];

  if(adj[i].empty())

  return dp[i]=0;

  int best=0;

  for(int x: adj[i])

  best=max(best,solve(x)+1);

  return dp[i]=best;

}

int main()

{

  int n,m,x,y;

  cin>>n>>m;

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

  {

    cin>>x>>y;

    adj[x].push_back(y);

  }

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

  solve(i);

  cout<<*max_element(dp.begin(),dp.end())<<endl;

  return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;



using ll = long long;

const int MAXN  = 2e5+10;

const int MAXM  = 1e5+10;



int N, M;



struct edge {

    int to, w;

};

vector<edge> G[MAXN];

int in[MAXN];

int d[MAXN];

bool vis[MAXN];



void add(int u, int v, int w) {

    G[u].push_back({v, w});

}

int bfs(int s) {

    queue<int> que;

    que.push(s);

    vis[s] = true;

    while(!que.empty()) {

        int u = que.front(); que.pop();

        for(int i=0; i<G[u].size(); i++) {

            int v = G[u][i].to;

            if(d[v]<d[u]+1) {

                que.push(v);

                vis[v] = true;

                d[v] = d[u] + 1;

            }

        }

    }



    int ret = 0;

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

        ret = max(ret, d[i]);

    }    

    return ret;

}

int solve(int s) {

    queue<int> que;

    que.push(s);

    while(!que.empty()) {

        int u = que.front(); que.pop();

        for(int i = 0; i<G[u].size(); i++) {

            int v = G[u][i].to;

            --in[v];

            if(in[v]==0) {

                if(d[v] < d[u]+1) {

                    d[v] = d[u] + 1;

                }

                que.push(v);

            }

        }

    }



    int ret = 0;

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

        ret = max(ret, d[i]);

    }    

    return ret;

}

int main() {

    cin >> N >> M;

    int a, b;

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

        cin >> a >> b;

        in[b]++;

        add(a, b, 1);

    }

    /*

    // TLE

    int ans = 0;

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

        if(in[i] == 0) {

            d[i] = 0;

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

        }

    }

    cout << ans << endl;

    */

    

    queue<int> que;

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

        if(in[i] == 0) {

            d[i] = 0;

            que.push(i);

        }

    }

    while(!que.empty()) {

        int u = que.front(); que.pop();

        for(int i = 0; i<G[u].size(); i++) {

            int v = G[u][i].to;

            --in[v];

            if(in[v]==0) {

                if(d[v] < d[u]+1) {

                    d[v] = d[u] + 1;

                }

                que.push(v);

            }

        }

    }



    int ans = 0;

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

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

    }    

    cout << ans << endl;



    return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;



using LL = long long;

const int MAXN = 100100;



int N, M;

vector<int> g[MAXN];

int ans;

int dp[MAXN];

int dfs(int v) {

    if(dp[v]) return dp[v];

    for(int u=0; u<g[v].size(); u++) {

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

    }

    return dp[v];

}

int main() {

    scanf("%d%d", &N, &M);

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

        int x, y;

        scanf("%d%d", &x, &y);

        g[x].push_back(y);

    }

    

    memset(dp, 0, sizeof(dp));

    ans = 0;

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

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

    }

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

    return 0;

}

// Fastest known solution for this problem: