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

#include<iomanip>

#include<cstdio>

#include<cmath>

#include<vector>

#include<string>

#include<algorithm>

#include<queue>

#include<set>

#include<map>

#include<limits>

#include<stack>

#include<array>

#include<stdio.h>

#include<cstring>



using namespace std;



typedef long long ll;

typedef pair<int,int> ii;

typedef vector<pair<int,int> > vii;

typedef vector<vii> vvii;

typedef vector<int> vi;

typedef vector<vi> vvi;

typedef vector<ll> vll;

typedef vector<vll> vvll;

typedef vector<bool> vb;

typedef vector<vb> vvb;

typedef vector<char> vc;

typedef vector<vc> vvc;

typedef vector<string> vs;



int INF = std::numeric_limits<int>::max();

ll LLINF = 1e15;

int NINF = std::numeric_limits<int>::min();

int MOD = 1e9+7;



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

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



//knight moves

int cc[] = {1,2,2,1,-1,-1,-2,-2};

int rr[] = {-2,-1,1,2,-2,2,1,-1};



vvi adjLst(1e5+5,vi());

vb vstd(1e5+5,0);

vi dp(1e5+5,1);





void dfs(int u)

{

    vstd[u] = 1;

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

    {

        if(!vstd[adjLst[u][i]])

            dfs(adjLst[u][i]);



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

    }

}





int main()

{

    //cout << LLINF ;

    ios::sync_with_stdio(0);

    cin.tie(0);



    int n, m, u, v;

    cin >> n >> m;

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

    {

        cin >> u >> v;

        adjLst[u].push_back(v);

    }



    int mx = 0;

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

    {

        if(!vstd[i])

            dfs(i);

    }



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

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



    cout << mx-1;



    return 0;

}


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

#define f first

#define s second

#define pb push_back

#define ENDL '\n'

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

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

#define deb(a) cout << #a << ": " << a << ENDL

#define fore(i, a, b) for(int i(a), ThkMk(b); i < ThkMk; ++i)

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



using namespace std;



typedef long long lli;

typedef long double ld;

typedef pair<lli, lli> ii;

typedef vector<lli> vi;



vector<vector<lli>> graph;

vector<lli> dp;



int dfs(int u) {

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

    int ret = 0;

    for(auto it : graph[u]) {

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

    }

    dp[u] = ret;

    return ret;

}



int main()

{   _

    lli n, m, u, v; cin >> n >> m;

    graph.resize(n + 1);

    dp.resize(n + 1);

    fill(all(dp), -1);

    fore(i, 0, m) {

        cin >> u >> v;

        graph[u].pb(v);

    }

    int mx = 0;

    fore(i, 1, n + 1) mx = max(mx, dfs(i));

    cout << mx << ENDL;

    return 0;

}


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

using namespace std;



vector<int>v[100001];

int dp[100001];



int fun(int src){

       

       if(dp[src] != -1)

          return dp[src];



          bool leaf = true;

          int bestchild = -1;

        for(int nbr : v[src]){

            leaf = false;

            bestchild =  max(bestchild,fun(nbr));

        }

       return dp[src] = leaf? 0 : 1+bestchild;

}



void solve(){

  int n,m;

  cin >> n >> m;

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

      int x , y;

      cin >> x >> y;

      v[x].push_back(y);

  } 

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

       int ans = 0;

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

       { ans = max(ans,fun(i));}

    cout << ans;



}

int main(){

//  #ifndef ONLINE_JUDGE

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

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

// #endif 



solve();

return 0;

}

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

using namespace std;



vector<list<int>>v;





int fun(vector<int> &dp,int src){

       if(v[src].empty())

          {    dp[src] = 0;

               return 0;}



       if(dp[src] != -1)

          return dp[src];



          int bestchild = -1;

        for(int nbr : v[src]){

          

            bestchild =  max(bestchild,fun(dp,nbr));

        }

       return dp[src] = 1+bestchild;

}



void solve(){

  int n,m;

  cin >> n >> m;

  v.resize(n+1);

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

      int x , y;

      cin >> x >> y;

      v[x].push_back(y);

  } 

      vector<int>dp(n+1,-1);

     

       int ans = 0;

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

       { ans = max(ans,fun(dp,i));}



  cout << ans;



}

int main(){

//  #ifndef ONLINE_JUDGE

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

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

// #endif 



solve();

return 0;

}

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

 

using namespace std;

 

#define lli long long int

#define REP(i,s,l) for(lli i=s;i<l;i++)

#define DEBUG 0

#define INF (1LL<<50)

#define MOD 1000000007



lli dp[100100];

map<lli,vector<lli>> x;



lli dfs(lli p){

	if(dp[p]>0)return dp[p];



	REP(i,0,x[p].size()){

		lli next = x[p][i];

		dp[p] = max(dp[p],dfs(next)+1);

	}

	return dp[p];

}



signed main(){



	lli n,m;

	cin>>n>>m;

	REP(i,0,100100)dp[i]=0;



	REP(i,0,m){

		lli a,b;

		cin>>a>>b;

		a--,b--;

		x[a].push_back(b);

	}



	lli ans=0;

	REP(i,0,n){

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

	}



	cout<<ans<<endl;



	return 0;

}

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



using namespace std;



#define lli long long int

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

#define MOD 1000000007

#define NUM 2520

#define INF (1LL<<50)

#define DEBUG 0

#define mp(a,b) make_pair(a,b)

#define SORT(V) sort(V.begin(),V.end())

#define PI (3.141592653589794)



lli dp[100100];

bool vis[100100];

map<lli,vector<lli>> d;



lli dfs(lli now){

	if(vis[now])return dp[now];

	vis[now]=true;



	lli ret=0;

	for(auto e:d[now]){

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

	}

	return dp[now]=ret;

}



signed main(){



	lli n,m;

	cin>>n>>m;



	REP(i,0,m){

		lli x,y;

		cin>>x>>y;

		x--,y--;

		d[x].push_back(y);

	}



	lli ans=0;

	REP(i,0,n){

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

	}



	cout<<ans<<endl;

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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

// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include<iomanip>

#include <algorithm>

#include <map>

#include <vector>

#include<queue>

#include<math.h>

#include<cmath>

#include<sstream>

#include<set>

#include <map>

#include<string.h>

#include<sstream>

#include<stack>

#include<unordered_map>

#include <iostream>

#include <stdio.h>

#include <ctype.h>

#include <cstdio>

#include <cstdlib>

#define ll long long

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

#define arr2dof vector  vector<vector<int>>dp(N,vector<int>(2, inf));

using namespace std;

const int N = 2e5 + 5, inf = 1e9+7 ;

const double ep = 0.0000000001;

const double pi = 3.14159265359;

const long long inff= 1e18;

vector < vector<int>>graph;

int n, m,a,b;

int dp[100005];

bool visited[100005];

void dfs(int node) {

	visited[node] = true;

	for (int child : graph[node]) {

		if (!visited[child]) 

		dfs(child);

		

		

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

		

	}

}





int main()

{

	

	cin >> n>>m;

	graph.resize(max(n,m) + 5);

	

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

		cin >> a >> b;

		graph[a].push_back(b);

	

	}

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

		if (!visited[i])

			dfs(i);

	}

	int ans = 0;

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

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

	}

	cout << ans;

	return 0;

}

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



using namespace std;



#define ll long long int



int memo[(int)1e5 + 1];

vector<int> adj[(int)1e5 + 1];



bool vis[(int)1e5 + 1];



int dfs(int x) {

	

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



	vis[x] = true;

	

	int temp = 1;



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

		memo[x] = max(memo[x], temp + dfs(adj[x][i]));

	}



	return memo[x];

}



int main() {



	ios_base::sync_with_stdio(0);

	cin.tie(0);

	

	int n,m; cin >> n >> m;

	int s,t;

	

	while(m--) {

		cin >> s >> t;

		adj[s].push_back(t);

	}



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

		dfs(i);

	}



	int ans = 0;

	

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

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

	}



	cout << ans << '\n';



	return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include<iomanip>

#include <algorithm>

#include <map>

#include <vector>

#include<queue>

#include<math.h>

#include<cmath>

#include<sstream>

#include<set>

#include <map>

#include<string.h>

#include<sstream>

#include<stack>

#include<unordered_map>

#include <iostream>

#include <stdio.h>

#include <ctype.h>

#include <cstdio>

#include <cstdlib>

#define ll long long

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

#define arr2dof vector  vector<vector<int>>dp(N,vector<int>(2, inf));

using namespace std;

const int N = 2e5 + 5, inf = 1e9+7 ;

const double ep = 0.0000000001;

const double pi = 3.14159265359;

const long long inff= 1e18;

vector < vector<int>>graph;

int n, m,a,b;

int dp[100005];

bool visited[100005];

void dfs(int node) {

	visited[node] = true;

	for (int child : graph[node]) {

		if (!visited[child]) 

		dfs(child);

		

		

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

		

	}

}





int main()

{

	

	cin >> n>>m;

	graph.resize(max(n,m) + 5);

	

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

		cin >> a >> b;

		graph[a].push_back(b);

	

	}

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

		if (!visited[i])

			dfs(i);

	}

	int ans = 0;

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

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

	}

	cout << ans;

	return 0;

}

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

using namespace std;



const int N = 1e5 + 100;





#define mp make_pair

#define f first

#define s second



#define pb push_back



void boost()

{

	ios_base::sync_with_stdio(0);

	cin.tie(0);

	cout.tie(0);

}



int n,m;



vector<int>g[N];



bool was[N];



int d[N];



vector<int>ord;

int ans;



void dfs(int v)

{

 	was[v] = 1;

 	for (int to :g[v])

 	{

 		if (!was[to])

 		{

 			dfs(to);

 		}

 	}

 	ord.pb(v);

}

                                                                                                          

void dfs1(int v)

{

 	was[v] = 1;

 	for (int to :g[v])

 	{

 		if (!was[to])

 		{

 			dfs1(to);

 		}                               

 		d[v] = max(d[v],d[to] + 1);

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

 	}                          

}





int main(){

	boost();

	cin >> n >> m;

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

	{

		int u,v;

		cin >> u >> v;

		g[u].pb(v);

	}

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

	{

		if (!was[i])

		{             

			dfs(i);

		}

	}

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

	{

		was[i] = 0;

	}

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

	{                        

		dfs1(ord[i]);            

	}

	cout << ans;       

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include<iomanip>

#include <algorithm>

#include <map>

#include <vector>

#include<queue>

#include<math.h>

#include<cmath>

#include<sstream>

#include<set>

#include <map>

#include<string.h>

#include<sstream>

#include<stack>

#include<unordered_map>

#include <iostream>

#include <stdio.h>

#include <ctype.h>

#include <cstdio>

#include <cstdlib>

#define ll long long

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

#define arr2dof vector  vector<vector<int>>dp(N,vector<int>(2, inf));

using namespace std;

const int N = 2e5 + 5, inf = 1e9+7 ;

const double ep = 0.0000000001;

const double pi = 3.14159265359;

const long long inff= 1e18;

vector < vector<int>>graph;

int n, m,a,b;

int dp[100005];

bool visited[100005];

void dfs(int node) {

	visited[node] = true;

	for (int child : graph[node]) {

		if (!visited[child]) 

		dfs(child);

		

		

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

		

	}

}





int main()

{

	

	cin >> n>>m;

	graph.resize(max(n,m) + 5);

	

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

		cin >> a >> b;

		graph[a].push_back(b);

	

	}

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

		if (!visited[i])

			dfs(i);

	}

	int ans = 0;

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

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

	}

	cout << ans;

	return 0;

}

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

/**

*   author: j o s e m a g o

*   date:

**/

using namespace std;

#pragma GCC optimize ("Ofast")

#define f first

#define s second

#define mp make_pair

#define lb lower_bound

#define ub upper_bound

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

#define mset(a,v) memset(a,v,sizeof(a))

#define pb push_back

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

#define rsz resize

#define ln "\n"



typedef double db;

typedef unsigned long long ull;

typedef long long ll;

typedef long double ld;

const ld PI = 2*acos(0.0);

const int MOD = 1000000007;

const int JJJ = 100009;



int N,A;

vector<int>grafo[JJJ];

bool visited[JJJ];

int dp[JJJ];



int sol = 0;

void dfs(int nod){

    visited[nod] = true;

    dp[nod] = -1;

    for(int i = 0;i < (int)grafo[nod].size();i++){

        int xx = grafo[nod][i];

        if(!visited[xx]){

            dfs(xx);

        }

        dp[nod] = max(dp[nod],dp[xx]);

    }

    dp[nod]++;

}







int main(){



  

    ios_base::sync_with_stdio(0); cin.tie(0);





    cin >> N >> A;

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

        int a,b;

        cin >> a >> b;

        grafo[a].pb(b);

    }



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

        if(!visited[i]){

            dfs(i);

        }

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

    }



    cout<<sol;







    return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include<iomanip>

#include <algorithm>

#include <map>

#include <vector>

#include<queue>

#include<math.h>

#include<cmath>

#include<sstream>

#include<set>

#include <map>

#include<string.h>

#include<sstream>

#include<stack>

#include<unordered_map>

#include <iostream>

#include <stdio.h>

#include <ctype.h>

#include <cstdio>

#include <cstdlib>

#define ll long long

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

#define arr2dof vector  vector<vector<int>>dp(N,vector<int>(2, inf));

using namespace std;

const int N = 2e5 + 5, inf = 1e9+7 ;

const double ep = 0.0000000001;

const double pi = 3.14159265359;

const long long inff= 1e18;

vector < vector<int>>graph;

int n, m,a,b;

int dp[100005];

bool visited[100005];

void dfs(int node) {

	visited[node] = true;

	for (int child : graph[node]) {

		if (!visited[child]) 

		dfs(child);

		

		

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

		

	}

}





int main()

{

	

	cin >> n>>m;

	graph.resize(max(n,m) + 5);

	

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

		cin >> a >> b;

		graph[a].push_back(b);

	

	}

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

		if (!visited[i])

			dfs(i);

	}

	int ans = 0;

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

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

	}

	cout << ans;

	return 0;

}

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

using namespace std;

const int N = 1e5 + 25, M = 1e6 + 25, oo = 1e9, mod = 1e9 + 7;

const long long OO = 1e18+25;



int n, m,u,v, mx, mem[N];

vector <int> g[N];



int dp(int p)

{

    int &ret = mem[p];

    if(ret != 0) return ret;

    for(int to : g[p])

        ret = max(ret, dp(to)+1);

    return ret;

}



int main()

{

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

    while(m--)

    {

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

        g[u].push_back(v);

    }

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

    {

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

    }

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

    return 0;

}

	     		 					   	 	 								 	

// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include<iomanip>

#include <algorithm>

#include <map>

#include <vector>

#include<queue>

#include<math.h>

#include<cmath>

#include<sstream>

#include<set>

#include <map>

#include<string.h>

#include<sstream>

#include<stack>

#include<unordered_map>

#include <iostream>

#include <stdio.h>

#include <ctype.h>

#include <cstdio>

#include <cstdlib>

#define ll long long

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

#define arr2dof vector  vector<vector<int>>dp(N,vector<int>(2, inf));

using namespace std;

const int N = 2e5 + 5, inf = 1e9+7 ;

const double ep = 0.0000000001;

const double pi = 3.14159265359;

const long long inff= 1e18;

vector < vector<int>>graph;

int n, m,a,b;

int dp[100005];

bool visited[100005];

void dfs(int node) {

	visited[node] = true;

	for (int child : graph[node]) {

		if (!visited[child]) 

		dfs(child);

		

		

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

		

	}

}





int main()

{

	

	cin >> n>>m;

	graph.resize(max(n,m) + 5);

	

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

		cin >> a >> b;

		graph[a].push_back(b);

	

	}

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

		if (!visited[i])

			dfs(i);

	}

	int ans = 0;

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

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

	}

	cout << ans;

	return 0;

}

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

using namespace std;

#define ll long long

#define ull unsigned long long

#define mst(a, b) memset((a), (b), sizeof(a))

#define mp(a, b) make_pair(a, b)

#define pi acos(-1)

#define pii pair<int, int>

#define pb push_back

const int INF = 0x3f3f3f3f;

const double eps = 1e-10;

const int maxn = 1e5 + 7;

const int maxm = 5e5 + 10;

const int mod = 1e9 + 7;

vector<int> s[maxn];

int vis[maxn];

int dp[maxn];

int main()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

    mst(vis, 0);

    mst(dp, 0);

    queue<int> q;

    int n, m;

    cin >> n >> m;

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

    {

        int x, y;

        cin >> x >> y;

        vis[y]++;

        s[x].pb(y);

    }

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

    {

        if (!vis[i])

            q.push(i);

    }

    while (!q.empty())

    {

        int now = q.front();

        q.pop();

        int len = s[now].size();

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

        {

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

            vis[s[now][i]]--;

            if (vis[s[now][i]] == 0)

                q.push(s[now][i]);

        }

    }

    int ans = 0;

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

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

    cout << ans << endl;

    return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include<iomanip>

#include <algorithm>

#include <map>

#include <vector>

#include<queue>

#include<math.h>

#include<cmath>

#include<sstream>

#include<set>

#include <map>

#include<string.h>

#include<sstream>

#include<stack>

#include<unordered_map>

#include <iostream>

#include <stdio.h>

#include <ctype.h>

#include <cstdio>

#include <cstdlib>

#define ll long long

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

#define arr2dof vector  vector<vector<int>>dp(N,vector<int>(2, inf));

using namespace std;

const int N = 2e5 + 5, inf = 1e9+7 ;

const double ep = 0.0000000001;

const double pi = 3.14159265359;

const long long inff= 1e18;

vector < vector<int>>graph;

int n, m,a,b;

int dp[100005];

bool visited[100005];

void dfs(int node) {

	visited[node] = true;

	for (int child : graph[node]) {

		if (!visited[child]) 

		dfs(child);

		

		

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

		

	}

}





int main()

{

	

	cin >> n>>m;

	graph.resize(max(n,m) + 5);

	

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

		cin >> a >> b;

		graph[a].push_back(b);

	

	}

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

		if (!visited[i])

			dfs(i);

	}

	int ans = 0;

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

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

	}

	cout << ans;

	return 0;

}

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



using namespace std;



#define el				'\n'

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

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

#define clr(v, d)		memset(v, d, sizeof(v))



double const EPS = 1e-8, PI = acos(-1);

const int N = 1e5 + 9, M = 50 + 9, OO = (int) 1e9 + 1;

const long long MOD = 1e9 + 7;



typedef long long ll;



void OUTPUT() {

	cout << fixed << setprecision(12);

	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

}



void INPUT() {

#ifndef ONLINE_JUDGE

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

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

#endif

	cout << fixed << setprecision(0);

//	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

}



int n, m, x, y, vis[N], ans;

vector<vector<int>> edges(N);



int DFS(int node) {

	if (vis[node] != -1)

		return vis[node];

	vis[node] = 0;

	for (auto child : edges[node]) {

		DFS(child);

		vis[node] = max(vis[node], vis[child] + 1);

	}

	return 0;

}



int main() {

//	INPUT();

	OUTPUT();

	clr(vis, -1);

	cin >> n >> m;

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

		cin >> x >> y;

		edges[x].push_back(y);

	}

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

		DFS(j);

	}

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

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

	}

	cout << ans;



	return 0;



}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include<iomanip>

#include <algorithm>

#include <map>

#include <vector>

#include<queue>

#include<math.h>

#include<cmath>

#include<sstream>

#include<set>

#include <map>

#include<string.h>

#include<sstream>

#include<stack>

#include<unordered_map>

#include <iostream>

#include <stdio.h>

#include <ctype.h>

#include <cstdio>

#include <cstdlib>

#define ll long long

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

#define arr2dof vector  vector<vector<int>>dp(N,vector<int>(2, inf));

using namespace std;

const int N = 2e5 + 5, inf = 1e9+7 ;

const double ep = 0.0000000001;

const double pi = 3.14159265359;

const long long inff= 1e18;

vector < vector<int>>graph;

int n, m,a,b;

int dp[100005];

bool visited[100005];

void dfs(int node) {

	visited[node] = true;

	for (int child : graph[node]) {

		if (!visited[child]) 

		dfs(child);

		

		

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

		

	}

}





int main()

{

	

	cin >> n>>m;

	graph.resize(max(n,m) + 5);

	

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

		cin >> a >> b;

		graph[a].push_back(b);

	

	}

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

		if (!visited[i])

			dfs(i);

	}

	int ans = 0;

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

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

	}

	cout << ans;

	return 0;

}

// Fastest known solution for this problem: