// Slower C++ solution:
/*

	Author: Luis Manuel D�az Bar�n (LUISMO)

	Problem:

	Online Judge:

	Idea:

*/

#include<bits/stdc++.h>

// Types

#define ll long long

#define ull unsigned long long

// IO

#define sf scanf

#define pf printf

#define mkp make_pair

#define fi first

#define se second

#define endl "\n"



using namespace std;



typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

const ll inf = 1e16 + 3;

const int mod = 1e9 + 7;

const int lim = 2e5 + 2;



int N, M;

vector<int> adj[lim];



int dp[lim];

bool mark[lim];



int DFS(int idx)

{

    if(mark[idx])

        return dp[idx];

    // for each adjacent

    for(int i = 0; i < adj[idx].size(); i++)

    {

        int nxt = adj[idx][i];

        int aux = DFS(nxt);

        dp[idx] = max(dp[idx], 1 + aux);

    }

    mark[idx] = true;

    return dp[idx];

}



void solve()

{

    cin >> N >> M;

    // reading edges

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

    {

        int xi, yi;

        cin >> xi >> yi;

        adj[xi].push_back(yi);

    }

    

    int answ = 0;



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

    {

        int aux = DFS(i);

        answ = max(answ, aux);

    }



    cout << answ;

}



void fastIO()

{

	cin.sync_with_stdio(false);

	cin.tie(0);

}



void IO()

{

	if(fopen("d:\\lmo.in","r") != NULL)

	{

		freopen("d:\\lmo.in","r",stdin);

	}

	else if(fopen("/media/Beijing/lmo.in","r") != NULL)

	{

		freopen("/media/Beijing/lmo.in", "r", stdin);

	}

}



int main()

{

	IO();



	fastIO();



	solve();

}


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

#include<algorithm>

#include<iomanip>

#include<cmath>

#include<vector>

#include<queue>

#include<stack>

#include<set>

#include <cstdio>

#include<map>

#include<string>

#include<assert.h>

#include<unordered_map>

#include <cstring>//memset();

#define Amr_Abdelazim ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

#define pb push_back

#define pp pop_back

#define ll long long

#define ld long double

#define pll pair<ll,ll> 

#define vll vector<ll> 

#define vvll vector<vector<ll> >  

#define vpll vector<pair<ll,ll> > 

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

#define rep(i,n)   for(int i=0;i<n;i++)

#define repp(s,i,n)   for(int i=s;i<n;i++)

#define print(v) for(auto i:v)cout<<i<<" ";cout<<"\n"; 

#define mkp make_pair

#define clr(ar,v) memset(ar,v,sizeof(ar));

#define TC ll t;cin>>t;while(t--)

#define in_vec ll n;cin>>n;vll v(n);rep(i,n)cin >> v[i];

#define EPS 1e-9

using namespace std;

const int mod = 1000000007;

const int N = 1000005;

class cmp{

public:

	bool operator() (pair<ll, pll> &A, pair<ll, pll> &B){

		return A > B;

	}

};

bool by_sec(pll &A, pll &B){

	return A.second < B.second;

}

bool is(pll a, pll b){

	return !((a.first > b.second&&a.second > b.second) || (a.first < b.first&&a.second < b.first));

}

ld dist(pll p1, pll p2){

	return (ld)sqrt((ld)(p1.first - p2.first)*(p1.first - p2.first) + (ld)(p1.second - p2.second)*(p1.second - p2.second));

}

vvll vv(100000+9);

ll dp[100000 + 9];

ll path(ll n){

	if (vv[n].size() == 0)return 0;

	if (dp[n] == -1){

		ll mx = -1;

		rep(i, vv[n].size())mx = max(mx, path(vv[n][i])+1);

		dp[n] = mx;

	}

	return dp[n];

}

int main()

{

	Amr_Abdelazim

		clr(dp, -1);

		ll n, m,ans=0;

	cin >> n >> m;

	while (m--){

		ll a, b;

		cin >> a >> b;

		vv[a].push_back(b);

	}

	repp(1, i, n + 1)

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

	cout << ans << "\n";

	return 0;

}