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

#include<iomanip>

#include<cmath>

#include<string>

#include<cctype>

#include<algorithm>

#include<set>

#include<map>

#include<stack>

#include<queue>

#include<cstring>

//#include<windows.h>

//#include<time.h>

#define pb push_back

#define ppb pop_back

#define fi first

#define se second

#define mer make_pair

#define mme memset

using namespace std;



const double pie1=3.1415926;//π1

const double pie2=3.14159265358979;//π2

const double pie3=3.14159265358979323846;//π3

const int vbi=999999999;

const int vli=-vbi;

const long long vbl=999999999999999999;

const long long vll=-vbl;



typedef long long ll;

typedef pair<int,int> pii;

typedef pair<ll,ll> pll;

typedef pair<pii,int> piii;

typedef pair<pii,pii> pi4;

typedef pair<pll,ll> plll;

typedef pair<int,pii> ipii;

typedef pair<ll,pll> lpll;

typedef pair<pll,pll> pl4;

typedef vector<int> vi;

typedef vector<ll> vl;

typedef vector<pii> vpi;

typedef vector<pll> vpl;

typedef set<int> sti;

typedef set<ll> stl;

typedef set<pii> spi;

typedef set<pll> spl;

priority_queue<int> pqi;

priority_queue<ll> pql;

queue<int> qi;

queue<ll> ql;



/*void bin_v(){

	char bin[1000];

	gets(bin);

}*/



bool pss(int a){

	for(int i=2;i<=sqrt(a);i++)

		if(a%i==0)

			return false;

	return true;

}

/////////////////////////////////////////////////////////////////////////////////////////

int n,m;

vector<int> v[100010];

int d[100010];

int dp[100010];



int main(){

	//my name is Veex_WCY

	ios::sync_with_stdio(false);

	cin>>n>>m;

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

		int a,b;

		cin>>a>>b;

		v[a].pb(b);

		d[b]++;

	}

	stack<int> st;

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

		if(d[i]==0)

			st.push(i);

	while(!st.empty()){

		int x=st.top();

		st.pop();

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

			int ne=v[x][i];

			if(dp[x]+1>dp[ne])

				dp[ne]=dp[x]+1;

			d[ne]--;

			if(d[ne]==0)

				st.push(ne);

		}

	}

	int maxn=0;

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

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

	cout<<maxn;

	return 0;

}


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

#define si(a) scanf("%d", &a)

#define fore(i,a,b) for(int i = a; i < b; ++i)

using namespace std;

typedef long long ll;

typedef pair<int,int> pi;

typedef vector<int> vi;

vector<vector<int> > gr;

vi out;

vi ans;

vector<bool> visited;

vi aux;

void dfs(int u){

	visited[u] = true;

	//ans[u] = max(ans[u], val);

	fore(j,0,gr[u].size()){

		if(!visited[ gr[u][j] ])

			dfs(gr[u][j]);

		//ans[u] = max(ans[u], ans[ gr[u][j] ] + 1);

	}

	aux.push_back(u);

}

void solve(){

	int n,m;

	si(n); si(m);

	int x,y;

	gr.assign(n+1,vector<int>());

	out.assign(n+1,0);

	ans.assign(n+1,0);

	vector<pi> inv(m);

	aux.reserve(n);

	vi in(n+1);

	visited.assign(n+1,false);

	fore(i,0,m){

		si(x);si(y);

		inv[i] = pi(x,y);

		out[x]++;

		in[y]++;

	}

	fore(i,1,n+1)

		gr[i].reserve( in[i] );

	fore(i,0,m){

		x = inv[i].first;

		y = inv[i].second;

		gr[x].push_back(y);

	}

		

	fore(i,1,n+1)

		if(!visited[i])

			dfs(i);

	vi dp(n+1);

	//printf("aux: ");for(int i:aux) printf("%d ", i);printf("\n");

	for(int v: aux){

		if(gr[v].size() == 0)

			dp[v] = 0;

		else{

			int k = 0;

			for(int u: gr[v])

				k = max(k, dp[u]);

			dp[v] = k+1;

		}

	}

	int anss = 0;

	//printf("dp: ");for(int i:dp) printf("%d ", i);printf("\n");

	

	for(int i: dp)

		anss = max(anss, i);

	

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

}

int main(){

	solve();

	return 0;

}