// Problem : G - Longest Path
// Contest : AtCoder - Educational DP Contest
// URL : https://atcoder.jp/contests/dp/tasks/dp_g
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#define XOX
#define fast ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;

#define int long long
#define re return
#define beg() begin()
#define cont continue
#define ldb long double
#define db double

#define br break
#define fr first
#define se second
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define mkp make_pair

#define pi pair<int,int>
#define pll pair<ll,ll>
#define pdb pair<db,db>
#define pldb pair<ldb,ldb>

#define vi vector<int>
#define vll vector<ll>
#define vdb vector<db>
#define vldb vector<ldb>
#define vpi vector< pi >
#define vpll vector< pll >

#define mi map<int,int>
#define mdb map<db,db>
#define mldb map<ldb,ldb>

#define si set<int>
#define sdb set<db>
#define sldb set<ldb>

#define test int t; cin>>t; while(t--)
#define scan() int n; cin>>n; int a[n]; for(int i=0;i<n;i++) cin>>a[i]
#define scan2() int n,k; cin>>n>>k; int a[n]; for(int i=0;i<n;i++) cin>>a[i]
#define print(a,n) for(int i=0;i<n;i++) cout<<a[i]<<' '
#define mem(a,v) memset(a,v,sizeof(a))
#define srt(v) sort(v.begin(),v.end())
#define rev(s) reverse(s.begin(),s.end())
#define cn(x) cout<<x<<"\n"
#define cs(x) cout<<x<<" "
#define c(x) cout<<x
#define all(v) v.begin(),v.end()

#define forr(i,a,b) for (int i = (a); i < (b); ++i)
#define rrof(i,a,b) for (int i = (b)-1; i >= (a); --i)


const int MOD = 1e9+7;
const ldb PI = 4*atan((ldb)1);
const int INF = 1e18;
const int NINF = -1e18;

int get_hash(string s){
	int N=1000001;
	int base[N],A=11,MD=1110111110111;
	base[0]=1;

	forr(i,1,N)
	base[i]=(base[i-1]*A)%MD;

	int hs=0;
	forr(i,0,s.size()){
		hs+=(s[i]*base[i]);
		hs%=MD;
	}

	re hs;
}

int power(int a,int n){
	int res=1;

	while(n){
		if(n%2)
		res*=a;
		a*=a;
		n/=2;
	}

	return res;
}

vector<string> vec_splitter(string s) {
	s += ',';
	vector<string> res;
	while(!s.empty()) {
		res.push_back(s.substr(0, s.find(',')));
		s = s.substr(s.find(',') + 1);
	}
	return res;
}
void debug_out(
	vector<string> __attribute__ ((unused)) args,
	__attribute__ ((unused)) int idx,
	__attribute__ ((unused)) int LINE_NUM) { cerr << endl; }
	template <typename Head, typename... Tail>
	void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
	if(idx > 0) cerr << ", "; else cerr << "Line(" << LINE_NUM << ") ";
	stringstream ss; ss << H;
	cerr << args[idx] << " = " << ss.str();
	debug_out(args, idx + 1, LINE_NUM, T...);
}
#ifdef XOX
#define debug(...) debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif

bool bl[200001]={false};
int dp[200001];
vi v[2000001];
int solve(int s){
	bl[s]=true;
	
	if(dp[s]!=-1)
	return dp[s];
	
	int ans=0;
	forr(i,0,v[s].size())
	ans=max(ans,solve(v[s][i])+1);
	
	dp[s]=ans;
	return ans;
}

int32_t main(){
	fast;
	
	int n,m;
	cin>>n>>m;

	forr(i,0,m){
		int x,y;
		cin>>x>>y;
		v[y].pb(x);
	}
	
	memset(dp,-1,sizeof(dp));
	forr(i,1,n+1){
		if(bl[i]==false)
		solve(i);
	}
	
	int maxa=0;
	forr(i,1,n+1){
		if(dp[i]>maxa)
		maxa=dp[i];
	}
	
	cout<<maxa;
	re 0;
}

Measured memory_bytes: 56448