// Slower C++ solution:
// È¥°É£¡Æ¤¿¨Çð! °ÑAC´ø»ØÀ´£¡

//      ¤Ø¡¡¡¡¡¡¡¡¡¡£¯|

// ¡¡¡¡/£Ü7¡¡¡¡¡¡ ¡Ï£ß/

// ¡¡ /¡¡©¦¡¡¡¡ £¯¡¡£¯								AC		AC		AC		AC

//    ©¦¡¡Z £ß,£¼¡¡£¯¡¡¡¡ /`©c						AC		AC		AC		AC

//    ©¦¡¡¡¡¡¡¡¡¡¡©c¡¡¡¡ /¡¡¡¡¡µ					AC		AC		AC		AC

// ¡¡Y¡¡¡¡¡¡¡¡¡¡`¡¡ /¡¡¡¡/  /						AC		AC		AC		AC

// ¡¡Øé¡ñ¡¡.¡¡¡ñ¡¡¡¡¡´¡¡/¡¡/						AC		AC		AC		AC

// ¡¡()¡¡ ¤Ø¡¡¡¡¡¡¡¡|¡¡£Ü¡´							AC		AC		AC		AC

// ¡¡¡¡>- ._¡¡ ¥£¡¡ ©¦ £¯£¯							AC		AC		AC		AC

// ¡¡ / ¤Ø¡¡¡¡ /¡¡/£¼| £Ü£Ü							AC		AC		AC		AC

// ¡¡ ©c_/¡¡¡¡(_£¯¡¡ ©¦£¯£¯							AC		AC		AC		AC

// ¡¡¡¡ 7¡¡¡¡¡¡¡¡¡¡¡¡¡¡|£¯							AC		AC		AC		AC

// ¡¡¡¡ £¾¨Dr£þ£þ`-¨D£ß/							AC		AC		AC		AC

//**************************************Accepted*****************************************//



#include<bits/stdc++.h>



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

#define pb push_back

#define mp make_pair

#define Unique(x) x.erase(unique(all(x)),x.end());



#define CIN_FILE "input.txt"

#define COUT_FILE "output.txt"



using namespace std;



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

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



int Read()

{

	char c;

	c=getchar();



	int tsqua=0;



	while(c!=' '&&c!='\n')

	{

		tsqua=(((tsqua<<1)<<1)<<1)+(tsqua<<1)+(int)(c-'0');



		c=getchar();

	}



	return tsqua;

}



typedef long long ll;



int n,m;

int Deg[111111],Q[111111];

vector<int> E[111111];

int Head,Tail;

int res;

int D[111111];



int main(int argc, char const *argv[])

{

	ios::sync_with_stdio(false);

	

	cin>>n>>m;

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

	{

		int a,b;

		cin>>a>>b;

		

		E[a].pb(b);

		Deg[b]++;

	}

	

	for(int i=1;i<=n;i++)if(!Deg[i])Q[++Tail]=i;

	

	while(Head<Tail)

	{

		int x=Q[++Head];

		

		res=max(res,D[x]);

		

		for(int i=0;i<E[x].size();i++)Deg[E[x][i]]--;

		

		for(int i=0;i<E[x].size();i++)D[E[x][i]]=max(D[E[x][i]],D[x]+1);

		

		for(int i=0;i<E[x].size();i++)if(!Deg[E[x][i]])Q[++Tail]=E[x][i];

	}

	

	cout<<res;

	

	//printf("Time used = %.12f",(double)(clock())/CLOCKS_PER_SEC);

	return 0;

}

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



using namespace std;



#define F first

#define S second

#define modulo ll (1e9 + 7)



typedef long long ll;

typedef pair<int,int> pii;



void init(){

    cin.tie(0);

    cin.sync_with_stdio(0);

}



const int N = 1e5 + 9, M = 1e6 + 9, OO = 0x3f3f3f3f;

const ll llOO = 0x3f3f3f3f3f3f3f3f;





#define neig(a, u, e, v) for(int v, e = (a).head[u] ; ~e and (v = (a).to[e], 1) ; e = (a).nxt[e])



struct Adj {

	int head[N], nxt[M], to[M], ne, n;

	void init(int n) {

		memset(head, -1, n * sizeof(head[0]));

		ne = 0;

		this->n = n;

	}

	void addEdge(int f, int t) {

		nxt[ne] = head[f];

		to[ne] = t;

		head[f] = ne++;

	}

	void addBiEdge(int f, int t) {

		addEdge(f, t);

		addEdge(t, f);

	}

	int addNode() {

		head[++n] = 0;

		return n;

	}

} adj;







int dp[N];



int dfs(int u){

    int &ret = dp[u];

    if(~ret)    return dp[u];



    ret = 0;

    neig(adj, u, e, v)

        ret = max(ret, dfs(v));



    ret++;



    return ret;

}





int n, m, u, v;



void go(int tc){

    cin >> n >> m;

    adj.init(n);

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

        cin >> u >> v;  u--, v--;

        adj.addEdge(u, v);

    }



    memset(dp, -1, sizeof dp);



    int ans = 0;

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

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



    cout << ans - 1;

}



int main(){

    init();



    int t, tc = 1;  t = 1;//cin >> t;

    while(t--)  go(tc++);



}