stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#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;

}


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

#include<string>

#include<algorithm>

#include<stack>

#include<math.h>

#include<map>

#include<unordered_map> 

#include<vector>

#include<queue>

#include<set>

#include<bits/stdc++.h>

#include<deque> 

#include<bitset>

#include<string>

#define N 40

#define K 300005

#define MOD 1e9+7

#define int long long 

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

using namespace std;



int max(int a, int b){

    if(a>b)

        return a;

    return b;

}

int mod = 1e9 + 7;

int ans = 0;

int vis[100005], dis[100005], in[100005];

void dfs(int pa, int ro, vector<int> g[]){

	vis[ro] = 1;

	



	for(int x: g[ro]){

		in[x] --;

		dis[x] = max(dis[x], dis[ro] + 1);

		if(vis[x] == 0 && in[x] == 0){

			dfs(ro, x, g);

		}

	}



}

int32_t main(){

	int n, m;

	cin>>n>>m;

	vector<int> g[n+1];

	int x, y;

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

		cin>>x>>y;

		g[x].push_back(y);

		in[y]++;

	}

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

		//g[0].push_back(i);

		g[0].push_back(i);

        in[i]++;

	}



	dfs(-1, 0, g);

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

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

	}

	cout<<ans - 1;

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

}


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

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

}


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

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

}

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

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



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

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

}



int dp[MAXN];

int dfs(int s) {

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

    for(auto e : G[s]) {

        dp[s] = max(dp[s], dfs(e.to) + 1); 

    }

    return dp[s];

}

void solve() {

    int ans = 0;

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

        if(in[v] == 0){

            dp[v] = 0;

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

        } 

    }

    cout << ans << endl;

}



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;

    */

    

    /*

    // bfs

    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;

    */

   // dfs

   solve();



    return 0;

}

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

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

using namespace std;

int n,m;

vector<int> pred[100010];

int f[100010];

int lp(int x){

	if(f[x]!=-1)

	   return f[x];

	for(int i=0;i<pred[x].size();i++){

		f[x]=max(f[x],lp(pred[x][i])+1);

	}

	f[x]=max(f[x],0);

	return f[x];

}

int main()

{

	cin>>n>>m;

	int a,b;

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

		cin>>a>>b;

		pred[b].push_back(a);

	}

	int maxx=0;

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

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

		if(f[i]==-1)

	      f[i]=lp(i);

	    maxx=max(maxx,f[i]);

	}

	cout<<maxx<<endl;

	return 0;

}


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

using namespace std;

int n,m;

vector<int> g[100010];

int ind[100010];

int a,b,c;

int dp[100010];

int main()

{

	cin>>n>>m;

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

		cin>>a>>b;

		g[a].push_back(b);

		ind[b]++;

	}

	stack<int> s;

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

	   if(ind[i]==0)

	      s.push(i);

	while(s.size()){

		int p=s.top();

		s.pop();

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

			int to=g[p][i];

			if(dp[p]+1>dp[to]){

				dp[to]=dp[p]+1;

			}

			ind[to]--;

			if(!ind[to]) s.push(to);

		}

	}

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

	return 0;

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

using namespace std;

int n,m;

int dp[100010];

vector<int> adj[100010];

int rec(int x){

	if(dp[x]>=0)

	   return dp[x];

	if(adj[x].empty())

	   return dp[x]=0;

	dp[x]=dp[adj[x][0]]+1;

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

		dp[x]=max(rec(adj[x][i])+1,dp[x]);

	}

	return  dp[x];

}

int a,b;

int main()

{

	cin>>n>>m;

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

	{

		cin>>a>>b;

		adj[a].push_back(b);

	}

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

	int ans=0;

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

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

	cout<<ans<<endl;

	return 0;

}


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

using namespace std;

int n,m;

vector<int> g[100010];

int ind[100010];

int a,b,c;

int dp[100010];

int main()

{

	cin>>n>>m;

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

		cin>>a>>b;

		g[a].push_back(b);

		ind[b]++;

	}

	stack<int> s;

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

	   if(ind[i]==0)

	      s.push(i);

	while(s.size()){

		int p=s.top();

		s.pop();

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

			int to=g[p][i];

			if(dp[p]+1>dp[to]){

				dp[to]=dp[p]+1;

			}

			ind[to]--;

			if(!ind[to]) s.push(to);

		}

	}

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

	return 0;

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

using namespace std;

int n,m;

vector<int> pred[100010];

int f[100010];

int lp(int x){

	if(f[x]!=-1)

	   return f[x];

	for(int i=0;i<pred[x].size();i++){

		f[x]=max(f[x],lp(pred[x][i])+1);

	}

	f[x]=max(f[x],0);

	return f[x];

}

int main()

{

	cin>>n>>m;

	int a,b;

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

		cin>>a>>b;

		pred[b].push_back(a);

	}

	int maxx=0;

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

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

		if(f[i]==-1)

	      f[i]=lp(i);

	    maxx=max(maxx,f[i]);

	}

	cout<<maxx<<endl;

	return 0;

}


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

using namespace std;

int indeg[101000],n,m,dist[101000];

vector<int> e[101000];

int a,b;

int main()

{

	cin>>n>>m;

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

	{

		cin>>a>>b;

		indeg[b]++;

		e[a].push_back(b);

	}

	queue<int> q;

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

	   if(indeg[i]==0)

	      q.push(i);

	int res=0;

	while(q.size()){

		int x=q.front();

		q.pop();

		res=max(res,dist[x]);

		for(int i=0;i<e[x].size();i++){

			indeg[e[x][i]]--;

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

			if(indeg[e[x][i]]==0){

				q.push(e[x][i]);

			}

		}

	}

	cout<<res<<endl;

	return 0;

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

using namespace std;

int n,m;

int dp[100010];

vector<int> adj[100010];

int rec(int x){

	if(dp[x]>=0)

	   return dp[x];

	if(adj[x].empty())

	   return dp[x]=0;

	dp[x]=dp[adj[x][0]]+1;

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

		dp[x]=max(rec(adj[x][i])+1,dp[x]);

	}

	return  dp[x];

}

int a,b;

int main()

{

	cin>>n>>m;

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

	{

		cin>>a>>b;

		adj[a].push_back(b);

	}

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

	int ans=0;

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

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

	cout<<ans<<endl;

	return 0;

}


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

using namespace std;

int indeg[101000],n,m,dist[101000];

vector<int> e[101000];

int a,b;

int main()

{

	cin>>n>>m;

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

	{

		cin>>a>>b;

		indeg[b]++;

		e[a].push_back(b);

	}

	queue<int> q;

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

	   if(indeg[i]==0)

	      q.push(i);

	int res=0;

	while(q.size()){

		int x=q.front();

		q.pop();

		res=max(res,dist[x]);

		for(int i=0;i<e[x].size();i++){

			indeg[e[x][i]]--;

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

			if(indeg[e[x][i]]==0){

				q.push(e[x][i]);

			}

		}

	}

	cout<<res<<endl;

	return 0;

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

using namespace std;

int n,m;

int dp[100010];

vector<int> radj[100010];

int rec(int x){

	if(dp[x]>=0)

	   return dp[x];

	if(radj[x].empty())

	   return dp[x]=0;

	dp[x]=dp[radj[x][0]]+1;

	for(int i=0;i<radj[x].size();i++){

		dp[x]=max(rec(radj[x][i])+1,dp[x]);

	}

	return  dp[x];

}

int a,b;

int main()

{

	cin>>n>>m;

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

	{

		cin>>a>>b;

		radj[a].push_back(b);

	}

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

	int ans=0;

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

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

	cout<<ans<<endl;

	return 0;

}

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

using namespace std;

int indeg[101000],n,m,dist[101000];

vector<int> e[101000];

int a,b;

int main()

{

	cin>>n>>m;

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

	{

		cin>>a>>b;

		indeg[b]++;

		e[a].push_back(b);

	}

	queue<int> q;

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

	   if(indeg[i]==0)

	      q.push(i);

	int res=0;

	while(q.size()){

		int x=q.front();

		q.pop();

		res=max(res,dist[x]);

		for(int i=0;i<e[x].size();i++){

			indeg[e[x][i]]--;

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

			if(indeg[e[x][i]]==0){

				q.push(e[x][i]);

			}

		}

	}

	cout<<res<<endl;

	return 0;

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

using namespace std;

int n,m;

vector<int> pred[100010];

int f[100010];

int lp(int x){

	if(f[x]!=-1)

	   return f[x];

	for(int i=0;i<pred[x].size();i++){

		f[x]=max(f[x],lp(pred[x][i])+1);

	}

	f[x]=max(f[x],0);

	return f[x];

}

int main()

{

	cin>>n>>m;

	int a,b;

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

		cin>>a>>b;

		pred[b].push_back(a);

	}

	int maxx=0;

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

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

		if(f[i]==-1)

	      f[i]=lp(i);

	    maxx=max(maxx,f[i]);

	}

	cout<<maxx<<endl;

	return 0;

}


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

using namespace std;

queue<int> q;

int a,b;

vector<int> ga[100010];

int indeg[100010];

int n,m;

int dp[100010];

int res;

int main()

{

	cin>>n>>m;

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

		cin>>a>>b;

		ga[a].push_back(b);

		indeg[b]++;

	}

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

		if(indeg[i]==0)

		   q.push(i);

	}

	while(!q.empty()){

		int u=q.front();

		q.pop();

		res=max(res,dp[u]);

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

			int v=ga[u][i];

			indeg[v]--;

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

			if(indeg[v]==0)

			   q.push(v);

		}

	}

	cout<<res<<endl;

	return 0;

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

using namespace std;

int n,m;

int dp[100010];

vector<int> adj[100010];

int rec(int x){

	if(dp[x]>=0)

	   return dp[x];

	if(adj[x].empty())

	   return dp[x]=0;

	dp[x]=dp[adj[x][0]]+1;

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

		dp[x]=max(rec(adj[x][i])+1,dp[x]);

	}

	return  dp[x];

}

int a,b;

int main()

{

	cin>>n>>m;

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

	{

		cin>>a>>b;

		adj[a].push_back(b);

	}

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

	int ans=0;

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

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

	cout<<ans<<endl;

	return 0;

}


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

using namespace std;

queue<int> q;

int a,b;

vector<int> ga[100010];

int indeg[100010];

int n,m;

int dp[100010];

int res;

int main()

{

	cin>>n>>m;

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

		cin>>a>>b;

		ga[a].push_back(b);

		indeg[b]++;

	}

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

		if(indeg[i]==0)

		   q.push(i);

	}

	while(!q.empty()){

		int u=q.front();

		q.pop();

		res=max(res,dp[u]);

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

			int v=ga[u][i];

			indeg[v]--;

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

			if(indeg[v]==0)

			   q.push(v);

		}

	}

	cout<<res<<endl;

	return 0;

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

using namespace std;

int n,m;

int dp[100010];

vector<int> radj[100010];

int rec(int x){

	if(dp[x]>=0)

	   return dp[x];

	if(radj[x].empty())

	   return dp[x]=0;

	dp[x]=dp[radj[x][0]]+1;

	for(int i=0;i<radj[x].size();i++){

		dp[x]=max(rec(radj[x][i])+1,dp[x]);

	}

	return  dp[x];

}

int a,b;

int main()

{

	cin>>n>>m;

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

	{

		cin>>a>>b;

		radj[a].push_back(b);

	}

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

	int ans=0;

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

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

	cout<<ans<<endl;

	return 0;

}

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

using namespace std;

queue<int> q;

int a,b;

vector<int> ga[100010];

int indeg[100010];

int n,m;

int dp[100010];

int res;

int main()

{

	cin>>n>>m;

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

		cin>>a>>b;

		ga[a].push_back(b);

		indeg[b]++;

	}

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

		if(indeg[i]==0)

		   q.push(i);

	}

	while(!q.empty()){

		int u=q.front();

		q.pop();

		res=max(res,dp[u]);

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

			int v=ga[u][i];

			indeg[v]--;

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

			if(indeg[v]==0)

			   q.push(v);

		}

	}

	cout<<res<<endl;

	return 0;

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

using namespace std;

int n,m;

vector<int> ga[100010];

int x,y;

int dp[100010];

int dypr(int u){

	if(dp[u]!=-1)

	   return dp[u];

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

		int v=ga[u][i];

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

	}

	return dp[u];

}

int main()

{

	cin>>n>>m;

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

	{

		cin>>x>>y;

		ga[y].push_back(x);

	}

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

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

	   dp[i]=dypr(i);

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

	return 0;

}


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

using namespace std;

queue<int> q;

int a,b;

vector<int> ga[100010];

int indeg[100010];

int n,m;

int dp[100010];

int res;

int main()

{

	cin>>n>>m;

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

		cin>>a>>b;

		ga[a].push_back(b);

		indeg[b]++;

	}

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

		if(indeg[i]==0)

		   q.push(i);

	}

	while(!q.empty()){

		int u=q.front();

		q.pop();

		res=max(res,dp[u]);

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

			int v=ga[u][i];

			indeg[v]--;

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

			if(indeg[v]==0)

			   q.push(v);

		}

	}

	cout<<res<<endl;

	return 0;

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

using namespace std;

int n,m;

vector<int> ga[100010];

int x,y;

int dp[100010];

int sol(int u){

	if(~dp[u])

	   return dp[u];

	if(ga[u].empty())

	   return dp[u]=0;

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

		int v=ga[u][i];

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

	}

	return dp[u];

}

int main()

{

	cin>>n>>m;

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

	{

		cin>>x>>y;

		ga[x].push_back(y);

	}

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

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

	   sol(i);

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

using namespace std;

queue<int> q;

int a,b;

vector<int> ga[100010];

int indeg[100010];

int n,m;

int dp[100010];

int res;

int main()

{

	cin>>n>>m;

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

		cin>>a>>b;

		ga[a].push_back(b);

		indeg[b]++;

	}

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

		if(indeg[i]==0)

		   q.push(i);

	}

	while(!q.empty()){

		int u=q.front();

		q.pop();

		res=max(res,dp[u]);

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

			int v=ga[u][i];

			indeg[v]--;

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

			if(indeg[v]==0)

			   q.push(v);

		}

	}

	cout<<res<<endl;

	return 0;

}