// Slower C++ solution:
/*

██╗  ██╗ █████╗ ██████╗ ███████╗███████╗███╗   ███╗        ██╗  ██╗██╗  ██╗ █████╗ ██╗     ███████╗██████╗

██║ ██╔╝██╔══██╗██╔══██╗██╔════╝██╔════╝████╗ ████║        ██║ ██╔╝██║  ██║██╔══██╗██║     ██╔════╝██╔══██╗

█████╔╝ ███████║██████╔╝█████╗  █████╗  ██╔████╔██║        █████╔╝ ███████║███████║██║     █████╗  ██║  ██║

██╔═██╗ ██╔══██║██╔══██╗██╔══╝  ██╔══╝  ██║╚██╔╝██║        ██╔═██╗ ██╔══██║██╔══██║██║     ██╔══╝  ██║  ██║

██║  ██╗██║  ██║██║  ██║███████╗███████╗██║ ╚═╝ ██║███████╗██║  ██╗██║  ██║██║  ██║███████╗███████╗██████╔╝

╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝╚══════╝╚═╝     ╚═╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝╚══════╝╚═════╝

Believe in yourself ,( try and try and then try ), You can do it

*/

#define _CRT_SECURE_NO_WARNINGS

#include<bits/stdc++.h>

#include<unordered_map>

#define endl "\n"

#define Ceil(x,y) ((x+y-1)/y)

#define clr(arr, x) memset(arr, x, sizeof arr)

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

#define allr(s) s.rbegin(),s.rend()

#define rt(s) return cout<<s,0

#define watch(x) cout<<(#x)<<" = "<<x<<endl

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

#define OO 0x3f3f3f3f3f3f3f3fLL

const int oo = 0x3f3f3f3f, mod = 1e9 + 7;

using namespace std;

typedef long long ll;

typedef long double ld;

typedef unsigned long long ull;

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

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

void K_K(){ 

	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

}

vector<vector<int>>gr;

int dp[100005];

int dfs(int node){

	if (!sz(gr[node]))

		return 0;

	int &ret = dp[node];

	if (~ret)

		return ret;

	for (auto child : gr[node]){

		ret = max(ret, dfs(child) + 1);

	}

	return ret;

}

int main(){

	K_K();

	int n, m;

	cin >> n >> m;

	gr.resize(n + 1);

	clr(dp, -1);

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

		int u, v;

		cin >> u >> v;

		gr[u].push_back(v);

	}

	int ans = 0;

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

		dfs(i);

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

	}

	cout << ans;

}

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

#define ll          long long int

#define ld          long double

#define pb          push_back

#define mp          make_pair

#define ff          first

#define se          second

#define scan(n)     scanf("%lld", &n);

#define print(n)    printf("%lld\n", n);

#define fd(n)       fixed<<setprecision(n)

#define MAX         1000000000000000000

#define MAXN        100005

#define LOG         19

#define mod         1000000007

using namespace std;





int main(){

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    ll n,m,i,x,y,mx=0;

    cin>>n>>m;

    vector<ll> vi[n+1];

    ll deg[n+1];

    queue<ll> qe;

    vector<ll> vi1;

    memset(deg,0,sizeof(deg));

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

        cin>>x>>y;

        vi[x].pb(y);

        deg[y]++;

    }

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

        if(deg[i]==0){

            qe.push(i);

            vi1.pb(i);

        }

    }

    while(!qe.empty()){

        ll node=qe.front();

        qe.pop();

        for(auto x:vi[node]){

            deg[x]--;

            if(deg[x]==0){

                vi1.pb(x);

                qe.push(x);

            }

        }

    }

    ll dp[n+1];

    memset(dp,0,sizeof(dp));

    for(auto node:vi1){

        for(auto x:vi[node]){

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

        }

    }

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

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

    }

    cout<<mx;

}