// Scholar ID --> 1912011
//////////////////////////////////////
////   Author: ABHINASH GIRI      ////
/////////////////////////////////////

#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
using namespace std;
#define pr 4294967296   // 2^32
#define fast ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr)
#define pi 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899
#define high 1000000001
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define setbits(x)      __builtin_popcountll(x)
#define zrobits(x)      __builtin_ctzll(x)
#define ps(x,y)         fixed<<setprecision(y)<<x
#define w(x)            int t; cin>>t; while(t--)
#define rep(i,a,b) for (int i = a; i <= b; i++)
#define nl "\n"
#define all(v) v.begin(),v.end()
typedef long long ll;
typedef unsigned long int  ul;
typedef unsigned long long int ull;
typedef unsigned long long  int  li;
typedef vector<int> vi;
typedef vector<long long int> vll;
typedef vector<unsigned long long int> vull;
typedef vector<long int> vli;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef vector<pair<int, int>> vpi;
typedef vector<pair<string, string>> vps;
typedef vector<pair<long int, long int>> vpl;
typedef vector<pair<long long int, long long int>> vpll;
//cout<<"Case #"<<x<<": "<<ans<<endl;
//***********************************************************************************************
//CONSTANTS

const long long int inf = 1e18;
const long long int ninf = -1e18;
const long long int mod = 1000000009;
const long long int MOD =  998244353;
//***********************************************************************************************

//Debug code

#define debug1(x)                   cout<<#x<<"="<<x<<'\n'
#define debug2(x,y)                 cout<<#x<<"="<<x<<","<<#y<<"="<<y<<'\n'
#define debug3(x,y,z)               cout<<#x<<"="<<x<<","<<#y<<"="<<y<<","<<#z<<"="<<z<<'\n'

//***********************************************************************************************
// Printing
#define ptvs(v) for(auto &item :v) cout<<item<<" ";cout<<"\n"
#define ptp(v) for(auto &item :v) cout<<item.first<<" "<<item.second<<"\n"
#define ptv(v) for(auto &item :v) cout<<item<<"\n"
#define ptb(ans) cout<<(ans?"YES\n":"NO\n")
#define pt(x) cout<<x<<"\n";
#define pts(x,y) cout<<x<<" "<<y<<"\n";
//Take input
#define get1(a) cin>>a
#define get2(a,b) cin>>a>>b
#define get3(a,b,c) cin>>a>>b>>c

//***********************************************************************************************
//Sorting Comparators

// sorts in ascending order on first and on second ( if first equals)
template <typename T>
bool asc(pair<T,T>&a,pair<T,T>&b)
{
    if(a.first==b.first)
    {return a.second<b.second;}
    return a.first<b.first;
}
// sorts in descending order on first and on second ( if first equals)
template <typename T>
bool desc(pair<T,T>&a,pair<T,T>&b)
{
    if(a.first==b.first)
    {return a.second>b.second;}
    return a.first>b.first;
}

//***********************************************************************************************

// Fast Exponentiation power(a,b) ==> a to the power b

template <typename T>
T  power(T  a, T  b) {
    if (b == 0)
        return 1;
    if (b == 1)
        return a;
    else {
        T  res = (power(a, b / 2));
        if (b % 2)
        {
            return (res * res * a);
        }
        else
        {return res * res;}
    }
}

// Fast Modular Exponentiation  power(a,b,m) ==> (a to the power b) modulo m

template <typename T>
T  power(T  a, T  b, T modulo) {
    if (b == 0)
        return 1;
    if (b == 1)
        return a;
    else {
        T  res = (power(a, b / 2, modulo) % modulo);
        if (b % 2)
        {
            return ((((res % modulo) * (res % modulo)) % modulo) * (a % modulo)) % modulo;
        }
        else
        {return ((res % modulo) * (res % modulo)) % modulo;}
    }
}

// G C D
template <typename T>
T  gcd(T  a, T  b) {
    if (b == 0)
        return a;
    return gcd(b, a % b);
}

// L C M
template <typename T>
T lcm(T p, T q)
{
    return (p * q) / gcd<T>(p, q);
}

//Prime factorisation
template <typename T>
void primefactorise(T n,vector<T>&vec)
{
    while (n % 2 == 0) {
        vec.emplace_back(2);
        n = n / 2;
    }
    // n must be odd at this point.  So we can skip
    // one element (Note i = i +2)
    for (int i = 3; i <= sqrt(n); i = i + 2) {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
            vec.emplace_back(i);
            n = n / i;
        }
    }
    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
    {
        vec.emplace_back(n);
    }
}

// All factors of a number in O(sqrt(n))
template <typename T>
void all_factor(T n,vector<T>&vec)
{
    for (auto i = 1; i <=sqrt(n) ; ++i) {
        if(n%i==0)
        {
//          Factors occurs in pairs
            vec.emplace_back(i);
            vec.emplace_back(n/i);
        }
    }
}

ll mulmod(ll a, ll b, ll c)
{
    // base case if b==0, return 0
    if (b == 0)
    {
        //cout<<"returned 0\n";
        return 0;
    }
    // Divide the problem into 2 parts
    ll s = mulmod(a, b / 2, c);

    // If b is odd, return
    // (a+(2*a)*((b-1)/2))%c
    if (b % 2 == 1)
    {   ll p = (a % c + 2 * (s % c)) % c;
        //cout<<" returned "<<p<<endl;
        return p;
    }
        // If b is even, return
        // ((2*a)*(b/2))%c
    else
    {   ll  p = (2 * (s % c)) % c;
        //cout<<" returned "<<p<<endl;
        return p ;
    }
}

bool valid(string &s,ll len,ll k)
{
    map<char,int>mp;
    deque<char>dq;
    for (ll i = 0; i <len ; ++i) {
        dq.emplace_back(s[i]);
        mp[s[i]]++;
    }
    ll diff = min(mp['a'],mp['b']);
    if(diff<=k)
    {
        return true;
    }
    ll e=dq.size();
    for (ll j = 0; j <s.length()-len ; ++j) {
        mp[s[e]]++;
        mp[dq.front()]--;
        dq.emplace_back(s[e++]);
        dq.pop_front();
        ll d = min(mp['a'],mp['b']);
        if(d<=k)
        {
            return true;
        }
    }
    return false;
}

ll mod_inv(ll a) {    return (power<ll>(a,mod-2,mod))%mod;    }

void factorial(ll n,vector<ll>fact)
{
    fact.resize(n+1,1);
    for (int i = 2; i <=n ; ++i)
    {
        fact[i]=((fact[i-1]%mod)*(i%mod))%mod;
    }
}
bitset<1000008>vis;
map<int,vi>mp;
int dp[1000008];
int lp(int node)
{
    //cout<<" solving for "<<node<<"\n";
    if(!vis[node])
    {
        vis[node]=true;
        if(mp[node].empty())
        {
            //cout<<" returning 0\n";
            vis[node]=false;
            return 0;
        }
        int ans=0;
        for(auto &i:mp[node])
        {
            if(!vis[i])
            {
                int a;
                //cout<<" calling for "<<i<<"\n";
                if(!dp[i])
                {
                    a = lp(i);
                    dp[i]=a;
                }
                else a=dp[i];
                //cout<<"got for "<<i<< "  "<<a<<"\n";
                ans=max(a,ans);
                vis[i]=false;
                //cout<<" ans is "<<ans<<"\n";
            }
           
        }
        //cout<<" returning "<<ans+1<<"\n";
        dp[node]=ans+1;
        return dp[node];
    }
return 0;
}
int main() {
    std::chrono::time_point<std::chrono::high_resolution_clock> start_timer, end_timer;
    start_timer = std::chrono::high_resolution_clock::now();
    bool show_time = false;  //  change it to true when needed;
//    #ifndef ONLINE_JUDGE
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
//    #endif
    /* Building Block */
    fast;
    int n,m;
    cin>>n>>m;
    int a,b;
    for (int i = 0; i <m ; ++i)
    {
        cin>>a>>b;
        mp[a].emplace_back(b);
    }
    int ans=0;
    for (int i = 1; i <=n ; ++i) {
        vis.reset();
        int p = lp(i);
//        cout<< " for "<<i<<" lp = "<<p<<"\n";
        ans=max(ans,p);
    }
    pt(ans);
//    pt(" dc ");
//    cout<<lp(1);
    end_timer = std::chrono::high_resolution_clock::now();
    ll elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_timer - start_timer).count();
    if (show_time)
    {cout << "\nElapsed Time: " << elapsed_time << "ms\n";}

    return 0;
}

Measured memory_bytes: 15872