stablegradients/pie-gem5-pairs huggingface dataset:
// 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 dp[100100];

int n,m;

vector<int> ga[100100];

int u,v;

int d(int x){

	if(dp[x]!=-1)

		return dp[x];

	int &res=dp[x];

	res=0;

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

		int y=ga[x][i];

		res=max(res,d(y)+1);

	}

	return res;

}

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

	}

	int res=0;

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

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

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

	}

	cout<<res<<endl;

	return 0;

}


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

using namespace std;

int ans,n,m,a[100010],b[100010],dp[100010];

vector < int > adj[100010];

bool visit[100010];

int dfs(int x)

{

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

	dp[x] = 1;

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

	{

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

	}

	return dp[x];

}

int main()

{

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

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

	{

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

		adj[a[i]].push_back(b[i]);

	}

	for(int i=1;i<=n;i++) dp[i] = -1;

	ans = 1;

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

	{

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

	}

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

	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 dp[100100];

int n,m;

vector<int> ga[100100];

int u,v;

int d(int x){

	if(dp[x]!=-1)

		return dp[x];

	int &res=dp[x];

	res=0;

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

		int y=ga[x][i];

		res=max(res,d(y)+1);

	}

	return res;

}

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

	}

	int res=0;

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

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

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

	}

	cout<<res<<endl;

	return 0;

}


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

using namespace std;

#define db(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<'\n'

const int N = 1e5;

vector<int> adj[N+9];

int vis[N+9], mxdist[N+9];



int dfs(int r) {

	if(vis[r]) return mxdist[r];

	vis[r]=1;

	int res=0;

	for(int x: adj[r]) {

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

	}

	return mxdist[r] = res;

}

int main(){

	ios_base::sync_with_stdio(0);

	int a,b,n,m,T,cas=0;

	cin>>n>>m;

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

		cin>>a>>b;

		adj[a].emplace_back(b);

	}

	int res=0;

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

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

	}

	cout<<res<<endl;

	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 dp[100100];

int n,m;

vector<int> ga[100100];

int u,v;

int d(int x){

	if(dp[x]!=-1)

		return dp[x];

	int &res=dp[x];

	res=0;

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

		int y=ga[x][i];

		res=max(res,d(y)+1);

	}

	return res;

}

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

	}

	int res=0;

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

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

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

	}

	cout<<res<<endl;

	return 0;

}


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

using namespace std;

const int MAXM = 100010;

int n, m, f[MAXM], w[MAXM], rd[MAXM];

struct edge{

	int next, to;

}e[MAXM];

int fir[MAXM],num=0;

void join(int a,int b)

{

	e[++num].to=b;

	e[num].next=fir[a];

	fir[a]=num;

}

void topo()

{

	queue<int> q;

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

		if(rd[i]==0)

		{

			q.push(i);

			f[i]=0;  

		}	

	while(!q.empty())

	{

		int u=q.front();

		q.pop();

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

		{

			int v=e[i].to;

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

			rd[v]--;                  

			if(rd[v]==0)q.push(v);

		} 

	}

}

int main()

{

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

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

	{

		int a,b;

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

		join(a,b); 

		rd[b]++;

	}

	topo();

	int ans=0;

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

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

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

	return 0;

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

using namespace std;

typedef long long int ll;

const int MAX=1e5 + 10;

int n,m,Sub[MAX];

vector<int>g[MAX];

bool vis[MAX];

int dfs(int root)

{

    if(vis[root])return Sub[root];

    vis[root]=1;

    int ans=0;

    for(int x:g[root]){

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

    }

    return Sub[root]=ans;

}

int main ()

{

    cin >> n >> m;

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

        int u,v;

        cin >> u >> v;

        g[u].push_back(v);

    }

    int ans=0;

    for(int i=1;i<=n;i++) if(!vis[i])ans = max(ans,dfs(i));

    cout<<ans;

    return 0;

}


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

using namespace std;

const int MAXM = 100010;

int n, m, f[MAXM], w[MAXM], rd[MAXM];

struct edge{

	int next, to;

}e[MAXM];

int fir[MAXM],num=0;

void join(int a,int b)

{

	e[++num].to=b;

	e[num].next=fir[a];

	fir[a]=num;

}

void topo()

{

	queue<int> q;

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

		if(rd[i]==0)

		{

			q.push(i);

			f[i]=0;  

		}	

	while(!q.empty())

	{

		int u=q.front();

		q.pop();

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

		{

			int v=e[i].to;

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

			rd[v]--;                  

			if(rd[v]==0)q.push(v);

		} 

	}

}

int main()

{

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

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

	{

		int a,b;

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

		join(a,b); 

		rd[b]++;

	}

	topo();

	int ans=0;

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

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

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

	return 0;

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

using namespace std;



#define MX 100005

#define ll long long



vector < int > G[MX];

vector < int > topsort;

bool vis[MX];

ll dp[MX];



void dfs(int n){

    vis[n] = 1;

    for (int i = 0; i < G[n].size(); i++){

        int nxt = G[n][i];

        if (!vis[nxt])

            dfs(nxt);

    }

    topsort.push_back(n);

}



void solve(){

    for (int x = 0; x < topsort.size(); x++){

        int cur = topsort[x];

        if (G[cur].size() == 0){

            dp[cur] = 0;

        }

        else{

            ll mx = 0;

            for (int i = 0; i < G[cur].size(); i++){

                int nxt = G[cur][i];

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

            }

            dp[cur] = mx + 1;

        }

    }





}



int main()

{

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

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

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

        G[u].push_back(v);

    }



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

        if (!vis[i])

            dfs(i);

    }

    solve();

    ll res = 0;

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

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



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

    return 0;

}




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

using namespace std;

const int MAXM = 100010;

int n, m, f[MAXM], w[MAXM], rd[MAXM];

struct edge{

	int next, to;

}e[MAXM];

int fir[MAXM],num=0;

void join(int a,int b)

{

	e[++num].to=b;

	e[num].next=fir[a];

	fir[a]=num;

}

void topo()

{

	queue<int> q;

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

		if(rd[i]==0)

		{

			q.push(i);

			f[i]=0;  

		}	

	while(!q.empty())

	{

		int u=q.front();

		q.pop();

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

		{

			int v=e[i].to;

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

			rd[v]--;                  

			if(rd[v]==0)q.push(v);

		} 

	}

}

int main()

{

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

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

	{

		int a,b;

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

		join(a,b); 

		rd[b]++;

	}

	topo();

	int ans=0;

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

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

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

	return 0;

}
// Slower C++ solution:
// PUJI TUHAN !!! YES

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

using namespace std;

const int MAXM = 100010;

int n, m, f[MAXM], w[MAXM], rd[MAXM];

struct edge{

	int next, to;

}e[MAXM];

int fir[MAXM],num=0;

void join(int a,int b)

{

	e[++num].to=b;

	e[num].next=fir[a];

	fir[a]=num;

}

void topo()

{

	queue<int> q;

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

		if(rd[i]==0)

		{

			q.push(i);

			f[i]=0;  

		}	

	while(!q.empty())

	{

		int u=q.front();

		q.pop();

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

		{

			int v=e[i].to;

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

			rd[v]--;                  

			if(rd[v]==0)q.push(v);

		} 

	}

}

int main()

{

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

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

	{

		int a,b;

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

		join(a,b); 

		rd[b]++;

	}

	topo();

	int ans=0;

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

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

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

	return 0;

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

using namespace std;

int ans,n,m,a[100010],b[100010],dp[100010];

vector < int > adj[100010];

bool visit[100010];

int dfs(int x)

{

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

	dp[x] = 1;

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

	{

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

	}

	return dp[x];

}

int main()

{

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

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

	{

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

		adj[a[i]].push_back(b[i]);

	}

	for(int i=1;i<=n;i++) dp[i] = -1;

	ans = 1;

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

	{

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

	}

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

	return 0;

}

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

using namespace std;

const int MAXM = 100010;

int n, m, f[MAXM], w[MAXM], rd[MAXM];

struct edge{

	int next, to;

}e[MAXM];

int fir[MAXM],num=0;

void join(int a,int b)

{

	e[++num].to=b;

	e[num].next=fir[a];

	fir[a]=num;

}

void topo()

{

	queue<int> q;

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

		if(rd[i]==0)

		{

			q.push(i);

			f[i]=0;  

		}	

	while(!q.empty())

	{

		int u=q.front();

		q.pop();

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

		{

			int v=e[i].to;

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

			rd[v]--;                  

			if(rd[v]==0)q.push(v);

		} 

	}

}

int main()

{

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

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

	{

		int a,b;

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

		join(a,b); 

		rd[b]++;

	}

	topo();

	int ans=0;

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

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

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

	return 0;

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

using namespace std;

#define db(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<'\n'

const int N = 1e5;

vector<int> adj[N+9];

int vis[N+9], mxdist[N+9];



int dfs(int r) {

	if(vis[r]) return mxdist[r];

	vis[r]=1;

	int res=0;

	for(int x: adj[r]) {

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

	}

	return mxdist[r] = res;

}

int main(){

	ios_base::sync_with_stdio(0);

	int a,b,n,m,T,cas=0;

	cin>>n>>m;

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

		cin>>a>>b;

		adj[a].emplace_back(b);

	}

	int res=0;

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

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

	}

	cout<<res<<endl;

	return 0;

}

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

using namespace std;

const int MAXM = 100010;

int n, m, f[MAXM], w[MAXM], rd[MAXM];

struct edge{

	int next, to;

}e[MAXM];

int fir[MAXM],num=0;

void join(int a,int b)

{

	e[++num].to=b;

	e[num].next=fir[a];

	fir[a]=num;

}

void topo()

{

	queue<int> q;

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

		if(rd[i]==0)

		{

			q.push(i);

			f[i]=0;  

		}	

	while(!q.empty())

	{

		int u=q.front();

		q.pop();

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

		{

			int v=e[i].to;

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

			rd[v]--;                  

			if(rd[v]==0)q.push(v);

		} 

	}

}

int main()

{

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

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

	{

		int a,b;

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

		join(a,b); 

		rd[b]++;

	}

	topo();

	int ans=0;

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

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

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

	return 0;

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



using namespace std;

 

typedef long long ll;

typedef long double ld;

typedef unsigned long long ull;

 

#define nl '\n'

 

#define y1 aza_ibagaliev

 

#define f first

#define s second

	

#define ed end()

#define bg begin()

#define rbg rbegin()

 

#define rv reverse

#define mp make_pair

#define pb push_back

#define ppb pop_back

#define ppf pop_front

 

#define sz size()

#define all(x) x.bg, x.ed

 

#define pll pair < ll, ll >

#define pii pair < int, int >

 

#define sqr(x) ((x) * 1ll * (x))

#define sqrd(x) ((x) * 1.0 * (x))

 

#define speed ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)

 

#define rnl cout << "----------------------------------------" << nl

 

#define bit __builtin_popcount

 

inline ll bip(ll x, ll n, ll mod){ll res=1;while(n){if(n & 1){res=(res*x)%mod;}x=(x*x)%mod;n>>=1;}return res;}

        	

const int ppr = 257;

const ll INF = 2e18;

const int inf = 2e9;

const int mod = 1e9 + 7;

const int N = 1e5 + 123;

const ld pi = 3.1741592653589793238462643;

 

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

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



int n, m, dp[N], ans, cnt[N], gr[N];

vector<int>g[N],ord;

bool u[N];



void top(int v) {

	u[v] = 1;

	for(int to : g[v]) 

		if(!u[to]) top(to);

	ord.pb(v);

}



void dfs(int v) {

	u[v] = 1;

	for(int to : g[v])

		if(!u[to]) dfs(to);

}



main() {             	

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

//  freopen(".out", "w", stdout);



//	srand(time(NULL));



//	speed;



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



	while(m--) {

		int x, y;

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

		g[x].pb(y);

		gr[y]++;

	}



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

		if(!u[i]) top(i);

            

	rv(all(ord));



	queue<int>q;



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

		if(!gr[i]) q.push(i);



	while(!q.empty()) {

		int v = q.front();

		q.pop();



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



		for(int to : g[v]) {

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

			cnt[to]++;

			if(cnt[to] == gr[to]) q.push(to);

		}

	}



	cout << ans;



    return 0;                                        

}


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

using namespace std;

const int MAXM = 100010;

int n, m, f[MAXM], w[MAXM], rd[MAXM];

struct edge{

	int next, to;

}e[MAXM];

int fir[MAXM],num=0;

void join(int a,int b)

{

	e[++num].to=b;

	e[num].next=fir[a];

	fir[a]=num;

}

void topo()

{

	queue<int> q;

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

		if(rd[i]==0)

		{

			q.push(i);

			f[i]=0;  

		}	

	while(!q.empty())

	{

		int u=q.front();

		q.pop();

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

		{

			int v=e[i].to;

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

			rd[v]--;                  

			if(rd[v]==0)q.push(v);

		} 

	}

}

int main()

{

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

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

	{

		int a,b;

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

		join(a,b); 

		rd[b]++;

	}

	topo();

	int ans=0;

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

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

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

	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 dp[100100];

int n,m;

vector<int> ga[100100];

int u,v;

int d(int x){

	if(dp[x]!=-1)

		return dp[x];

	int &res=dp[x];

	res=0;

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

		int y=ga[x][i];

		res=max(res,d(y)+1);

	}

	return res;

}

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

	}

	int res=0;

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

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

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

	}

	cout<<res<<endl;

	return 0;

}


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

#include<iostream>

#include<cstring>

#include<algorithm>

#include<vector>

#include<queue>



using namespace std;

const int maxn = 1e5 + 5;



vector<int>vc[maxn];

queue<int> que;



int in[maxn], sum[maxn];

int n, m, ans;





int main(){

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

	int u, v;

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

		scanf("%d %d", &u, &v); //u -> v

		vc[u].push_back(v);

		in[v]++;

	}

	int p = 0;

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

		if(!in[i]) 

			que.push(i);

	}

	int x;

	while(!que.empty()){

		x = que.front();

		que.pop();

		int len = vc[x].size();

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

			int y = vc[x][i];

			in[y]--;

			if(!in[y]) {

				que.push(y);

				sum[y] = sum[x] + 1;

			}

		}

	}

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

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

	}

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

}
// 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 dp[100100];

int n,m;

vector<int> ga[100100];

int u,v;

int d(int x){

	if(dp[x]!=-1)

		return dp[x];

	int &res=dp[x];

	res=0;

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

		int y=ga[x][i];

		res=max(res,d(y)+1);

	}

	return res;

}

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

	}

	int res=0;

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

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

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

	}

	cout<<res<<endl;

	return 0;

}


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

using namespace std;



#define ll long long

#define pb push_back

#define mp make_pair

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

#define f first

#define se second

#define lb lower_bound

#define ub upper_bound

#define pii pair<int, int>

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



const int N = 1e5 + 144, mod = 1e9 + 7, inf = 1e9 + 7;

int n, m, dp[N];

vector <int> g[N];

bool was[N];



ll bp(ll x, ll y){

    if(y == 0)

        return 1;

    if(y & 1)

        return (x * bp(x, y - 1));

    ll z = bp(x, y / 2);

    return (z * z) % mod;

}



void dfs(int x){

    was[x] = true;

    for(auto to: g[x]){

        if(!was[to])

            dfs(to);

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

    }

}



int main(){

    boost;

    cin >> n >> m;

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

        int x, y;

        cin >> x >> y;

        g[x].pb(y);

    }

    int ans = 0;

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

        if(!was[i])

            dfs(i);

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

    }

    cout << ans;

    return 0;

}