stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):


#include<bits/stdc++.h>

using namespace std;



const int N = 1e5 + 5;

typedef long long ll;

vector<int> adj[N];

bool visited[N]={};

int nodesNum;

int dp[N];

void dfs(int node){

    if(visited[node])

        return;

visited[node]=1;

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

        int child=adj[node][i];

    if(!visited[child])

    dfs(child);

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

}

}







int main()

{

   int edges;

   cin >> nodesNum >> edges;

   while (edges--)

   {

       int x, y;

       cin >> x >> y;

       adj[x].push_back(y);

   }

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

        if(!visited[i])

      dfs(i);

   }

   int ans=0;

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

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

   }

 cout<<ans;

   return 0;

}


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

#define eps 1e-3

#define pi acos(-1.0)

#define inf 0x3f

#define INF 0x3f3f3f3f

#define pb push_back

#define debug1 cout<<"&&";

#define debug2 cout<<"**";

#define ms(a, x) memset(a, x, sizeof(a))

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

#define for1(i, n) for(int i = 1; i <= n; ++i)

using namespace std;

typedef double db;

typedef long long ll;

typedef unsigned long long ull;

typedef pair<int, int> pii;

typedef pair<long long, int> pli;

typedef pair<long long, long long> pll;

const int mod = 1e9 + 7;

const int N = 1e5+10;

const int M = 1e6+10;

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

inline ll Pow(ll a, ll b) { ll ans = 1; for( ; b; b >>= 1) { if(b&1) ans = ans * a % mod; a = a * a % mod;} return ans;}

inline ll Mul ( ll a, ll b)  { ll lf = a * ( b >> 25ll ) % mod * ( 1LL << 25 ) % mod; ll rg = a * ( b & ( ( 1ll << 25 ) - 1 ) ) % mod; return ( lf + rg ) % mod;}

inline ll C(ll y, ll x) { ll ans = 1; if(y < 0 || x < 0 || y < x) return 0; y %= mod; if(!y || !x) return 1; for0(i, x) ans = ans * (y-i) % mod; for1(i, x) ans = ans * Pow(i, mod-2) % mod; return ans; }

//==================================================================================================================================================================//



int n, m, tot, head[N], nex[N], ver[N];

int dp[N], deg[N], ans;

queue<int> q;



void add(int x, int y) {

   ver[++tot] = y, nex[tot] = head[x], head[x] = tot;

}



int main() {

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

   for1(i, m) {

      int x, y;

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

      add(x, y);

      deg[y]++;

   }

   for1(i, n) if(!deg[i]) q.push(i);

   while(!q.empty()) {

      int x = q.front(); q.pop();

      for(int i = head[x]; i; i = nex[i]) {

         int y = ver[i]; deg[y]--;

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

         if(!deg[y]) q.push(y);

      }

   }

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

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

   return 0;

}

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

#include <set>

#include <stack>

#include <vector>

#include <map>

#include <string>

#include <string.h>

#include <cstring>

#include <queue>

#include <algorithm>

#include <math.h>



using namespace std;



typedef long long ll;





const int N = 1e5 + 5;

typedef long long ll;

vector<int> adj[N];

bool visited[N] = {};

int nodesNum;

int dp[N];

void dfs(int node) {

	if (visited[node])

		return;

	visited[node] = 1;

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

		int child = adj[node][i];

		if (!visited[child])

			dfs(child);

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

	}

}







int main()

{

	int edges;

	cin >> nodesNum >> edges;

	while (edges--)

	{

		int x, y;

		cin >> x >> y;

		adj[x].push_back(y);

	}

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

		if (!visited[i])

			dfs(i);

	}

	int ans = 0;

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

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

	}

	cout << ans;

	return 0;

}

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

#define eps 1e-3

#define pi acos(-1.0)

#define inf 0x3f

#define INF 0x3f3f3f3f

#define pb push_back

#define debug1 cout<<"&&";

#define debug2 cout<<"**";

#define ms(a, x) memset(a, x, sizeof(a))

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

#define for1(i, n) for(int i = 1; i <= n; ++i)

using namespace std;

typedef double db;

typedef long long ll;

typedef unsigned long long ull;

typedef pair<int, int> pii;

typedef pair<long long, int> pli;

typedef pair<long long, long long> pll;

const int mod = 1e9 + 7;

const int N = 1e5+10;

const int M = 1e6+10;

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

inline ll Pow(ll a, ll b) { ll ans = 1; for( ; b; b >>= 1) { if(b&1) ans = ans * a % mod; a = a * a % mod;} return ans;}

inline ll Mul ( ll a, ll b)  { ll lf = a * ( b >> 25ll ) % mod * ( 1LL << 25 ) % mod; ll rg = a * ( b & ( ( 1ll << 25 ) - 1 ) ) % mod; return ( lf + rg ) % mod;}

inline ll C(ll y, ll x) { ll ans = 1; if(y < 0 || x < 0 || y < x) return 0; y %= mod; if(!y || !x) return 1; for0(i, x) ans = ans * (y-i) % mod; for1(i, x) ans = ans * Pow(i, mod-2) % mod; return ans; }

//==================================================================================================================================================================//



int n, m, tot, head[N], nex[N], ver[N];

int dp[N], deg[N], ans;

queue<int> q;



void add(int x, int y) {

   ver[++tot] = y, nex[tot] = head[x], head[x] = tot;

}



int main() {

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

   for1(i, m) {

      int x, y;

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

      add(x, y);

      deg[y]++;

   }

   for1(i, n) if(!deg[i]) q.push(i);

   while(!q.empty()) {

      int x = q.front(); q.pop();

      for(int i = head[x]; i; i = nex[i]) {

         int y = ver[i]; deg[y]--;

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

         if(!deg[y]) q.push(y);

      }

   }

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

   printf("%d\n", 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 PII pair<int,int>

#define PSI pair<string,int>

#define PIII pair< int, pair<int,int> >

const int MaxN = 1e5+5;

vector<int> g[MaxN];

int dp[MaxN];

int N;



int dfs(int node){



    auto &ret = dp[node];

    if(ret!=-1) return ret;

    

    ret = 0;

    for(auto i: g[node])

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



    return ret;

}



void read(){



    int edge;

    memset(dp, -1, sizeof dp);

    cin>>N>>edge;



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

        int u,v;

        cin>>u>>v;

        g[u].push_back(v);

    }

}



void solve(){



    read();

    int res = 0;

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

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



    cout<< res << "\n";

}





int main(){



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

    ios_base::sync_with_stdio(false);

    cin.tie(nullptr);

    solve();



    return 0;

}


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

#define eps 1e-3

#define pi acos(-1.0)

#define inf 0x3f

#define INF 0x3f3f3f3f

#define pb push_back

#define debug1 cout<<"&&";

#define debug2 cout<<"**";

#define ms(a, x) memset(a, x, sizeof(a))

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

#define for1(i, n) for(int i = 1; i <= n; ++i)

using namespace std;

typedef double db;

typedef long long ll;

typedef unsigned long long ull;

typedef pair<int, int> pii;

typedef pair<long long, int> pli;

typedef pair<long long, long long> pll;

const int mod = 1e9 + 7;

const int N = 1e5+10;

const int M = 1e6+10;

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

inline ll Pow(ll a, ll b) { ll ans = 1; for( ; b; b >>= 1) { if(b&1) ans = ans * a % mod; a = a * a % mod;} return ans;}

inline ll Mul ( ll a, ll b)  { ll lf = a * ( b >> 25ll ) % mod * ( 1LL << 25 ) % mod; ll rg = a * ( b & ( ( 1ll << 25 ) - 1 ) ) % mod; return ( lf + rg ) % mod;}

inline ll C(ll y, ll x) { ll ans = 1; if(y < 0 || x < 0 || y < x) return 0; y %= mod; if(!y || !x) return 1; for0(i, x) ans = ans * (y-i) % mod; for1(i, x) ans = ans * Pow(i, mod-2) % mod; return ans; }

//==================================================================================================================================================================//



int n, m, tot, head[N], nex[N], ver[N];

int dp[N], deg[N], ans;

queue<int> q;



void add(int x, int y) {

   ver[++tot] = y, nex[tot] = head[x], head[x] = tot;

}



int main() {

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

   for1(i, m) {

      int x, y;

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

      add(x, y);

      deg[y]++;

   }

   for1(i, n) if(!deg[i]) q.push(i);

   while(!q.empty()) {

      int x = q.front(); q.pop();

      for(int i = head[x]; i; i = nex[i]) {

         int y = ver[i]; deg[y]--;

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

         if(!deg[y]) q.push(y);

      }

   }

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

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

   return 0;

}

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

#include<stdio.h>

#include<cstring>

#include<queue>

#include<vector>

#define ll long long

#define pi acos(-1.0)

#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1e5+5;

int out[maxn];

vector<int>vec[maxn];

queue<int>q1,q2;



int main(){

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

	int u, v;

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

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

		vec[v].push_back(u);

		out[u]++;

	}

	int ans = 0, ok = 0;

	for(int i = 1; i <= n; i++) if(out[i] == 0) q1.push(i);

	while(1){

		ok = 1;

		while(!q1.empty()){

			int now = q1.front(); q1.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q2.push(x);

			}

			ok = 0;

		}

		if(!ok){

			ans++;

			continue;

		}

		while(!q2.empty()){

			int now = q2.front(); q2.pop();

			for(int i = 0; i < vec[now].size(); i++){

				int x = vec[now][i];

				out[x]--;

				if(!out[x]) q1.push(x);

			}

			ok = 0;

		}

		if(ok) break;

		ans++;

	}

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

	return 0;

}

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

#define eps 1e-3

#define pi acos(-1.0)

#define inf 0x3f

#define INF 0x3f3f3f3f

#define pb push_back

#define debug1 cout<<"&&";

#define debug2 cout<<"**";

#define ms(a, x) memset(a, x, sizeof(a))

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

#define for1(i, n) for(int i = 1; i <= n; ++i)

using namespace std;

typedef double db;

typedef long long ll;

typedef unsigned long long ull;

typedef pair<int, int> pii;

typedef pair<long long, int> pli;

typedef pair<long long, long long> pll;

const int mod = 1e9 + 7;

const int N = 1e5+10;

const int M = 1e6+10;

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

inline ll Pow(ll a, ll b) { ll ans = 1; for( ; b; b >>= 1) { if(b&1) ans = ans * a % mod; a = a * a % mod;} return ans;}

inline ll Mul ( ll a, ll b)  { ll lf = a * ( b >> 25ll ) % mod * ( 1LL << 25 ) % mod; ll rg = a * ( b & ( ( 1ll << 25 ) - 1 ) ) % mod; return ( lf + rg ) % mod;}

inline ll C(ll y, ll x) { ll ans = 1; if(y < 0 || x < 0 || y < x) return 0; y %= mod; if(!y || !x) return 1; for0(i, x) ans = ans * (y-i) % mod; for1(i, x) ans = ans * Pow(i, mod-2) % mod; return ans; }

//==================================================================================================================================================================//



int n, m, tot, head[N], nex[N], ver[N];

int dp[N], deg[N], ans;

queue<int> q;



void add(int x, int y) {

   ver[++tot] = y, nex[tot] = head[x], head[x] = tot;

}



int main() {

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

   for1(i, m) {

      int x, y;

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

      add(x, y);

      deg[y]++;

   }

   for1(i, n) if(!deg[i]) q.push(i);

   while(!q.empty()) {

      int x = q.front(); q.pop();

      for(int i = head[x]; i; i = nex[i]) {

         int y = ver[i]; deg[y]--;

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

         if(!deg[y]) q.push(y);

      }

   }

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

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

   return 0;

}

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

#include <queue>

#include <vector>

#include <cstring>

#include <algorithm>

using namespace std;



const int maxn=1e5+10;

int dp[maxn],in[maxn];

vector<int > G[maxn];

int main()

{

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

    return 0;

}

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

#define eps 1e-3

#define pi acos(-1.0)

#define inf 0x3f

#define INF 0x3f3f3f3f

#define pb push_back

#define debug1 cout<<"&&";

#define debug2 cout<<"**";

#define ms(a, x) memset(a, x, sizeof(a))

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

#define for1(i, n) for(int i = 1; i <= n; ++i)

using namespace std;

typedef double db;

typedef long long ll;

typedef unsigned long long ull;

typedef pair<int, int> pii;

typedef pair<long long, int> pli;

typedef pair<long long, long long> pll;

const int mod = 1e9 + 7;

const int N = 1e5+10;

const int M = 1e6+10;

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

inline ll Pow(ll a, ll b) { ll ans = 1; for( ; b; b >>= 1) { if(b&1) ans = ans * a % mod; a = a * a % mod;} return ans;}

inline ll Mul ( ll a, ll b)  { ll lf = a * ( b >> 25ll ) % mod * ( 1LL << 25 ) % mod; ll rg = a * ( b & ( ( 1ll << 25 ) - 1 ) ) % mod; return ( lf + rg ) % mod;}

inline ll C(ll y, ll x) { ll ans = 1; if(y < 0 || x < 0 || y < x) return 0; y %= mod; if(!y || !x) return 1; for0(i, x) ans = ans * (y-i) % mod; for1(i, x) ans = ans * Pow(i, mod-2) % mod; return ans; }

//==================================================================================================================================================================//



int n, m, tot, head[N], nex[N], ver[N];

int dp[N], deg[N], ans;

queue<int> q;



void add(int x, int y) {

   ver[++tot] = y, nex[tot] = head[x], head[x] = tot;

}



int main() {

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

   for1(i, m) {

      int x, y;

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

      add(x, y);

      deg[y]++;

   }

   for1(i, n) if(!deg[i]) q.push(i);

   while(!q.empty()) {

      int x = q.front(); q.pop();

      for(int i = head[x]; i; i = nex[i]) {

         int y = ver[i]; deg[y]--;

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

         if(!deg[y]) q.push(y);

      }

   }

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

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

   return 0;

}

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

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

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

اذكر الله

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

****/



#include <bits/stdc++.h>

#define ll long long

#define endl "\n"

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



using namespace std;



inline int D()

{

    int t;

    scanf("%d",&t);

    return t;

}

inline ll llD()

{

    ll t;

    scanf("%lld",&t);

    return t;

}



const ll OO=-1e18;

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

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

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

const int N = 1e6+1;

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

bool valid(int x,int y)

{

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

}

void init()

{

    memset(mem,-1,sizeof mem);

}

bool visited[200005];

vector <int> adj[200005];

int dfs(int s)

{

    int &ret=mem[s];

    if(~ret)return ret;

       ret=0;

      /// visited[s] = true;



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

    {

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

        {

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

        }

    }

    return ret;

}

int main()

{

    init();

    int x,y;

    cin >> n;

    cin >> m;

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

    {

        cin >> x >> y;

        adj[x].push_back(y);

    }

    int mx=0,mn=2000006;

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

    {

            cnt= dfs(i);

            mx=max(cnt,mx);

        }



    cout<<mx;

}






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

using namespace std;

using ll = long long;

using ii = pair<int,int>;



const int mx = 2e5+5;



int dist[mx];

int n, m, vis[mx];

vector<int> g[mx], tp;



void dfs(int u){

    vis[u] = 1;

    for(int v : g[u])

        if(!vis[v])

            dfs(v);

    tp.push_back(u);

}



int main(){

    cin.tie(nullptr);

    ios_base::sync_with_stdio(0);



    cin >> n >> m;

    while(m--){

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

        g[u].push_back(v);

    }



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

        dist[i] = 1;

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

    }



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

    for(int u : tp)

        for(int v : g[u])

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

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



    return 0;

}




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

using namespace std;

constexpr int MAXN = 1e5 + 7;



vector<int> from[MAXN];

int dp[MAXN];

int ans;



void dfs(int u)

{

    if (dp[u])

        return;

    for (int v : from[u]) {

        dfs(v);

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

    }

    if (dp[u] > ans)

        ans = dp[u];

}



int main()

{

    int n, m;

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

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

        int u, v;

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

        from[u].push_back(v);

    }

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

        if (!dp[i])

            dfs(i);

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

}

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

using namespace std;

constexpr int MAXN = 1e5 + 7;

constexpr int MAXM = 1e5 + 7;



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

int dp[MAXN];



int dfs(int x)

{

    if (!dp[x])

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

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

    return dp[x];

}



int main()

{

    int n, m;

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

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

        int a, b;

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

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

        u[a] = i;

    }

    int ans = 0;

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

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

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

}

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

#include<map>

#include<vector>

#include<math.h>

#define ll long long

using namespace std;



int dp[100001];

void fillarray()

{

	int i;

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

	dp[i] = -1;

}



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

{

	if(dp[i] >= 0)

	return dp[i];

	

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

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

	{

		dp[i] = 0;

		return 0;

	}

	

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

	int j,k,len,maxm = 0;

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

	{

		

		k = g[i][j];

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

		len = 1 + dfs(g , k);

		maxm = max(len , maxm);

	}

	

	dp[i] = maxm;

	return maxm;

	

}





main()

{

	int n,m;

	cin>>n>>m;

	int i,j;

	

	vector<int> g[n+1];

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

	{

		int u,v;

		cin>>u>>v;

		g[u].push_back(v);

	}

	

	fillarray();

	

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

	{

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

		dfs(g , i);

	}

	

	int maxm = 0;

	int index;

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

	{

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

		if(maxm < dp[i])

		{

			maxm = dp[i];

			index = i;

		}

	}

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

	cout<<maxm;

	

	

}

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

#include<vector>

#include<map>

#include<algorithm>

#include<math.h>



#define ll long long

using namespace std;



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

{

	if(visited[i])

	{

		return maxd[i];

	}

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

	

	visited[i] = true;

	int j,k;

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

	int h = -1;

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

	{

		k = g[i][j];

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

	}

	

	maxd[i] = 1 + h;

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

	return maxd[i];

}



main()

{

	int n,m;

	cin>>n>>m;

	int i,j;

	

	vector<int> g[n+1];

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

	{

		int u,v;

		cin>>u>>v;

		

		g[u].push_back(v);	

	}	

	

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

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

	int maxm = 0;

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

	{

		if(!visited[i])

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

	}

	

	cout<<maxm;

}

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

using namespace std;



const int maxn = 1e5 + 5;



bool visited[maxn];

int dist[maxn];

vector<int> g[maxn];

int indegree[maxn];



void dfs(int a){

    visited[a] = true;

    for(auto b : g[a]){

        dist[b] = max(dist[b] , 1 + dist[a]);

        --indegree[b];

        if(indegree[b] == 0)

            dfs(b);

    }

}



int main(){

    int n,m;

    cin>>n>>m;



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

        int a,b;

        cin>>a>>b;



        g[a].push_back(b);

        indegree[b]++;

    }



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

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

            dfs(i);

    }



    cout<<*max_element(dist,dist+maxn);

}

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



#define int long long

using namespace std;

#define maxn 100010

int n,m;

vector<int> g[maxn];

int indegree[maxn] ,dist[maxn] ;

bool visited[maxn];



void dfs(int v,int p){

    visited[v] = true;

    for(auto x: g[v]){

        if(x == p)continue;

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

        indegree[x]--;

        if(indegree[x] == 0 and !visited[x])

            dfs(x ,v);

    }

}



int32_t main() {



    cin >> n >> m;



    int a ,b;

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

        cin >> a >> b;

        g[a].push_back(b);

        indegree[b]++;

    }

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

        if(!visited[i] and indegree[i] == 0)

            dfs(i , -1);

    }

    int ans = 0;

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

        ans = max(ans,dist[j]);

    }

    cout << ans;

}




// Fastest known solution for this problem: