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

/**

*   author: j o s e m a g o

*   date:

**/

using namespace std;

#pragma GCC optimize ("Ofast")

#define f first

#define s second

#define mp make_pair

#define lb lower_bound

#define ub upper_bound

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

#define mset(a,v) memset(a,v,sizeof(a))

#define pb push_back

#define sz(x) ((int)(x).size())

#define rsz resize

#define ln "\n"



typedef double db;

typedef unsigned long long ull;

typedef long long ll;

typedef long double ld;

const ld PI = 2*acos(0.0);

const int MOD = 1000000007;

const int JJJ = 100009;



int N,A;

vector<int>grafo[JJJ];

bool visited[JJJ];

int dp[JJJ];



int sol = 0;

void dfs(int nod){

    visited[nod] = true;

    dp[nod] = -1;

    for(int i = 0;i < (int)grafo[nod].size();i++){

        int xx = grafo[nod][i];

        if(!visited[xx]){

            dfs(xx);

        }

        dp[nod] = max(dp[nod],dp[xx]);

    }

    dp[nod]++;

}







int main(){



  

    ios_base::sync_with_stdio(0); cin.tie(0);





    cin >> N >> A;

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

        int a,b;

        cin >> a >> b;

        grafo[a].pb(b);

    }



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

        if(!visited[i]){

            dfs(i);

        }

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

    }



    cout<<sol;







    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 2.5614818785587277x):
#include <iostream>

#include <algorithm>

#include <cmath>

#include <cstdlib>

#include <cstdio>

#include <cstring>

#include <iomanip>

#include <string>

#include <set>

#include <vector>

#include <queue>

#include <stack>

#include <map>

using namespace std;

#define ms(a, x) memset(a, x, sizeof(a))

#define fore(i, a, n) for (long long i = a; i < n; i++)

#define ford(i, a, n) for (long long i = n - 1; i >= a; i--)

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

#define sl(a) scanf("%lld", &a)

#define sii(a, b) scanf("%d%d", &a, &b)

#define siii(a, b, c) scanf("%d%d%d", &a, &b, &c)

#define sll(a, b) scanf("%lld%lld", &a, &b)

#define slll(a, b, c) scanf("%lld%lld%lld", &a, &b, &c)

#define debug(a) cout << a << endl

#define pr(a) printf("%d ",a)

#define endl '\n'

#define pi acos(-1.0)

#define tr t[root]

#define lson t[root << 1]

#define rson t[root << 1 | 1]

#define IO ios::sync_with_stdio(false), cin.tie(0)

#define ull unsigned long long

const double eps = 1e-8;

inline int sgn(const double &x) { return x < -eps ? -1 : x > eps; }

typedef long long ll;

const int inf=0x3f3f3f3f;

const int MAXN = 1e5 + 10;

int n,m;

struct edge{

	int to ,next;

}e[MAXN];

int head[MAXN];

int cnt,ans;

void add(int x,int y)

{

	e[cnt].to=y;

	e[cnt].next=head[x];

	head[x]=cnt;

	cnt++;

 }

int ru[MAXN],chu[MAXN],dp[MAXN];

ll dfs(int x)

{

	if(chu[x]==0) return 0;

	if(dp[x])return dp[x];

	ll ans=0;

	for(int i=head[x];~i;i=e[i].next )

	{

		ans=max(dfs(e[i].to)+1,ans);

				

	}//cout<<ans<<endl;

	

	return dp[x]=ans;

}

int main()

{

	sii(n,m);

	ms(head,-1);

	ll ans=0;

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

	{

		int x,y;

		sii(x,y);

		add(x,y);

		ru[y]++;

		chu[x]++;

	}

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

	{

		if(!ru[i])

		{

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

		}

	}

	printf("%lld\n",ans);

 }