stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



const int maxn = 1e5 + 10;



vector<int> adj[maxn];

int dp[maxn];

int ans = -1;



int dfs(int u)

{

    if (dp[u] != -1)

        return dp[u];

    int ans = 0;

    for(auto elem : adj[u]){

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

    }

    return dp[u] = ans;

}



int main()

{

    int n, m, x, y;

    cin >> n >> m;

    memset(dp, -1, sizeof dp);

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

        cin >> x >> y;

        adj[x].push_back(y);

    }

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

        if (dp[i] == -1){

            dfs(i);

        }

    }

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

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

    }

    cout << ans;

    return 0;

}


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



using namespace std;

const int maxn = 1e5 + 5;

vector<int> adj[maxn];

int dp[maxn];



int dfs(int u){

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

    dp[u] = 0;

    for (auto v : adj[u]){

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

    }

    return dp[u];

}



int main()

{

    int n, m;

    cin >> n >> m;

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

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

        int x, y;

        cin >> x >> y;

        adj[x].push_back(y);

    }

    int ans = 0;

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

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

    }

    cout << ans;

    return 0;

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

typedef long long int ll;

using namespace std;

const ll mod=1e9+7;

ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

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



vector<ll>graph[100005];

vector<ll>deg(100005,0);

vector<ll>dp(100005,0);

queue<ll>q;



int main(){

    ios::sync_with_stdio(false);

    cin.tie(0);

    cout.tie(0);

    ll n,m;

    cin>>n>>m;

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

        ll a,b;

        cin>>a>>b;

        graph[a].push_back(b);

        deg[b]++;

    }

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

        if(deg[i]==0){

            q.push(i);

        }

    }

    while(!q.empty()){

        ll tete=q.front();

        q.pop();

        vector<ll>::iterator it=graph[tete].begin();

        for(it;it!=graph[tete].end();it++){

            dp[*it]=max(dp[*it],dp[tete]+1);

            deg[*it]--;

            if(deg[*it]==0)q.push(*it);

        }

    }

    ll res=0;

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

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

    }

    cout<<res<<endl;

    return 0;

    }


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

typedef long long int ll;

typedef long double ld;

using namespace std;

const ll mod=1e9+7;

const ll inf = (ll)1e17;

const ld eps = 1e-12;

const ld PI = 3.14159265358979323846;

ll mul(ll a, ll b, ll m = mod) { return (ll)(a * b) % m;}

ll add(ll a, ll b, ll m = mod) { a += b; if(a >= m) a -= m; if(a < 0) a += m; return a;}

ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

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



int n,m;

const int N=100005;

vector<int>graph[N];

int deg[100005];

int dp[100005];



int main(){

    ios::sync_with_stdio(false);

    cin.tie(0);

    cout.tie(0);

    cin>>n>>m;

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

        int a,b;

        cin>>a>>b;

        deg[b]++;

        graph[a].push_back(b);

    }

    queue<int>q;

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

        if(deg[i]==0)q.push(i);

    }

    while(!q.empty()){

        int tete=q.front();

        q.pop();

        for(int i=0;i<graph[tete].size();i++){

            int qq=graph[tete][i];

            deg[qq]--;

            dp[qq]=max(dp[qq],dp[tete]+1);

            if(deg[qq]==0)q.push(qq);

        }

    }

    int res=0;

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

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

    }

    cout<<res<<endl;



    return 0;

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

#define EQ(x, y) (abs(x - y) < EPS)

typedef long long ll;

using namespace std;



const int N = 1e5 + 1;

int dp[N];

int n, m;

vector<vector<int>> g; // directed



int dfs(int node){

	if (dp[node] != -1)

		return dp[node];

	dp[node] = 0;

	for (auto &x : g[node]){

		if (dp[x] != -1){

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

		}

		else {

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

		}

	}

	return dp[node];

}



int main(){

	ios_base::sync_with_stdio(0);

	cin.tie(0);

	cout.tie(0);

	cout.precision(10);



	cin >> n >> m;

	g.resize(n + 1);

	for (int i = 0; i < m; ++i){ // from x to y

		int x, y;

		cin >> x >> y;

		g[x].push_back(y);

	}

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

	

	int mx = -1;

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

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

	}

	cout << mx << '\n';

	return 0;

}

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



using namespace std;



vector<vector<int>> g;

vector<int> dp;



void solve(int u) {

  if (dp[u] != -1)

    return;

  dp[u] = 0;

  for (auto v : g[u]) {

    solve(v);

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

  }

}



int main() {

  ios_base::sync_with_stdio(0);

  cin.tie(0);

  int n, m;

  cin >> n >> m;

  g.resize(n + 1);

  dp.resize(n + 1, -1);

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

    int a, b;

    cin >> a >> b;

    g[a].push_back(b);

  }

  g[0].resize(n);

  iota(g[0].begin(), g[0].end(), 1);

  solve(0);

  cout << dp[0] - 1 << '\n';

  return 0;

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

#define EQ(x, y) (abs(x - y) < EPS)

typedef long long ll;

using namespace std;



const int N = 1e5 + 1;

int dp[N];

int n, m;

vector<vector<int>> g; // directed



int dfs(int node){

	dp[node] = 0;

	for (auto &x : g[node]){

		if (dp[x] != -1){

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

		}

		else {

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

		}

	}

	return dp[node];

}



int main(){

	ios_base::sync_with_stdio(0);

	cin.tie(0);

	cout.tie(0);

	cout.precision(10);



	cin >> n >> m;

	g.resize(n + 1);

	for (int i = 0; i < m; ++i){ // from x to y

		int x, y;

		cin >> x >> y;

		g[x].push_back(y);

	}

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

	

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

		g[0].push_back(i);

	cout << dfs(0) - 1 << '\n';

	return 0;

}


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



using namespace std;



vector<vector<int>> g;

vector<int> dp;



void solve(int u) {

  if (dp[u] != -1)

    return;

  dp[u] = 0;

  for (auto v : g[u]) {

    solve(v);

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

  }

}



int main() {

  ios_base::sync_with_stdio(0);

  cin.tie(0);

  int n, m;

  cin >> n >> m;

  g.resize(n + 1);

  dp.resize(n + 1, -1);

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

    int a, b;

    cin >> a >> b;

    g[a].push_back(b);

  }

  g[0].resize(n);

  iota(g[0].begin(), g[0].end(), 1);

  solve(0);

  cout << dp[0] - 1 << '\n';

  return 0;

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

#include <assert.h>

#include <cmath>

#include <iostream>

#include <iomanip>

#include <list>

#include <memory.h>

#include <stack>

#include <string>

#include <time.h>

#include <vector>



using namespace std;



const int N = 1e5 + 1;

vector<int> g[N];

bool vis[N];

int dp[N];



int main()

{

	ios_base::sync_with_stdio(false);

	cin.tie(nullptr);



#ifdef _DEBUG

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

#endif



	int n, m;

	cin >> n >> m;

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

		int x, y;

		cin >> x >> y;

		g[x].push_back(y);

	}



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

		g[0].push_back(i);

	

	stack<int> st;

	st.push(0);



	while (!st.empty()) {

		int u = st.top();

		if (vis[u]) {

			st.pop();

			for (auto& v : g[u])

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

		}

		else {

			vis[u] = true;

			for (auto& v : g[u]) {

				if (!vis[v]);

					st.push(v);

			}

		}

	}



	cout << dp[0] - 1 << '\n';



	return 0;

}

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



using namespace std;



vector<vector<int>> g;

vector<int> dp;



void solve(int u) {

  if (dp[u] != -1)

    return;

  dp[u] = 0;

  for (auto v : g[u]) {

    solve(v);

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

  }

}



int main() {

  ios_base::sync_with_stdio(0);

  cin.tie(0);

  int n, m;

  cin >> n >> m;

  g.resize(n + 1);

  dp.resize(n + 1, -1);

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

    int a, b;

    cin >> a >> b;

    g[a].push_back(b);

  }

  g[0].resize(n);

  iota(g[0].begin(), g[0].end(), 1);

  solve(0);

  cout << dp[0] - 1 << '\n';

  return 0;

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

using namespace std;

const int N=1e5+5;

int dp[N],ans=-1;

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

vector<int>vf[N],vb[N],e,v[N];

bool f[N];

int dfs(int now)

{

	if(dp[now]==-1){

		if(v[now].empty())

		{

			dp[now]=0;

			return dp[now];

		}

		int res=-1;

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

			res=max(res,dfs(v[now][i])+1);

		dp[now]=res;

		return res;

	}

	else

		return dp[now];

}

int main()

{

	std::ios::sync_with_stdio(false);

	cin>>n>>m;

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

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

	{

		cin>>x[i]>>y[i];

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

		f[y[i]]=true;

	}

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

		if(!f[i])

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

	cout<<ans<<endl;

	return 0;

}

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

#define pb push_back

using namespace std;

const int N=1e5+5;

int n,m,dp[N],in[N],ans=-1;

vector<int>v[N];

bool notroot[N];

int dfs(int now)

{

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

	if(v[now].empty())return 0;

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

	{

		int to=v[now][i];

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

	}

	return dp[now];

}

int main()

{

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

	cin>>n>>m;

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

	{

		int a,b;

		cin>>a>>b;

		a--,b--;

		v[a].pb(b);

		notroot[b]=true;

	}

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

		if(!notroot[i])

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

	cout<<ans<<endl; 

	return 0;

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

using namespace std;

const int N=1e5+5;

int dp[N],ans=-1;

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

vector<int>vf[N],vb[N],e,v[N];

bool f[N];

int dfs(int now)

{

	if(dp[now]==-1){

		if(v[now].empty())

		{

			dp[now]=0;

			return dp[now];

		}

		int res=-1;

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

			res=max(res,dfs(v[now][i])+1);

		dp[now]=res;

		return res;

	}

	else

		return dp[now];

}

int main()

{

	std::ios::sync_with_stdio(false);

	cin>>n>>m;

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

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

	{

		cin>>x[i]>>y[i];

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

		f[y[i]]=true;

	}

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

		if(!f[i])

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

	cout<<ans<<endl;

	return 0;

}

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

using namespace std;

const int N=1e5+5;

queue<int>q;

int deg[N],n,m,ans,dist[N];

vector<int>v[N];

int main()

{

	cin>>n>>m;

	while(m--)

	{

		int a,b;

		cin>>a>>b;

		a--,b--;

		v[a].push_back(b);

		deg[b]++;

	}

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

		if(!deg[i])

			q.push(i);

	while(!q.empty())

	{

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

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

		{

			int to=v[now][i];

			dist[to]=max(dist[now]+1,dist[to]);

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

			deg[to]--;

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

		}

	}

	cout<<ans<<endl;

	return 0;

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

#define pb push_back

using namespace std;

const int N=1e5+5;

int n,m,dp[N],in[N],ans=-1;

vector<int>v[N];

bool notroot[N];

int dfs(int now)

{

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

	if(v[now].empty())return 0;

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

	{

		int to=v[now][i];

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

	}

	return dp[now];

}

int main()

{

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

	cin>>n>>m;

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

	{

		int a,b;

		cin>>a>>b;

		a--,b--;

		v[a].pb(b);

		notroot[b]=true;

	}

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

		if(!notroot[i])

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

	cout<<ans<<endl; 

	return 0;

}

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

using namespace std;

const int N=1e5+5;

queue<int>q;

int deg[N],n,m,ans,dist[N];

vector<int>v[N];

int main()

{

	cin>>n>>m;

	while(m--)

	{

		int a,b;

		cin>>a>>b;

		a--,b--;

		v[a].push_back(b);

		deg[b]++;

	}

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

		if(!deg[i])

			q.push(i);

	while(!q.empty())

	{

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

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

		{

			int to=v[now][i];

			dist[to]=max(dist[now]+1,dist[to]);

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

			deg[to]--;

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

		}

	}

	cout<<ans<<endl;

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

using namespace std;

#define maxn 100005

int tot=0,t[maxn],nxt[maxn],hd[maxn],dp[maxn];

inline void add(int u,int v){t[++tot]=v;nxt[tot]=hd[u];hd[u]=tot;}

inline int d(int u){

	if(!dp[u]) for(int i=hd[u];i;i=nxt[i]) dp[u]=max(dp[u],d(t[i])+1);

	return dp[u];

}

int main(){

	int n,m,u,v,ans=0;

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

	for(int i=0;i<m;i++){scanf("%d%d",&u,&v);add(u,v);}

	for(int i=1;i<=n;i++) ans=max(ans,d(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.8252922809320271x):
#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;

}
// 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.4916730918269105x):
#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);

}
// 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.2399714313765962x):
#include<set>

#include<map>

#include<cmath>

#include<ctime>

#include<queue>

#include<stack>

#include<cstdio>

#include<string>

#include<vector>

#include<random>

#include<cstdlib>

#include<cstring>

#include<iomanip>

#include<iostream>

#include<algorithm>

#include<unordered_map>

#define endl "\n"

#define fi first

#define se second

#define db double

#define gcd __gcd

#define pb push_back

#define mp make_pair

#define lowbit(x) (x & (-x))

#define PII  pair<int, int> 

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

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

#define rep(i, a, b) for(__typeof(b) i = a; i <= (b); i++)

#define Rep(i, a, b) for(__typeof(a) i = a; i >= (b); i--)

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

template<class T> inline T qmin(T a, T b) { return a < b ? a : b; }

template<class T> inline T qmax(T a, T b) { return a > b ? a : b; }

typedef long long ll;

typedef unsigned long long ull;

const db eps = 1e-9;

const db PI = acos(-1);

const int inf = 0x3f3f3f3f;

const int mod = (int)1e9 + 7;

const int maxn = (int)1e5 + 5;//remember to modify it, No RE or MLE

const ll INF = 0x3f3f3f3f3f3f3f3f;

using namespace std;

ll qpow(ll x, ll y) { ll ret = 1; for( ; y; y >>= 1, x = (x * x) % mod) if(y & 1) ret = (ret * x) % mod; return ret; }



inline int read(){

	char ch = getchar();

	int x = 0, f = 1;

	while(ch < '0' || ch > '9'){

		if(ch == '-') f = -1;

		ch = getchar();

	}

	while('0' <= ch && ch <= '9'){

		x = x * 10 + ch - '0';

		ch = getchar();

	}

	return x * f;

}



int n, m;

vector<int> G[maxn];

int dp[maxn], ind[maxn];



void dfs(int u){

	for(int v : G[u]){

		if(!dp[v]){

			dfs(v);

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

		} else {

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

		}

	}

}



int main()

{

	n = read(), m = read();

	rep(i, 1, m) {

		int u = read(), v = read();

		G[u].pb(v);

		ind[v]++;

	}

	rep(i, 1, n){

		if(!ind[i]){

			dfs(i);

		}

	}

	printf("%d\n", *max_element(dp, dp + n + 1));

	return 0;

}