stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<iostream>

#include<queue>

#include<vector>

#define ii pair<int,int>

#define iii pair<int,ii> 

using namespace std;

int v,e,a,b;

vector<int> adjl[110000];

int vis[110000];

int memo[110000];

int start = 0;

int dp(int nodes){

//	cout<<nodes<<"\n";

	int sz = adjl[nodes].size();

	if(sz == 0) return 0;

	if(memo[nodes]!=-1) return memo[nodes];

	int ret = 0;

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

//		cout<<" visit "<<adjl[nodes][i]<<"\n";

		ret = max(ret, dp(adjl[nodes][i]) + 1);

	}

//	cout<<"\n";

	return memo[nodes] = ret;

}





int main(){

	cin>>v>>e;

	for(int i = 1;i<=v;i++) adjl[0].push_back(i);

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

		cin>>a>>b;

		adjl[a].push_back(b);

	}

	int ans = 0;

	for(int i = 0;i<=v;i++) memo[i] = -1;

	ans = dp(0) -1 ;

	cout<<ans<<"\n";

//	for(int i = 0;i<=v;i++) cout<<memo[i]<<" ";cout<<"\n";

//	for(int i = 0;i<=v;i++) ans = max(ans,)

	return 0;

}

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

#include <iostream>



using namespace std;



const int MAXN = 100010;



int n, m;



struct edge{

	int ne, to;

}e[MAXN];

int fir[MAXN], num = 0, d[MAXN];

inline void join(int a, int b)

{

	e[++num].ne = fir[a];

	fir[a] = num;

	e[num].to = b;

}



int f[MAXN];

int q[MAXN], h = 1, t = 0;



inline void topo()

{

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

		if(!d[i]) q[++t] = i;

	while(h <= t)

	{

		int u = q[h++];

		for(int i=fir[u];i;i=e[i].ne)

		{

			int v = e[i].to;

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

			--d[v];

			if(!d[v]) q[++t] = v;

		}

	}

}



int main()

{

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

	for(int i=1,a,b;i<=m;i++)

		scanf("%d%d",&a,&b),join(a, b),d[b]++;

	topo();

	int ans = -1;

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

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

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

	return 0;

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

using namespace std;

const int N = 1e5 + 10;

int n, m, dp[N];

vector<int> gg[N];

int dfs(int v){

	if (gg[v].size() == 0 || dp[v] != 0){

		return dp[v];

	}

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

		int child = gg[v][i];

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

	}

	return dp[v];

}

int main(){

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

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

	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	// cout << setprecision(10) << fixed;

	cin>>n>>m;

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

		int from, to;

		cin>>from>>to;

		gg[from].push_back(to);

	}

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

		dfs(i);

	}

	int ans = 0;

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

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

	}

	cout<<ans;

}

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

#include <iostream>



using namespace std;



const int MAXN = 100010;



int n, m;



struct edge{

	int ne, to;

}e[MAXN];

int fir[MAXN], num = 0, d[MAXN];

inline void join(int a, int b)

{

	e[++num].ne = fir[a];

	fir[a] = num;

	e[num].to = b;

}



int f[MAXN];

int q[MAXN], h = 1, t = 0;



inline void topo()

{

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

		if(!d[i]) q[++t] = i;

	while(h <= t)

	{

		int u = q[h++];

		for(int i=fir[u];i;i=e[i].ne)

		{

			int v = e[i].to;

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

			--d[v];

			if(!d[v]) q[++t] = v;

		}

	}

}



int main()

{

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

	for(int i=1,a,b;i<=m;i++)

		scanf("%d%d",&a,&b),join(a, b),d[b]++;

	topo();

	int ans = -1;

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

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

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

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <queue>



using namespace std;

struct snod

{

    vector <int> v;

    int len,leg;

} nod[100005];

int n,m,i,x,y,maxi;

queue <int> q;

int main()

{

    cin>>n>>m;

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

    {

        cin>>x>>y;

        nod[x].v.push_back(y);

        nod[y].leg++;

    }

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

        if(!nod[i].leg)

        {

            q.push(i);

        }



    while(!q.empty())

    {

        int poz=q.front();

        for(int it : nod[poz].v)

        {

            nod[it].len=max(nod[it].len, nod[poz].len+1);

            nod[it].leg--;

            if(!nod[it].leg)

                q.push(it);

        }

        q.pop();

    }

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

    {

        maxi=max(maxi, nod[i].len);

    }

    cout<<maxi;

    return 0;

}


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

#include <iostream>



using namespace std;



const int MAXN = 100010;



int n, m;



struct edge{

	int ne, to;

}e[MAXN];

int fir[MAXN], num = 0, d[MAXN];

inline void join(int a, int b)

{

	e[++num].ne = fir[a];

	fir[a] = num;

	e[num].to = b;

}



int f[MAXN];

int q[MAXN], h = 1, t = 0;



inline void topo()

{

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

		if(!d[i]) q[++t] = i;

	while(h <= t)

	{

		int u = q[h++];

		for(int i=fir[u];i;i=e[i].ne)

		{

			int v = e[i].to;

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

			--d[v];

			if(!d[v]) q[++t] = v;

		}

	}

}



int main()

{

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

	for(int i=1,a,b;i<=m;i++)

		scanf("%d%d",&a,&b),join(a, b),d[b]++;

	topo();

	int ans = -1;

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

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

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

	return 0;

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

using namespace std;

int n , m;

vector<vector<int>>vi(200005);

map<int,int>mp;

int mem[200005];

bool ok[200005];

int dfs(int node){

	if(mem[node])

		return mem[node];

	for(auto it : vi[node]){

		mem[node] = max(dfs(it) + 1 , mem[node]);

	}

	return mem[node];

}

int main() {

	memset(mem,0,sizeof(mem));

	cin>>n>>m;

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

		int x , y ; cin>>x>>y;

		vi[x].push_back(y);

		mp[y]++;

	}

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

		if(!mp[i]){

			dfs(i);

		}

	}

	int ans = 0;

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

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

	cout<<ans;

	return 0;

}


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

#include <iostream>



using namespace std;



const int MAXN = 100010;



int n, m;



struct edge{

	int ne, to;

}e[MAXN];

int fir[MAXN], num = 0, d[MAXN];

inline void join(int a, int b)

{

	e[++num].ne = fir[a];

	fir[a] = num;

	e[num].to = b;

}



int f[MAXN];

int q[MAXN], h = 1, t = 0;



inline void topo()

{

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

		if(!d[i]) q[++t] = i;

	while(h <= t)

	{

		int u = q[h++];

		for(int i=fir[u];i;i=e[i].ne)

		{

			int v = e[i].to;

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

			--d[v];

			if(!d[v]) q[++t] = v;

		}

	}

}



int main()

{

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

	for(int i=1,a,b;i<=m;i++)

		scanf("%d%d",&a,&b),join(a, b),d[b]++;

	topo();

	int ans = -1;

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

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

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

	return 0;

}
// Slower C++ solution:
/*

	Author: Luis Manuel D�az Bar�n (LUISMO)

	Problem:

	Online Judge:

	Idea:

*/

#include<bits/stdc++.h>

// Types

#define ll long long

#define ull unsigned long long

// IO

#define sf scanf

#define pf printf

#define mkp make_pair

#define fi first

#define se second

#define endl "\n"



using namespace std;



typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

const ll inf = 1e16 + 3;

const int mod = 1e9 + 7;

const int lim = 2e5 + 2;



int N, M;

vector<int> adj[lim];



int dp[lim];

bool mark[lim];



int DFS(int idx)

{

    if(mark[idx])

        return dp[idx];

    // for each adjacent

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

    {

        int nxt = adj[idx][i];

        int aux = DFS(nxt);

        dp[idx] = max(dp[idx], 1 + aux);

    }

    mark[idx] = true;

    return dp[idx];

}



void solve()

{

    cin >> N >> M;

    // reading edges

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

    {

        int xi, yi;

        cin >> xi >> yi;

        adj[xi].push_back(yi);

    }

    

    int answ = 0;



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

    {

        int aux = DFS(i);

        answ = max(answ, aux);

    }



    cout << answ;

}



void fastIO()

{

	cin.sync_with_stdio(false);

	cin.tie(0);

}



void IO()

{

	if(fopen("d:\\lmo.in","r") != NULL)

	{

		freopen("d:\\lmo.in","r",stdin);

	}

	else if(fopen("/media/Beijing/lmo.in","r") != NULL)

	{

		freopen("/media/Beijing/lmo.in", "r", stdin);

	}

}



int main()

{

	IO();



	fastIO();



	solve();

}


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

author :- Mahmoud Tarek.

*******/



#include<bits/stdc++.h>



using namespace std ;



#define rg register

#define dbg(v) cerr << #v << " " << v ;

typedef long long ll ;



const int N = 1e5 + 5 ;

vector<int> adj[N] ;

int n, m, a, b ;

int dp[N] ;



int solve(int i){



   if(i != 0 && !adj[i].size()){

     return 0 ;

   }



   int & ret = dp[i] ;

   if(~ret) return ret ;

   ret = 0 ;

   if(i == 0){

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

        ret = max(ret, solve(j)) ;

   }



   for(auto j: adj[i]){

      ret = max(ret, 1 + solve(j)) ;

   }



   return ret ;

}



int main() {

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



    cin >> n >> m ;

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

        cin >> a >> b ;

        adj[a].push_back(b) ;

    }



    memset(dp, -1, sizeof dp) ;

    cout << solve(0) ;



}





/*

  Empty set of troubles.

*/
// Slower C++ solution:
#include <iostream>

#include <climits>

#include <cstring>

#include <vector>

using namespace std;

typedef long long int ll;

const ll inf = 1000000000000;

const ll maxn = 100010;

vector <ll> adj[maxn];

ll dp[maxn];



ll dfs(ll p){

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

    ll maxpath = 0;

    for(auto x: adj[p]){

        maxpath = max(maxpath,1+dfs(x));

    }

    return dp[p] = maxpath;

}

int main(){

    memset(dp,-1,sizeof dp);



    ll n,k;



    scanf("%lld %lld",&n,&k);



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

        ll a,b;

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

        adj[a].push_back(b);

    }

    ll ans = -1;

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

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

    }

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

}


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

author :- Mahmoud Tarek.

*******/



#include<bits/stdc++.h>



using namespace std ;



#define rg register

#define dbg(v) cerr << #v << " " << v ;

typedef long long ll ;



const int N = 1e5 + 5 ;

vector<int> adj[N] ;

int n, m, a, b ;

int dp[N] ;



int solve(int i){



   if(i != 0 && !adj[i].size()){

     return 0 ;

   }



   int & ret = dp[i] ;

   if(~ret) return ret ;

   ret = 0 ;

   if(i == 0){

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

        ret = max(ret, solve(j)) ;

   }



   for(auto j: adj[i]){

      ret = max(ret, 1 + solve(j)) ;

   }



   return ret ;

}



int main() {

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



    cin >> n >> m ;

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

        cin >> a >> b ;

        adj[a].push_back(b) ;

    }



    memset(dp, -1, sizeof dp) ;

    cout << solve(0) ;



}





/*

  Empty set of troubles.

*/
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <queue>



using namespace std;

struct snod

{

    vector <int> v;

    int len,leg;

} nod[100005];

int n,m,i,x,y,maxi;

queue <int> q;

int main()

{

    cin>>n>>m;

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

    {

        cin>>x>>y;

        nod[x].v.push_back(y);

        nod[y].leg++;

    }

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

        if(!nod[i].leg)

        {

            q.push(i);

        }



    while(!q.empty())

    {

        int poz=q.front();

        for(int it : nod[poz].v)

        {

            nod[it].len=max(nod[it].len, nod[poz].len+1);

            nod[it].leg--;

            if(!nod[it].leg)

                q.push(it);

        }

        q.pop();

    }

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

    {

        maxi=max(maxi, nod[i].len);

    }

    cout<<maxi;

    return 0;

}


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

author :- Mahmoud Tarek.

*******/



#include<bits/stdc++.h>



using namespace std ;



#define rg register

#define dbg(v) cerr << #v << " " << v ;

typedef long long ll ;



const int N = 1e5 + 5 ;

vector<int> adj[N] ;

int n, m, a, b ;

int dp[N] ;



int solve(int i){



   if(i != 0 && !adj[i].size()){

     return 0 ;

   }



   int & ret = dp[i] ;

   if(~ret) return ret ;

   ret = 0 ;

   if(i == 0){

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

        ret = max(ret, solve(j)) ;

   }



   for(auto j: adj[i]){

      ret = max(ret, 1 + solve(j)) ;

   }



   return ret ;

}



int main() {

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



    cin >> n >> m ;

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

        cin >> a >> b ;

        adj[a].push_back(b) ;

    }



    memset(dp, -1, sizeof dp) ;

    cout << solve(0) ;



}





/*

  Empty set of troubles.

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

using namespace std;

int n , m;

vector<vector<int>>vi(200005);

map<int,int>mp;

int mem[200005];

bool ok[200005];

int dfs(int node){

	if(mem[node])

		return mem[node];

	for(auto it : vi[node]){

		mem[node] = max(dfs(it) + 1 , mem[node]);

	}

	return mem[node];

}

int main() {

	memset(mem,0,sizeof(mem));

	cin>>n>>m;

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

		int x , y ; cin>>x>>y;

		vi[x].push_back(y);

		mp[y]++;

	}

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

		if(!mp[i]){

			dfs(i);

		}

	}

	int ans = 0;

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

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

	cout<<ans;

	return 0;

}


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

author :- Mahmoud Tarek.

*******/



#include<bits/stdc++.h>



using namespace std ;



#define rg register

#define dbg(v) cerr << #v << " " << v ;

typedef long long ll ;



const int N = 1e5 + 5 ;

vector<int> adj[N] ;

int n, m, a, b ;

int dp[N] ;



int solve(int i){



   if(i != 0 && !adj[i].size()){

     return 0 ;

   }



   int & ret = dp[i] ;

   if(~ret) return ret ;

   ret = 0 ;

   if(i == 0){

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

        ret = max(ret, solve(j)) ;

   }



   for(auto j: adj[i]){

      ret = max(ret, 1 + solve(j)) ;

   }



   return ret ;

}



int main() {

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



    cin >> n >> m ;

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

        cin >> a >> b ;

        adj[a].push_back(b) ;

    }



    memset(dp, -1, sizeof dp) ;

    cout << solve(0) ;



}





/*

  Empty set of troubles.

*/
// Slower C++ solution:
/*

	Author: Luis Manuel D�az Bar�n (LUISMO)

	Problem:

	Online Judge:

	Idea:

*/

#include<bits/stdc++.h>

// Types

#define ll long long

#define ull unsigned long long

// IO

#define sf scanf

#define pf printf

#define mkp make_pair

#define fi first

#define se second

#define endl "\n"



using namespace std;



typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

const ll inf = 1e16 + 3;

const int mod = 1e9 + 7;

const int lim = 2e5 + 2;



int N, M;

vector<int> adj[lim];



int dp[lim];

bool mark[lim];



int DFS(int idx)

{

    if(mark[idx])

        return dp[idx];

    // for each adjacent

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

    {

        int nxt = adj[idx][i];

        int aux = DFS(nxt);

        dp[idx] = max(dp[idx], 1 + aux);

    }

    mark[idx] = true;

    return dp[idx];

}



void solve()

{

    cin >> N >> M;

    // reading edges

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

    {

        int xi, yi;

        cin >> xi >> yi;

        adj[xi].push_back(yi);

    }

    

    int answ = 0;



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

    {

        int aux = DFS(i);

        answ = max(answ, aux);

    }



    cout << answ;

}



void fastIO()

{

	cin.sync_with_stdio(false);

	cin.tie(0);

}



void IO()

{

	if(fopen("d:\\lmo.in","r") != NULL)

	{

		freopen("d:\\lmo.in","r",stdin);

	}

	else if(fopen("/media/Beijing/lmo.in","r") != NULL)

	{

		freopen("/media/Beijing/lmo.in", "r", stdin);

	}

}



int main()

{

	IO();



	fastIO();



	solve();

}


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

#include <algorithm>

#include <vector>



std::vector<std::vector<int>> vec;

std::vector<int> dp;



int dfs(int node)

{

	if (vec[node].empty())

		return 0;

	if (dp[node] != -1)

		return dp[node];

	int max = 0;

	for (int i : vec[node])

	{

		int temp = dfs(i);

		dp[i] = temp;

		max = std::max(max, temp);

	}

	return max + 1;

}



int main()

{

	int n, m;

	std::cin >> n >> m;

	vec = std::vector<std::vector<int>>(n + 1);

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

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

	{

		int x, y;

		std::cin >> x >> y;

		vec[x].push_back(y);

	}

	int max = 0;

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

		max = std::max(max, dfs(i));

	std::cout << max << '\n';

	return 0;

}
// Slower C++ solution:
// È¥°É£¡Æ¤¿¨Çð! °ÑAC´ø»ØÀ´£¡

//      ¤Ø¡¡¡¡¡¡¡¡¡¡£¯|

// ¡¡¡¡/£Ü7¡¡¡¡¡¡ ¡Ï£ß/

// ¡¡ /¡¡©¦¡¡¡¡ £¯¡¡£¯								AC		AC		AC		AC

//    ©¦¡¡Z £ß,£¼¡¡£¯¡¡¡¡ /`©c						AC		AC		AC		AC

//    ©¦¡¡¡¡¡¡¡¡¡¡©c¡¡¡¡ /¡¡¡¡¡µ					AC		AC		AC		AC

// ¡¡Y¡¡¡¡¡¡¡¡¡¡`¡¡ /¡¡¡¡/  /						AC		AC		AC		AC

// ¡¡Øé¡ñ¡¡.¡¡¡ñ¡¡¡¡¡´¡¡/¡¡/						AC		AC		AC		AC

// ¡¡()¡¡ ¤Ø¡¡¡¡¡¡¡¡|¡¡£Ü¡´							AC		AC		AC		AC

// ¡¡¡¡>- ._¡¡ ¥£¡¡ ©¦ £¯£¯							AC		AC		AC		AC

// ¡¡ / ¤Ø¡¡¡¡ /¡¡/£¼| £Ü£Ü							AC		AC		AC		AC

// ¡¡ ©c_/¡¡¡¡(_£¯¡¡ ©¦£¯£¯							AC		AC		AC		AC

// ¡¡¡¡ 7¡¡¡¡¡¡¡¡¡¡¡¡¡¡|£¯							AC		AC		AC		AC

// ¡¡¡¡ £¾¨Dr£þ£þ`-¨D£ß/							AC		AC		AC		AC

//**************************************Accepted*****************************************//



#include<bits/stdc++.h>



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

#define pb push_back

#define mp make_pair

#define Unique(x) x.erase(unique(all(x)),x.end());



#define CIN_FILE "input.txt"

#define COUT_FILE "output.txt"



using namespace std;



const int dx[]={-1,0,1,0};

const int dy[]={0,-1,0,1};



int Read()

{

	char c;

	c=getchar();



	int tsqua=0;



	while(c!=' '&&c!='\n')

	{

		tsqua=(((tsqua<<1)<<1)<<1)+(tsqua<<1)+(int)(c-'0');



		c=getchar();

	}



	return tsqua;

}



typedef long long ll;



int n,m;

int Deg[111111],Q[111111];

vector<int> E[111111];

int Head,Tail;

int res;

int D[111111];



int main(int argc, char const *argv[])

{

	ios::sync_with_stdio(false);

	

	cin>>n>>m;

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

	{

		int a,b;

		cin>>a>>b;

		

		E[a].pb(b);

		Deg[b]++;

	}

	

	for(int i=1;i<=n;i++)if(!Deg[i])Q[++Tail]=i;

	

	while(Head<Tail)

	{

		int x=Q[++Head];

		

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

		

		for(int i=0;i<E[x].size();i++)Deg[E[x][i]]--;

		

		for(int i=0;i<E[x].size();i++)D[E[x][i]]=max(D[E[x][i]],D[x]+1);

		

		for(int i=0;i<E[x].size();i++)if(!Deg[E[x][i]])Q[++Tail]=E[x][i];

	}

	

	cout<<res;

	

	//printf("Time used = %.12f",(double)(clock())/CLOCKS_PER_SEC);

	return 0;

}

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

#include <algorithm>

#include <vector>



std::vector<std::vector<int>> vec;

std::vector<int> dp;



int dfs(int node)

{

	if (vec[node].empty())

		return 0;

	if (dp[node] != -1)

		return dp[node];

	int max = 0;

	for (int i : vec[node])

	{

		int temp = dfs(i);

		dp[i] = temp;

		max = std::max(max, temp);

	}

	return max + 1;

}



int main()

{

	int n, m;

	std::cin >> n >> m;

	vec = std::vector<std::vector<int>>(n + 1);

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

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

	{

		int x, y;

		std::cin >> x >> y;

		vec[x].push_back(y);

	}

	int max = 0;

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

		max = std::max(max, dfs(i));

	std::cout << max << '\n';

	return 0;

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

using namespace std;

#define ALL(x) (x).begin(),(x).end()

#define uniq(x) (x).erase(unique(ALL(x)),(x).end())

#define SORT(x) sort(ALL(x))

#define REV(x) reverse(ALL(x))

#define foreach(it,x) for(__typeof((x).begin()) it=(x).begin();it!=(x).end();it++)

#define debug(x) cerr<<#x<<"="<<(x)<<endl

#define gett() cerr<<"Time:"<<clock()<<"ms."<<endl

#define ri(x) scanf("%d",&x)

#define rl(x) scanf("%lld",&x)

#define rlcfpoj(x) scanf("%I64d",&x)

#define pi(x) printf("%d",x)

#define pl(x) printf("%lld",x)

#define plcfpoj(x) printf("%I64d",x)

#define lfd() printf("\n")

#define sp() printf(" ")

#define inrep(x) int x;scanf("%d",&x);while(x--)

#define testbit(mask,i) (((mask)>>(i))&1)

#define setbit(mask,i) ((mask)|(1<<i))

#define delbit(mask,i) ((mask)^(1<<i))

int n,m,u,v;

vector<int> ga[100100];

int deg[100100];

int dp[100100];

int main(){

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

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

	ios::sync_with_stdio(false);

	cin.tie(NULL);

	cout.tie(NULL);

	cin>>n>>m;

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

		cin>>u>>v;

		ga[u].push_back(v);

		deg[v]++;

	}

	stack<int> s;

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

		if(deg[i]==0){

			s.push(i);

		} 

	}

	while(s.size()){

		int x=s.top();

		s.pop();

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

			int y=ga[x][i];

			deg[y]--;

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

			if(deg[y]==0){

				s.push(y);

			}

		} 

	}

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

	return 0;

}


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

#include <algorithm>

#include <vector>



std::vector<std::vector<int>> vec;

std::vector<int> dp;



int dfs(int node)

{

	if (vec[node].empty())

		return 0;

	if (dp[node] != -1)

		return dp[node];

	int max = 0;

	for (int i : vec[node])

	{

		int temp = dfs(i);

		dp[i] = temp;

		max = std::max(max, temp);

	}

	return max + 1;

}



int main()

{

	int n, m;

	std::cin >> n >> m;

	vec = std::vector<std::vector<int>>(n + 1);

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

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

	{

		int x, y;

		std::cin >> x >> y;

		vec[x].push_back(y);

	}

	int max = 0;

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

		max = std::max(max, dfs(i));

	std::cout << max << '\n';

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <climits>

#include <cstring>

#include <vector>

using namespace std;

typedef long long int ll;

const ll inf = 1000000000000;

const ll maxn = 100010;

vector <ll> adj[maxn];

ll dp[maxn];



ll dfs(ll p){

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

    ll maxpath = 0;

    for(auto x: adj[p]){

        maxpath = max(maxpath,1+dfs(x));

    }

    return dp[p] = maxpath;

}

int main(){

    memset(dp,-1,sizeof dp);



    ll n,k;



    scanf("%lld %lld",&n,&k);



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

        ll a,b;

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

        adj[a].push_back(b);

    }

    ll ans = -1;

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

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

    }

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

}


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

#include <algorithm>

#include <vector>



std::vector<std::vector<int>> vec;

std::vector<int> dp;



int dfs(int node)

{

	if (vec[node].empty())

		return 0;

	if (dp[node] != -1)

		return dp[node];

	int max = 0;

	for (int i : vec[node])

	{

		int temp = dfs(i);

		dp[i] = temp;

		max = std::max(max, temp);

	}

	return max + 1;

}



int main()

{

	int n, m;

	std::cin >> n >> m;

	vec = std::vector<std::vector<int>>(n + 1);

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

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

	{

		int x, y;

		std::cin >> x >> y;

		vec[x].push_back(y);

	}

	int max = 0;

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

		max = std::max(max, dfs(i));

	std::cout << max << '\n';

	return 0;

}