#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mod int(1e9)
#define flash                         \
    ios_base::sync_with_stdio(false); \
    cin.tie(NULL)
#define rep(i, a, b) for (ll i = a; i < b; i++)
#define repc(i, a, b, c) for (ll i = a; (c > 0 ? i < b : i > b) and c != 0; i += c)
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define all(name) (name.begin(), name.end())
#define fact(n) rep(i, 1, n + 1) ft.pb((ft[i - 1] * i) % mod);
#define mod_in(a) power(a, mod - 2)
#define ncr(n, r) ((ft[n] * mod_in((ft[r] * ft[(n) - (r)]) % mod)) % mod)
#define deb(x) cout << #x << " " << x << endl;
#define answ(x, y) cout << "Case #" << x << ": " << y << endl;
vector<bool> is_prime(1000, 1);
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;

    return gcd(b % a, a);
}
void sieve()
{
    is_prime[0] = is_prime[1] = 0;
    for (int i = 2; i * i <= 1000; i++)
        if (is_prime[i])
            repc(j, i * i, 1000, i) is_prime[j] = 0;
}
// pair<ll, ll> d[mod];
// ll h[mod];
// vector<ll> edge[mod];

// void dfs(ll u, ll pair = -1)
// {
//     for (auto i : edge[u])
//     {
//         if (i == pair)
//             continue;
//         h[i] = h[u] + 1;
//         dfs(i, u);
//         d[u].first += d[i].first + 1;
//     }
// }

bool cmp(pair<ll, ll> c, pair<ll, ll> b)
{
    return c.second - c.first > b.second - b.first;
}
// ll power(ll x, ll y)
// {
//     ll res = 1;
//     x %= mod;
//     while (y > 0)
//     {
//         if (y & 1)
//             res = (res * x) % mod;
//         y = y >> 1;
//         x = (x * x) % mod;
//     }
//     return res % mod;
// }

// void bfs(int st,vector<ll> d){
//     queue<int> q;
//     d[st]=0;
//     q.push(st);
//     while(!q.empty()){
//         int v=q.front();
//         q.pop();
//         for(auto it:edge[v]){
//             if(d[it]==mod){
//                 d[it]=d[v]+1;
//                 q.push(it);
//             }
//         }
//     }
// }
//using namespace std;
const ll man=1e5 +5;
vector<ll> edge[man];
vector<ll> dp(man);
bool visited[man];
ll coming[man];
// ll dfs(ll a){
//     if(edge[a].size()==0){
//         cout<<"a is "<<a<<endl;
//         return dp[a]=1;
//     }
//     visited[a]=1;
//     for(ll i=0;i<edge[a].size();i++){
//         cout<<"edge[a][i] is "<<edge[a][i]<<endl;
//         if(visited[edge[a][i]]==0){
            
//             dp[a]=max(dfs(edge[a][i])+1,dp[a]);
//         }
//     }
// }
void dfs(ll a){
    visited[a]=true;
    for(auto b:edge[a]){
        dp[b]=max(dp[b],dp[a]+1);
        --coming[b];
        if(coming[b]==0){
            dfs(b);
        }
    }
}
int main()
{
    long long int i, j, k, o, n, m;
    cin >> n >> m;
    
    vector<ll> nedge[n];
    for (i = 0; i < m; i++)
    {
        ll x, y;
        cin >> x >> y;
        x--, y--;
        edge[x].push_back(y);
        ++coming[y];
    }
    for(i=0;i<n;i++){
        if(!visited[i] && coming[i]==0){
            dfs(i);
        }
    }

    // vector<ll> no_coming;
    // for (i = 0; i < n; i++)
    // {
    //     if (nedge[i].size() == 0)
    //     {
    //         dp[i] = 0;
    //         no_coming.push_back(i);
    //     }
    // }
    // for(i=0;i<n;i++){
    //     for(j=0;j<edge[i].size();j++){
    //         cout<<"i is "<<i<<" value of j is "<<edge[i][j]<<endl;
    //         dp[i]=max(dp[i],dp[edge[i][j]]+1);
    //         cout<<" value of dp is "<<dp[i]<<" comp with "<<dp[edge[i][j]]+1<<endl;
    //     }
    // }
    // ll ans=0;
    // for (i = 0; i < no_coming.size(); i++)
    // {
    //     ll p = no_coming[i];
    //     ans=max(ans,dfs(p));
    //     // for (j = 0; j < edge[p].size(); j++)
    //     // {
            
    //     //     // cout << "p is " << p + 1 << " value of j is " << edge[p][j] + 1 << endl;
    //     //     // dp[p] = max(dp[p], dp[edge[p][j]] + 1);
    //     //     // cout << " value of dp is " << dp[p] << " comp with " << dp[edge[p][j]] + 1 << endl;
    //     //     // cout<<"no_coming is "<<no_coming[i]<<endl;
    //     //     // cout<<"value of j is "<<
    //     //     // dp[no_coming[i]]=max(dp[no_coming[i]],dp[nedge[no_coming[i]][j]]+1);
    //     //     // ll q=edge[p][j];
    //     //     // while(edge[q].size()!=0){
    //     //     //     for(k=0;k<edge[q].size();k++){
    //     //     //         dp[edge[k][]]=
    //     //     //     }
    //     //     // }
    //     // }
    // }
    // for (k = 0; k< n; k++)
    // {
    //     for (i = 0; i < n; i++)
    //     {
    //         for (j = 0; j < nedge[i].size(); i++)
    //         {
    //             dp[j] = max(dp[j], dp[nedge[i][j]] + 1);
    //         }
    //     }
    // }
    
    // for (i = 0; i < n; i++)
    // {
    //     cout << "dp is " << dp[i] << endl;
    // }
    cout << *max_element(dp.begin(), dp.end()) << endl;
}

Measured memory_bytes: 12800