// Slower C++ solution:


#include <bits/stdc++.h>

#define inf INFINITY

#define file freopen( "input.txt" , "r" , stdin) ; freopen( "output.txt" , "w" , stdout) ;

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

#define _3102_ main()

#define endl '\n'

typedef long long ll;

typedef unsigned long long ull;

typedef long double ld;

using namespace std;

const int N = 1e5 + 100;

const ll MX = 1e18;

const ll mod = 1e9 + 7;

const double eps = 1e-9 ;

int n , m , dp[N] ;

vector < int > adj[N] ; 



int solve( int node ){

    //cout << node << endl ; 

    if ( dp[node] != -1 ) return dp[node] ;

    int maxi = 0 ; 

    for ( auto j : adj[node]){

        maxi = max ( maxi , solve(j) + 1 ) ;

    }

    return dp[node] = maxi ; 

} 



int _3102_{

	Gamed

    cin >> n >> m ; 

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

        int u , v ; 

        cin >> u >> v ;

        adj[v].push_back(u) ; 

    }

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

    //    cout << i << ": " ; 

    //    for ( auto j : adj[i] ){

    //        cout << j << " " ;

    //    }

    //    cout << endl ; 

    //}

    memset ( dp , -1 , sizeof dp ) ;

 

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

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

            //cout << "--" << i << "--" << endl  ;

            solve (i) ;

            //cout << "------\n";

            //for ( int j = 1 ; j <= n ; j ++ ) cout << dp[j] << " " ;

            //cout << "\n------\n" ;  

        }  

    }

    int ans= 0 ; 

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

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

    }

    cout << ans << endl ; 

    return 0;

}




// Faster C++ solution for the same problem (measured speedup: 1.1113826661076829x):
#pragma region

#include <algorithm>

#include <cstring>

#include <iostream>

#include <map>

#include <queue>

#include <stack>

#include <string>

#include <vector>

typedef long long ll;

#define tr t[root]

#define lson t[root << 1]

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

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

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

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

template <typename T>

void read(T &x) {

    x = 0;

    char ch = getchar();

    ll f = 1;

    while (!isdigit(ch)) {

        if (ch == '-') f *= -1;

        ch = getchar();

    }

    while (isdigit(ch)) {

        x = x * 10 + ch - 48;

        ch = getchar();

    }

    x *= f;

}

using namespace std;

/*

 *                                                     __----~~~~~~~~~~~------___

 *                                    .  .   ~~//====......          __--~ ~~

 *                    -.            \_|//     |||\\  ~~~~~~::::... /~

 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-

 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~

 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /

 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /

 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /

 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\

 *           '         ~-|      /|    |-~\~~       __--~~

 *                       |-~~-_/ |    |   ~\_   _-~            /\

 *                            /  \     \__   \/~                \__

 *                        _--~ _/ | .-~~____--~-/                  ~~==.

 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||

 *                                  -_     ~\      ~~---l__i__i__i--~~_/

 *                                  _-~-__   ~)  \--______________--~~

 *                                //.-~~~-~_--~- |-------~~~~~~~~

 *                                       //.-~~~--\

 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 */



#pragma endregion

const int maxn = 1e5 + 5;

int n, m;

vector<int> g[maxn];

int dp[maxn], in[maxn];

int main() {

    IO;

    cin >> n >> m;

    while (m--) {

        int x, y;

        cin >> x >> y;

        g[x].push_back(y);

        in[y]++;

    }

    queue<int> q;

    rep(i, 1, n) if (!in[i]) q.push(i);

    int ans = 0, sz = q.size();

    while (q.size()) {

        int now = q.front();

        q.pop();

        for (auto nex : g[now]) {

            in[nex]--;

            if (!in[nex])

                q.push(nex);

        }

        --sz;

        if (!sz) {

            sz = q.size();

            ans++;

        }

    }

    cout << ans - 1 << endl;

}