/***************************************** START OF TEMPLATE *********************************************/
#include<bits/stdc++.h>

using namespace std;

#define  SPEED          ios:: sync_with_stdio(0);cin.tie(0);cout.tie(0);cout<<fixed;cout<<setprecision(10);
#define  randomINIT     mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
#define  foo(i,a,n)     for(ll i = (a); i <= n; i++)
#define  frr(i,a,n)     for(ll i = (a); i >= n; i--)
#define  fo(i,n)        for(ll i = 0; i < n; i++)
#define  newl           cout<<"\n";
#define  f              first
#define  s              second
#define  pb             push_back
#define  mp             make_pair
#define  sym(s)         s="#"+s+"#";
#define  all(x)         (x).begin(),(x).end()
#define  alll(x, n)     x+1, x+n+1
#define  ll             long long
#define  ld             long double
#define  pll            pair<ll,ll>
#define  vll            vector<ll>
#define  vpll           vector<pll>
#define  deb(x...)      _print(x);newl;

void _print() {cout << "";}
void __print(int x) {cout << x;}
void __print(long long x) {cout << x;}
void __print(float x) {cout << x;}
void __print(double x) {cout << x;}
void __print(long double x) {cout << x;}
void __print(const char *x) {cout << '\"' << x << '\"';}
void __print(char x) {cout << '\'' << x << '\'';}
void __print(const string &x) {cout << '\"' << x << '\"';}
template<typename T, typename V> void __print(const pair<T, V> &x) {cout << '{'; __print(x.first); cout << ','; __print(x.second); cout << '}';}
template<typename T> void __print(const T &x) {int f = 0; cout << '{'; for (auto &i : x) cout << (f++ ? ", " : ""), __print(i); cout << "}";}
template<typename T, typename... V> void _print(T t, V... v) {__print(t); if (sizeof...(v)) cout << ", "; _print(v...);}
template<typename T1, typename T2> void mset(T1 &x, T2 val) {memset(x, val, sizeof(x));}
template<typename T1, typename T2> void mset(T1 &a, ll n, T2 v) {foo(i, 0, n)a[i] = v;}
template<typename T1, typename T2> void mset(T1 &a, ll n, ll m , T2 v) {foo(i, 0, n)foo(j, 0, m)a[i][j] = v;}
template<typename T1>void OUT(T1 a[], ll n, ll m) {foo(i, 1, n) {foo(j, 1, m) {cout << a[i][j] << " ";} newl;}}
void OUT(ll a[], ll n) {foo(i, 1, n) cout << a[i] << " "; newl;}
void OUT(pll a[], ll n) {foo(i, 1, n) __print(a[i]); newl;}

const ld   PI    =  3.14159265358979323846;
const ll   MOD   =  1e+9 + 7;
const ll   INF   =  LLONG_MAX;
const int  INFi  =  INT_MAX;
const ll   N     =  2e+5 + 8;

vll adj[N]; ll vis[N];
ll dx4[] = {0, 1, 0, -1}, dy4[] = {1, 0, -1, 0};

ll test_cases = 1; randomINIT;

/*********************************************************************************************************/
/***************************************** VARIABLE DECLARATIONS *****************************************/
ll n, m, u, v, dp[N];

/***************************************** FUNCTION IMPLEMENTATIONS **************************************/
ll dfs(ll v, ll p) {
    if (dp[v] != -1) return dp[v];
    ll ans = 0;
    for (auto to : adj[v]) {
        if (to != p) {
            ans = max(ans, dfs(to, v) + 1);
        }
    }
    return dp[v] = ans;
}


/***************************************** START OF MAIN FUNCTION ****************************************/
void MAIN(ll tc) {
    cin >> n >> m;
    foo(i, 1, m) {
        cin >> u >> v;
        adj[u].pb(v);
    }
    mset(dp, -1);
    ll res = 0;
    foo(i, 1, n) {
        if (dp[i] == -1) {
            res = max(res, dfs(i, 0));
        }
    }
    cout << res;
}

int main() {
    SPEED;

    //cin>>test_cases;
    foo(i, 1, test_cases) {
        MAIN(i);
    }
}

Measured memory_bytes: 12800