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

#define F first

#define S second

#define T second.first

#define C second.second

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

using namespace std;

typedef long long ll;

typedef pair<int, int> pii;

typedef pair<int,pair<int,int>> piii;



const int N= 1e2+5, L = 14, OO = 0x3f3f3f3f;

const int M= 1e9+7;

const double ESP = 1e-8;



int n,m, u,v;

vector<int>adj[100005];

int dp[100005];



int solve(int u){

    int& ret = dp[u];

    if(~ret)return ret;



    ret = 0;

    for(int v: adj[u])

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



    return ret;

}



int main(){

    FIO

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

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

    cin>>n>>m;

    memset(dp, -1, sizeof dp);

    while(m--){

        cin>>u>>v;

        adj[u].push_back(v);

    }

    int ans = 0;

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

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

    }

    cout<<ans;

}


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

using namespace std;

 

#define             ll  long long

#define            ull  unsigned long long

#define            P_B  push_back

#define            M_P  make_pair

#define         DBG(x)  printf("%s %d\n", #x, x)

#define       DBGLL(x)  printf("%s %lld\n", #x, x)

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

#define         SCD(x)  scanf("%lf",&x)

#define         SCS(x)  scanf("%s",x)

#define         CLR(x)  memset(x, 0, sizeof(x))

#define        CLRN(x)  memset(x, -1, sizeof(x))

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

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

#define  FORR(i, m, n)  for(int i = m; i < n; i++)

#define     SCI2(m, n)  scanf("%d%d", &m, &n)

#define  SCI3(m, n, o)  scanf("%d%d%d",&m, &n, &o)

#define     SCD2(m, n)  scanf("%lf%lf",&m,&n)

#define  SCD3(m, n, o)  scanf("%lf%lf%lf",&m,&n,&o)

#define    SCLL2(m, n)  scanf("%lld%lld", &m, &n)

#define SCLL3(m, n, o)  scanf("%lld%lld%lld",&m, &n, &o)

#define             vi  vector<int>

#define            vii  vector<pair<int, int> >

#define            vll  vector<pair<ll, ll> >

#define            Mod  1000000007

#define            INF  1000000000

 



int n, m;

queue<int> st;

vi node[100001];

vector<bool> selected(100001, false);

vector<bool> visited(100001, false);

int maxxes[100001];



void topsort(int v)

{

	if(selected[v]) return;

	selected[v] = true;

	for(auto it : node[v]){

		if(!selected[it]){

			topsort(it);

		}

	}

	st.push(v);

}



int notdfs(int v, int cnt)

{

	// cnt++;

	visited[v] = true;

	int mx =  -1;

	// DBG(mx);

	// DBG(v);

	for(auto it : node[v]){

		// if(!visited[it]){

			mx = max(mx, maxxes[it]);

			// DBG(mx);

			// DBG(it);

		// }

	}

	maxxes[v] = mx + 1;

	return mx + 1;

}



int main()

{

	SCI2(n, m);

	FORR(i, 1, m + 1){

		int p, q;

		SCI2(p, q);

		node[p].P_B(q);

	}

	FORR(i, 1, n + 1)topsort(i);

	int max_ = 0;

	FORR(i, 1, n + 1){

		int x = st.front();

		// DBG(x);

		st.pop();

		if(!visited[x]){

			max_ = max(max_, notdfs(x, -1));

		}

	}

	// FORR(i, 1, n + 1) printf("%d ", maxxes[i]);

	// cout << endl;

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

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

#include<bits/stdc++.h>



using namespace std;



int n,m;

vector<int>v[200005];

int ans=0,c=0;

int dp[200005];

int vis[200005];

int mx=0;

void dfs(int node){

    vis[node]=1;

    for(int j=0;j<v[node].size();j++){

            if(!vis[v[node][j]])

            dfs(v[node][j]);

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

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

    }

    }





int main()

{

    cin>>n>>m;

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

        int x,y;

        cin>>x>>y;

        v[x].push_back(y);

    }

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

    if(!vis[i]){

        dfs(i);

    }

   }

   cout<<mx;



    return 0;

}


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

using namespace std;

 

#define             ll  long long

#define            ull  unsigned long long

#define            P_B  push_back

#define            M_P  make_pair

#define         DBG(x)  printf("%s %d\n", #x, x)

#define       DBGLL(x)  printf("%s %lld\n", #x, x)

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

#define         SCD(x)  scanf("%lf",&x)

#define         SCS(x)  scanf("%s",x)

#define         CLR(x)  memset(x, 0, sizeof(x))

#define        CLRN(x)  memset(x, -1, sizeof(x))

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

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

#define  FORR(i, m, n)  for(int i = m; i < n; i++)

#define     SCI2(m, n)  scanf("%d%d", &m, &n)

#define  SCI3(m, n, o)  scanf("%d%d%d",&m, &n, &o)

#define     SCD2(m, n)  scanf("%lf%lf",&m,&n)

#define  SCD3(m, n, o)  scanf("%lf%lf%lf",&m,&n,&o)

#define    SCLL2(m, n)  scanf("%lld%lld", &m, &n)

#define SCLL3(m, n, o)  scanf("%lld%lld%lld",&m, &n, &o)

#define             vi  vector<int>

#define            vii  vector<pair<int, int> >

#define            vll  vector<pair<ll, ll> >

#define            Mod  1000000007

#define            INF  1000000000

 



int n, m;

queue<int> st;

vi node[100001];

vector<bool> selected(100001, false);

vector<bool> visited(100001, false);

int maxxes[100001];



void topsort(int v)

{

	if(selected[v]) return;

	selected[v] = true;

	for(auto it : node[v]){

		if(!selected[it]){

			topsort(it);

		}

	}

	st.push(v);

}



int notdfs(int v, int cnt)

{

	// cnt++;

	visited[v] = true;

	int mx =  -1;

	// DBG(mx);

	// DBG(v);

	for(auto it : node[v]){

		// if(!visited[it]){

			mx = max(mx, maxxes[it]);

			// DBG(mx);

			// DBG(it);

		// }

	}

	maxxes[v] = mx + 1;

	return mx + 1;

}



int main()

{

	SCI2(n, m);

	FORR(i, 1, m + 1){

		int p, q;

		SCI2(p, q);

		node[p].P_B(q);

	}

	FORR(i, 1, n + 1)topsort(i);

	int max_ = 0;

	FORR(i, 1, n + 1){

		int x = st.front();

		// DBG(x);

		st.pop();

		if(!visited[x]){

			max_ = max(max_, notdfs(x, -1));

		}

	}

	// FORR(i, 1, n + 1) printf("%d ", maxxes[i]);

	// cout << endl;

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

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





using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef double dd;

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

#define endl "\n"

#define clr(n, r) memset(n,r,sizeof(n));



void fast() {

    cin.tie(0);

    cin.sync_with_stdio(0);

}



int OO = 100000000,n,m;

int dp[100009];

vector<vector<int>>edges(1e5);

int ans(int i){

    int &ret=dp[i];

    if(~ret)return ret;

    if(i==n+1||edges[i].empty())return 0;

    ret =0;

    for (int j = 0; j <edges[i].size() ; ++j) {

        ret=max (ret,1+ans(edges[i][j]));

    }

    return ret;

}







int main() {

    fast();

    cin>>n>>m;

    clr(dp,-1);

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

        int a,b;cin>>a>>b;

        edges[a].push_back(b);

    }

    int s=0;

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

     s=max(s,ans(j));

    }

    cout<<s;

}

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

using namespace std;

 

#define             ll  long long

#define            ull  unsigned long long

#define            P_B  push_back

#define            M_P  make_pair

#define         DBG(x)  printf("%s %d\n", #x, x)

#define       DBGLL(x)  printf("%s %lld\n", #x, x)

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

#define         SCD(x)  scanf("%lf",&x)

#define         SCS(x)  scanf("%s",x)

#define         CLR(x)  memset(x, 0, sizeof(x))

#define        CLRN(x)  memset(x, -1, sizeof(x))

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

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

#define  FORR(i, m, n)  for(int i = m; i < n; i++)

#define     SCI2(m, n)  scanf("%d%d", &m, &n)

#define  SCI3(m, n, o)  scanf("%d%d%d",&m, &n, &o)

#define     SCD2(m, n)  scanf("%lf%lf",&m,&n)

#define  SCD3(m, n, o)  scanf("%lf%lf%lf",&m,&n,&o)

#define    SCLL2(m, n)  scanf("%lld%lld", &m, &n)

#define SCLL3(m, n, o)  scanf("%lld%lld%lld",&m, &n, &o)

#define             vi  vector<int>

#define            vii  vector<pair<int, int> >

#define            vll  vector<pair<ll, ll> >

#define            Mod  1000000007

#define            INF  1000000000

 



int n, m;

queue<int> st;

vi node[100001];

vector<bool> selected(100001, false);

vector<bool> visited(100001, false);

int maxxes[100001];



void topsort(int v)

{

	if(selected[v]) return;

	selected[v] = true;

	for(auto it : node[v]){

		if(!selected[it]){

			topsort(it);

		}

	}

	st.push(v);

}



int notdfs(int v, int cnt)

{

	// cnt++;

	visited[v] = true;

	int mx =  -1;

	// DBG(mx);

	// DBG(v);

	for(auto it : node[v]){

		// if(!visited[it]){

			mx = max(mx, maxxes[it]);

			// DBG(mx);

			// DBG(it);

		// }

	}

	maxxes[v] = mx + 1;

	return mx + 1;

}



int main()

{

	SCI2(n, m);

	FORR(i, 1, m + 1){

		int p, q;

		SCI2(p, q);

		node[p].P_B(q);

	}

	FORR(i, 1, n + 1)topsort(i);

	int max_ = 0;

	FORR(i, 1, n + 1){

		int x = st.front();

		// DBG(x);

		st.pop();

		if(!visited[x]){

			max_ = max(max_, notdfs(x, -1));

		}

	}

	// FORR(i, 1, n + 1) printf("%d ", maxxes[i]);

	// cout << endl;

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

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

using namespace std;

const int maxn = 1e5 + 5;

vector<int>G[maxn];

queue<int> q;

int in[maxn];

int n,m;

int ans = 0;

int dp[maxn];

void topu(){

	while(!q.empty()) q.pop();

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

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

		//if(in[i] == 0) printf("%d\n",i);

	}

	while(!q.empty()){

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

		int len = G[hh].size();

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

			int tmp = G[hh][i];

			//printf("%d\n",tmp);

			in[tmp]--;

			dp[tmp] = max(dp[tmp],dp[hh] + 1);

			if(in[tmp] == 0) q.push(tmp);

		}

		//ans++;

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

	}

	return ;

}

int main(){

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

	int x,y;

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

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

		G[x].push_back(y);

		in[y]++;

	}

	topu();

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

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

	cout << ans << endl;

	return 0;

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

#define F first

#define S second

#define T second.first

#define C second.second

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

using namespace std;

typedef long long ll;

typedef pair<int, int> pii;

typedef pair<int,pair<int,int>> piii;



const int N= 1e2+5, L = 14, OO = 0x3f3f3f3f;

const int M= 1e9+7;

const double ESP = 1e-8;



int n,m, u,v;

vector<int>adj[100005];

int dp[100005];



int solve(int u){

    int& ret = dp[u];

    if(~ret)return ret;



    ret = 0;

    for(int v: adj[u])

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



    return ret;

}



int main(){

    FIO

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

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

    cin>>n>>m;

    memset(dp, -1, sizeof dp);

    while(m--){

        cin>>u>>v;

        adj[u].push_back(v);

    }

    int ans = 0;

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

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

    }

    cout<<ans;

}


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

using namespace std;

const int maxn = 1e5 + 5;

vector<int>G[maxn];

queue<int> q;

int in[maxn];

int n,m;

int ans = 0;

int dp[maxn];

void topu(){

	while(!q.empty()) q.pop();

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

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

		//if(in[i] == 0) printf("%d\n",i);

	}

	while(!q.empty()){

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

		int len = G[hh].size();

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

			int tmp = G[hh][i];

			//printf("%d\n",tmp);

			in[tmp]--;

			dp[tmp] = max(dp[tmp],dp[hh] + 1);

			if(in[tmp] == 0) q.push(tmp);

		}

		//ans++;

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

	}

	return ;

}

int main(){

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

	int x,y;

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

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

		G[x].push_back(y);

		in[y]++;

	}

	topu();

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

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

	cout << ans << endl;

	return 0;

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

#include<bits/stdc++.h>



using namespace std;



int n,m;

vector<int>v[200005];

int ans=0,c=0;

int dp[200005];

int vis[200005];

int mx=0;

void dfs(int node){

    vis[node]=1;

    for(int j=0;j<v[node].size();j++){

            if(!vis[v[node][j]])

            dfs(v[node][j]);

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

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

    }

    }





int main()

{

    cin>>n>>m;

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

        int x,y;

        cin>>x>>y;

        v[x].push_back(y);

    }

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

    if(!vis[i]){

        dfs(i);

    }

   }

   cout<<mx;



    return 0;

}


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

using namespace std;

const int maxn = 1e5 + 5;

vector<int>G[maxn];

queue<int> q;

int in[maxn];

int n,m;

int ans = 0;

int dp[maxn];

void topu(){

	while(!q.empty()) q.pop();

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

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

		//if(in[i] == 0) printf("%d\n",i);

	}

	while(!q.empty()){

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

		int len = G[hh].size();

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

			int tmp = G[hh][i];

			//printf("%d\n",tmp);

			in[tmp]--;

			dp[tmp] = max(dp[tmp],dp[hh] + 1);

			if(in[tmp] == 0) q.push(tmp);

		}

		//ans++;

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

	}

	return ;

}

int main(){

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

	int x,y;

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

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

		G[x].push_back(y);

		in[y]++;

	}

	topu();

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

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

	cout << ans << endl;

	return 0;

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





using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef double dd;

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

#define endl "\n"

#define clr(n, r) memset(n,r,sizeof(n));



void fast() {

    cin.tie(0);

    cin.sync_with_stdio(0);

}



int OO = 100000000,n,m;

int dp[100009];

vector<vector<int>>edges(1e5);

int ans(int i){

    int &ret=dp[i];

    if(~ret)return ret;

    if(i==n+1||edges[i].empty())return 0;

    ret =0;

    for (int j = 0; j <edges[i].size() ; ++j) {

        ret=max (ret,1+ans(edges[i][j]));

    }

    return ret;

}







int main() {

    fast();

    cin>>n>>m;

    clr(dp,-1);

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

        int a,b;cin>>a>>b;

        edges[a].push_back(b);

    }

    int s=0;

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

     s=max(s,ans(j));

    }

    cout<<s;

}

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

using namespace std;

const int maxn = 1e5 + 5;

vector<int>G[maxn];

queue<int> q;

int in[maxn];

int n,m;

int ans = 0;

int dp[maxn];

void topu(){

	while(!q.empty()) q.pop();

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

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

		//if(in[i] == 0) printf("%d\n",i);

	}

	while(!q.empty()){

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

		int len = G[hh].size();

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

			int tmp = G[hh][i];

			//printf("%d\n",tmp);

			in[tmp]--;

			dp[tmp] = max(dp[tmp],dp[hh] + 1);

			if(in[tmp] == 0) q.push(tmp);

		}

		//ans++;

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

	}

	return ;

}

int main(){

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

	int x,y;

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

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

		G[x].push_back(y);

		in[y]++;

	}

	topu();

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

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

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

using namespace std;

using ll = long long;

using PII = pair<int, int>;

using VI = vector<int>;



int main() {

#ifdef LOCAL_EXEC

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

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

#else

  ios_base::sync_with_stdio(false); cin.tie(NULL);

#endif



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

  vector<VI> adj(n + 1);

  while (m--) {

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

    adj[x].push_back(y);

  }



  VI dis(n + 1, -1);

  function<int(int)> get = [&](int u) {

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

    dis[u] = 0;

    for (int v: adj[u]) {

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

    }

    return dis[u];

  };



  int ans = 0;

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

    ans = max(ans, get(u));

  }

  cout << ans << endl;



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

using namespace std;

using ll = long long;

using PII = pair<int, int>;

using VI = vector<int>;



int main() {

#ifdef LOCAL_EXEC

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

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

#else

  ios_base::sync_with_stdio(false); cin.tie(NULL);

#endif



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

  vector<VI> adj(n + 1);

  while (m--) {

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

    adj[x].push_back(y);

  }



  VI dis(n + 1, -1);

  function<int(int)> get = [&](int u) {

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

    dis[u] = 0;

    for (int v: adj[u]) {

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

    }

    return dis[u];

  };



  int ans = 0;

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

    ans = max(ans, get(u));

  }

  cout << ans << endl;



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

using namespace std;

using ll = long long;

using PII = pair<int, int>;

using VI = vector<int>;



int main() {

#ifdef LOCAL_EXEC

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

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

#else

  ios_base::sync_with_stdio(false); cin.tie(NULL);

#endif



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

  vector<VI> adj(n + 1);

  while (m--) {

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

    adj[x].push_back(y);

  }



  VI dis(n + 1, -1);

  function<int(int)> get = [&](int u) {

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

    dis[u] = 0;

    for (int v: adj[u]) {

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

    }

    return dis[u];

  };



  int ans = 0;

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

    ans = max(ans, get(u));

  }

  cout << ans << endl;



  return 0;

}