stablegradients/pie-gem5-pairs huggingface dataset:
// 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, int pr){



    auto &ret = dp[node];

    if(ret!=-1) return ret;

    ret = 0;

    for(auto i: g[node]){

        if(i==pr) continue;

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

    }



    return ret;

}



void read(){



    int i,edge;

    memset(dp,-1,sizeof dp);

    cin>>N>>edge;

    for(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,0) );

    }



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

using namespace std;

int N, M, x, y;

vector <int> adj[100005];

int dis[100005];

using namespace std;

int dfs(int cur){

	if(dis[cur] != 1) return dis[cur];

	int maxtemp = 0;

	for(auto j : adj[cur]){

		maxtemp = max(maxtemp, dfs(j));

	}

	dis[cur] += maxtemp;

	return dis[cur];

}

int main(){

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

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

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

		adj[x].push_back(y);

	}

	fill(dis,dis+N+1,1);

	int maxdis = 0;

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

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

	}

	cout << maxdis -1 <<endl;

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

#define f(i,s,v) for(int i=(int)s;i<(int)v;++i)

#define rf(i,s,v) for(int i=(int)s-1;i>(int)v;--i)

#define pb push_back

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

#define memset(c, value) memset(c, (int)value, sizeof(c))

using namespace std;

typedef long long ll;

const ll oo = 1e18;

const ll MOD =1e9+7;

const double pi = acos(-1);

void fast(){

    ios_base :: sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

}

int n, m;

bool valid (int r,int c){

    return (r < n && r >= 0 && c >= 0 && c < m);

}



int row[] = {0 , 1 , 0, -1};

int column[] = {1 , 0, -1, 0};



vector<int> adj[100001];

int path[100001];

int vis[100001];



int dp(int u){

    if(path[u]!=-1)

        return path[u];



    vis[u] = true;



    int sz = adj[u].size();



    path[u] = 0;

    f(j, 0, sz){

        if(!vis[adj[u][j]])

            path[u] = max( path[u], 1 + dp(adj[u][j]));

    }

    vis[u] = false;



    return path[u];

}





int main()

{

    fast();



    int u, v;

    cin>>n>>m;

    f(i, 0, m){

        cin>>u>>v;

        adj[u].push_back(v);

    }

    int maxi = 0;

    memset(vis, 0);

    memset(path, -1);



    f(i, 1, n+1){



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

    }



    cout<<maxi<<'\n';

    return 0;

}


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

using namespace std;

int N, M, x, y;

vector <int> adj[100005];

int dis[100005];

using namespace std;

int dfs(int cur){

	if(dis[cur] != 1) return dis[cur];

	int maxtemp = 0;

	for(auto j : adj[cur]){

		maxtemp = max(maxtemp, dfs(j));

	}

	dis[cur] += maxtemp;

	return dis[cur];

}

int main(){

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

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

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

		adj[x].push_back(y);

	}

	fill(dis,dis+N+1,1);

	int maxdis = 0;

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

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

	}

	cout << maxdis -1 <<endl;

}
// Slower C++ solution:
#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" ;

}

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

using namespace std;

int N, M, x, y;

vector <int> adj[100005];

int dis[100005];

using namespace std;

int dfs(int cur){

	if(dis[cur] != 1) return dis[cur];

	int maxtemp = 0;

	for(auto j : adj[cur]){

		maxtemp = max(maxtemp, dfs(j));

	}

	dis[cur] += maxtemp;

	return dis[cur];

}

int main(){

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

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

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

		adj[x].push_back(y);

	}

	fill(dis,dis+N+1,1);

	int maxdis = 0;

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

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

	}

	cout << maxdis -1 <<endl;

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

using namespace std;



vector<int> adj[100005];

int n,m;



int level[100005];

int dfs(int source){

    if(level[source]!=-1) return level[source];

    int res=0;

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

            int v;

            v=dfs(adj[source][i]);

            res=max(res,v);

    }

    res++;

    level[source]=res;

    return res;

   

}

int main(){

   

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

    cin >> n >> m;

    while(m--){

        int a,b;

        cin >> a >> b;

        adj[a].push_back(b);

    }

    vector<int> xoxo;

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

        xoxo.push_back(dfs(i));

    }

    sort(xoxo.begin(),xoxo.end(),greater<int>());

    

    cout << xoxo[0]-1 << endl;

    

   

    

}

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

using namespace std;

int N, M, x, y;

vector <int> adj[100005];

int dis[100005];

using namespace std;

int dfs(int cur){

	if(dis[cur] != 1) return dis[cur];

	int maxtemp = 0;

	for(auto j : adj[cur]){

		maxtemp = max(maxtemp, dfs(j));

	}

	dis[cur] += maxtemp;

	return dis[cur];

}

int main(){

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

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

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

		adj[x].push_back(y);

	}

	fill(dis,dis+N+1,1);

	int maxdis = 0;

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

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

	}

	cout << maxdis -1 <<endl;

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

#define ll long long

using namespace std;

ll n,m,x,y;

vector<ll>v[100009];

ll dp[100009];



ll f(ll N){

	if (v[N].empty())return 0;

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

	ll z=0;

	for(int i=0; i<v[N].size(); i++){

		z=max(z,f(v[N][i])+1);

	}

	dp[N]=z;

	return dp[N];

}



int main(){

	cin >> n >> m;

	memset(dp,-1,sizeof dp);

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

		cin >> x >> y;

		v[x].push_back(y);

	}

	ll jwb=0;

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

		jwb=max(jwb,f(i));

	}

	cout << jwb << endl;

}//j

// Faster C++ solution for the same problem (measured speedup: 1.241152841826985x):
/*

    if you can't see the repay

    Why not just work step by step

    rubbish is relaxed

    to ljq

*/

#include <cstdio>

#include <cstring>

#include <iostream>

#include <queue>

#include <cmath>

#include <map>

#include <stack>

#include <set>

#include <sstream>

#include <vector>

#include <stdlib.h>

#include <algorithm>

using namespace std;



#define dbg(x) cout<<#x<<" = "<< (x)<< endl

#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl

#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl

#define max3(a,b,c) max(a,max(b,c))

#define min3(a,b,c) min(a,min(b,c))

#define lc (rt<<1)

#define rc (rt<<11)

#define mid ((l+r)>>1)



typedef pair<int,int> pll;

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int _inf = 0xc0c0c0c0;

const ll INF = 0x3f3f3f3f3f3f3f3f;

const ll _INF = 0xc0c0c0c0c0c0c0c0;

const ll mod =  (int)1e9+7;



ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}

ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}

ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}

void exgcd(ll a,ll b,ll &x,ll &y,ll &d){if(!b) {d = a;x = 1;y=0;}else{exgcd(b,a%b,y,x,d);y-=x*(a/b);}}//printf("%lld*a + %lld*b = %lld\n", x, y, d);

const int MAX_N = 100025;

int dp[MAX_N],in[MAX_N];

vector<int > G[MAX_N];

int main()

{

    //ios::sync_with_stdio(false);

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

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

    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);

    //fclose(stdin);

    //fclose(stdout);

    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;

    return 0;

}
// Slower C++ solution:
#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" ;

}

// Faster C++ solution for the same problem (measured speedup: 1.1241764620839951x):
/*

    if you can't see the repay

    Why not just work step by step

    rubbish is relaxed

    to ljq

*/

#include <cstdio>

#include <cstring>

#include <iostream>

#include <queue>

#include <cmath>

#include <map>

#include <stack>

#include <set>

#include <sstream>

#include <vector>

#include <stdlib.h>

#include <algorithm>

using namespace std;



#define dbg(x) cout<<#x<<" = "<< (x)<< endl

#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl

#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl

#define max3(a,b,c) max(a,max(b,c))

#define min3(a,b,c) min(a,min(b,c))

#define lc (rt<<1)

#define rc (rt<<11)

#define mid ((l+r)>>1)



typedef pair<int,int> pll;

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int _inf = 0xc0c0c0c0;

const ll INF = 0x3f3f3f3f3f3f3f3f;

const ll _INF = 0xc0c0c0c0c0c0c0c0;

const ll mod =  (int)1e9+7;



ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}

ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}

ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}

void exgcd(ll a,ll b,ll &x,ll &y,ll &d){if(!b) {d = a;x = 1;y=0;}else{exgcd(b,a%b,y,x,d);y-=x*(a/b);}}//printf("%lld*a + %lld*b = %lld\n", x, y, d);

const int MAX_N = 100025;

int dp[MAX_N],in[MAX_N];

vector<int > G[MAX_N];

int main()

{

    //ios::sync_with_stdio(false);

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

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

    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);

    //fclose(stdin);

    //fclose(stdout);

    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;

    return 0;

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

using namespace std;



vector<int> adj[100005];

int n,m;



int level[100005];

int dfs(int source){

    if(level[source]!=-1) return level[source];

    int res=0;

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

            int v;

            v=dfs(adj[source][i]);

            res=max(res,v);

    }

    res++;

    level[source]=res;

    return res;

   

}

int main(){

   

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

    cin >> n >> m;

    while(m--){

        int a,b;

        cin >> a >> b;

        adj[a].push_back(b);

    }

    vector<int> xoxo;

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

        xoxo.push_back(dfs(i));

    }

    sort(xoxo.begin(),xoxo.end(),greater<int>());

    

    cout << xoxo[0]-1 << endl;

    

   

    

}

// Faster C++ solution for the same problem (measured speedup: 1.1177746392568517x):
/*

    if you can't see the repay

    Why not just work step by step

    rubbish is relaxed

    to ljq

*/

#include <cstdio>

#include <cstring>

#include <iostream>

#include <queue>

#include <cmath>

#include <map>

#include <stack>

#include <set>

#include <sstream>

#include <vector>

#include <stdlib.h>

#include <algorithm>

using namespace std;



#define dbg(x) cout<<#x<<" = "<< (x)<< endl

#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl

#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl

#define max3(a,b,c) max(a,max(b,c))

#define min3(a,b,c) min(a,min(b,c))

#define lc (rt<<1)

#define rc (rt<<11)

#define mid ((l+r)>>1)



typedef pair<int,int> pll;

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int _inf = 0xc0c0c0c0;

const ll INF = 0x3f3f3f3f3f3f3f3f;

const ll _INF = 0xc0c0c0c0c0c0c0c0;

const ll mod =  (int)1e9+7;



ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}

ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}

ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}

void exgcd(ll a,ll b,ll &x,ll &y,ll &d){if(!b) {d = a;x = 1;y=0;}else{exgcd(b,a%b,y,x,d);y-=x*(a/b);}}//printf("%lld*a + %lld*b = %lld\n", x, y, d);

const int MAX_N = 100025;

int dp[MAX_N],in[MAX_N];

vector<int > G[MAX_N];

int main()

{

    //ios::sync_with_stdio(false);

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

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

    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);

    //fclose(stdin);

    //fclose(stdout);

    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;

    return 0;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 1.7980622763782161x):
#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;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 3.9287713637809727x):
#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;

}
// Slower C++ solution:
				/*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;

}


// Faster C++ solution for the same problem (measured speedup: 1.1035803711230971x):
				/*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;

}
// Slower C++ solution:
#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);


// Faster C++ solution for the same problem (measured speedup: 1.2384812931637394x):
#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;

}