stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h> 

using namespace std;

#define int long long int

#define float double

#define pb push_back

#define FF first

#define SS second

#define N 201000

#define MOD 1000000007

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

#define rep(i,l,r) for(int i=l;i<=r;i++)

#define pii pair<int,int>

#define mp make_pair

#define INF 1000000000000000000

#define speed ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)



vector<int> adj[N];

int vis[N]={};

int dp[N]={};

int dfs(int a)

{

    vis[a]=1;

    fn(i,adj[a].size()) 

    {

        if(!vis[adj[a][i]]) dfs(adj[a][i]);

        dp[a]=max(dp[a],1+dp[adj[a][i]]);

    }

    return dp[a];

}

signed main() 

{

    speed;

    //freopen("input.tXt","r",stdin);

    //freopen("output.tXt","w",stdout);



    int n,m;

    cin>>n>>m;



    fn(i,m)

    {

        int a,b;

        cin>>a>>b;

        adj[a].pb(b);

    }

    int ans=0;

    rep(i,1,n) if(!vis[i]) ans=max(ans,dfs(i));

    cout<<ans;

}   

// Faster C++ solution for the same problem (measured speedup: 1.48174155697688x):
#include <bits/stdc++.h> 

using namespace std;

#define int long long int

#define float double

#define pb push_back

#define FF first

#define SS second

#define N 100005

#define MOD 1000000007

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

#define rep(i,l,r) for(int i=l;i<=r;i++)

#define pii pair<int,int>

#define mp make_pair

#define INF 9223372036854775807

#define speed ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)



int n,m;

vector<int> adj[N];

int dp[N];

int ans=0;



int dfs(int node)

{

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

    dp[node]=0;

    for(auto child:adj[node]) dp[node]=max(dfs(child)+1,dp[node]);

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

    return dp[node];

}





signed main() 

{

    speed;

    //freopen("input.tXt","r",stdin);

    //freopen("output.tXt","w",stdout);



    cin>>n>>m;

    memset(dp,-1,sizeof(dp));

    fn(i,m)

    {

        int u,v;

        cin>>u>>v;

        adj[u].pb(v);

    }



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

    {

        if(dp[i]==-1) dfs(i);

    }

    cout<<ans<<endl;

}
// Slower C++ solution:
/**

 *   author: Shubham Srivastava

 *   created: 04 February 2019  18:24:54

**/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef long double ld;

vector <long long> nodes[100005];

bool visited[100005] = {0};

vector <long long> dp(100005);

vector <long long> v;

ll maxi = -1;

ll dfs(ll s)

{

	if(dp[s])

		return dp[s];

	dp[s] = 0;

	for(auto i : nodes[s])

	{

		dp[i] = dfs(i);

		dp[s] = max(dp[s],dp[i]+1);

	}

	return dp[s];

}



int main(){

    ios_base::sync_with_stdio(false); 

    cin.tie(NULL);

    long long n,m;

    cin>>n>>m;

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

    {

    	int a,b;

    	cin>>a>>b;

    	nodes[a].push_back(b);

    }

    ll ans = -1;

	for(ll p = 1; p <= n; p++)

		ans = max(ans, dfs(p));

    cout<<ans;

return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1127868677451518x):
/**

 *   author: Shubham Srivastava

 *   created: 27 January 2020  12:16:37

**/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef long double ld;

#define MOD 1000000007

#define INF 0x7fffffff

#define sorti(v) sort(v.begin(),v.end())

#define sortd(v) sort(v.rbegin(),v.rend())

typedef pair<ll, ll> pll;

typedef pair<int, int> pii;

typedef vector<int> vi;

typedef vector<pii> vii;

ll parent[2000005];

vector <ll> arr;

vector <int> node[100005], vis(100005,false);

void dfs(ll n){

	vis[n] = 1;

	for(auto i : node[n]){

		if(!vis[i])

			dfs(i);

	}

	arr.push_back(n);

}



int main(){

    ios_base::sync_with_stdio(false); 

    cin.tie(NULL);

    ll n,m;cin>>n>>m;

    vector <int> dp(n+1,0);

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

    	ll a,b;cin>>a>>b;

    	node[a].push_back(b);

    }

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

    	if(!vis[i])

    		dfs(i);

    reverse(arr.begin(),arr.end());

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

    	for(auto j : node[arr[i]]){

    		dp[j] = max(dp[j],dp[arr[i]]+1);

    	}

    }

    int ans = 0;

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

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

    cout<<ans;

return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



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

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

#define _GLIBCXX_DEBUG

#define llint long long

const double pi=3.141592653589793;



vector<int> dp(100010,0);

vector<int> p(100010,0);

vector<vector<int>> st(100010,vector<int>(0));

vector<vector<int>> ts(100010,vector<int>(0));



//sを始点とする最長パスをdpで求める



int ddpp(int s){

    if (p[s]==1){

        return dp[s];

    }

    else{

        p[s]=1;

        int m1=0;

        if (st[s].size()==0){

            dp[s]=0;

            return 0;

        }

        for (int x:st[s]){

            m1=max(m1,ddpp(x));

        }

        dp[s]=1+m1;

        return dp[s];

    }

}

int main() {

    int n,m;

    cin>>n>>m;

    rep(i,m){

        int x,y;

        cin>>x>>y;

        st[x].push_back(y);

        ts[y].push_back(x);

    }

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

        if (ts[i].size()==0){

            ddpp(i);

        }

    }

    int mmm=0;

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

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

    }

    cout<<mmm<<endl;



    



    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 2.137990117855636x):
#include <bits/stdc++.h>



using namespace std;



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

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

#define _GLIBCXX_DEBUG



using ll = long long;

using vi = vector<int>;

using vll = vector<ll>;

using vd = vector<double>;

using vvi = vector<vi>;

using vvll = vector<vll>;

using vvd = vector<vd>;

using vvvi = vector<vvi>;

using vvvll = vector<vvll>;

using vvvd = vector<vvd>;



const double pi=3.141592653589793;



int n,m;

int dp[100010];

int flag[100010];

vvi to(100010,vi(0));



int ddpp(int x){

    if(flag[x]){

        return dp[x];

    }

    else{

        flag[x]=1;

        auto xto=to[x];

        int ans1=0;

        if (xto.size()==0){

            dp[x]=ans1;

            return ans1;

        }

        else{

            for (int y:xto){

                ans1=max(ans1,ddpp(y)+1);

            }

            dp[x]=ans1;

            return dp[x];

        }

        

    }

}



int main() {

    cin>>n>>m;

    rep(i,m){

        int x,y;

        cin>>x>>y;

        to[x].push_back(y);

    }

    int ans=0;

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

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

        //cout<<dp[i]<<endl;

    }

    cout<<ans<<endl;

    



    return 0;

}
// Slower C++ solution:
// G - Longest Path

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;



int N,M;



#define VMAX 100000



vvi V(VMAX+1);//vertex

vi D(VMAX+1);//depth



int dfs(int p){//parent 後置でD設定

	if(D[p]>0) return D[p];

	if(V[p].size()<=0) return 0;

	for(auto c:V[p]){

		D[p] = max(D[p], dfs(c)+1);

	}

	return D[p];

}



int main(){

	cin>>N>>M;



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

		int x,y; cin>>x>>y;

		V[x].push_back(y);

	}



	for(int p=1; p<=N; p++){

		if(D[p]<=0) D[0] = max(D[0], dfs(p));

	}

	cout<< D[0] <<endl;

}

// Faster C++ solution for the same problem (measured speedup: 3.933578774261548x):
// G - Longest Path

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;



int dfs(vvi &V, vi &D, int p){

	if(D[p]>0 || V[p].size()<=0) return D[p];

	for(int c:V[p]) D[p] = max(D[p], dfs(V,D,c)+1);

	return D[p];

}



int in(){int x;cin>>x;return x;}



int main(){

	int N,M; cin>>N>>M;



	vvi V(N+1);

	while(M--) V[in()].push_back(in());



	vi D(N+1);

	for(int p=1; p<=N; p++) if(D[p]<=0) D[0] = max(D[0], dfs(V,D,p));



	cout<< D[0] <<endl;

}
// Slower C++ solution:
// G - Longest Path

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;



int N,M;



#define VMAX 100000



vvi V(VMAX+1);//vertex

vi D(VMAX+1);//depth



int dfs(int p){//parent 後置でD設定

	if(D[p]>0) return D[p];

	if(V[p].size()<=0) return 0;

	for(auto c:V[p]){

		D[p] = max(D[p], dfs(c)+1);

	}

	return D[p];

}



int main(){

	cin>>N>>M;



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

		int x,y; cin>>x>>y;

		V[x].push_back(y);

	}



	for(int p=1; p<=N; p++){

		if(D[p]<=0) D[0] = max(D[0], dfs(p));

	}

	cout<< D[0] <<endl;

}

// Faster C++ solution for the same problem (measured speedup: 3.9327253131206574x):
// G - Longest Path

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;



int dfs(vvi &V, vi &D, int p){

	if(D[p]>0 || V[p].size()<=0) return D[p];

	for(int c:V[p]) D[p] = max(D[p], dfs(V,D,c)+1);

	return D[p];

}



int in(){int x;cin>>x;return x;}



int main(){

	int N,M; cin>>N>>M;



	vvi V(N+1);

	while(M--) V[in()].push_back(in());



	vi D(N+1);

	for(int p=1; p<=N; p++) D[0] = max(D[0], dfs(V,D,p));

	cout<< D[0] <<endl;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



vector<int> v[100001];

bool visited[100001];

int dp[100001];



void dfs(int idx)

{

    int num=0;

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

    {

        if(!visited[v[idx][i]])

        {

            visited[v[idx][i]]=1;

            dfs(v[idx][i]);

        }

        num=max(num,dp[v[idx][i]]+1);

    }

    dp[idx]=num;

}



int main()

{

    int n,m;

    cin >> n >> m;

    int x,y;

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

    {

        cin >> x >> y;

        v[x].push_back(y);

    }

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

    int res=0;

    for(int i=1;i<=n;i++) res=max(res,dp[i]);

    cout << res << endl;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.452811458434115x):
#include <bits/stdc++.h>



using namespace std;

typedef long long ll;



int main()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    int n,m;

    cin >> n >> m;

    vector<int> vr[n+1];

    vector<int> out(n+1,0);

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

    {

        int a,b;

        cin >> a >> b;

        vr[b].push_back(a);

        out[a]++;

    }

    queue<int> q;

    for(int i=1;i<=n;i++) if(out[i]==0) q.push(i);

    vector<int> dp(n+1,0);

    while(!q.empty())

    {

        int a=q.front();

        q.pop();

        for(int to:vr[a])

        {

            dp[to]=max(dp[to],dp[a]+1);

            out[to]--;

            if(out[to]==0) q.push(to);

        }

    }

    int res=0;

    for(int i=1;i<=n;i++) res=max(res,dp[i]);

    cout << res << "\n";

    return 0;

}
// Slower C++ solution:
#include<map>

#include<cmath>

#include<stack>

#include<queue>

#include<cstdio>

#include<vector>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

typedef long long ll;

template<class Read>void in(Read &x){

    x=0;

    int f=0;

    char ch=getchar();

    while(ch<'0'||ch>'9'){

        f|=(ch=='-');

        ch=getchar();

    }

    while(ch>='0'&&ch<='9'){

        x=(x<<1)+(x<<3)+(ch^48);

        ch=getchar();

    }

    x=f?-x:x;

    return;

}

struct Node{

    int x;

    int y;

}a[100005];

int n,m,ans,du[100005],h[100005],f[100005];

vector<int>v[100005],k[100005];

stack<int>q;

int main(){

    in(n);in(m);

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

        in(a[i].x);in(a[i].y);

        v[a[i].x].push_back(a[i].y);

        k[a[i].y].push_back(a[i].x);

        du[a[i].y]++;

    }

    for(int i=1;i<=n;i++)if(du[i]==0)q.push(i),h[++h[0]]=i;

    while(!q.empty()){

        int l=q.top();

        q.pop();

        for(int i=0;i<v[l].size();i++){

            int u=v[l][i];

            du[u]--;

            f[u]=max(f[u],f[l]+1);

            if(du[u]==0){

                q.push(u);

                h[++h[0]]=u;

            }

        }

    }

    for(int i=1;i<=n;i++)ans=max(ans,f[i]);

    printf("%d\n",ans);

	return 0;

}


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

#include<cmath>

#include<stack>

#include<queue>

#include<cstdio>

#include<vector>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

typedef long long ll;

template<class Read>void in(Read &x){

    x=0;

    int f=0;

    char ch=getchar();

    while(ch<'0'||ch>'9'){

        f|=(ch=='-');

        ch=getchar();

    }

    while(ch>='0'&&ch<='9'){

        x=(x<<1)+(x<<3)+(ch^48);

        ch=getchar();

    }

    x=f?-x:x;

    return;

}

struct Node{

    int to;

    int next;

}a[100005];

int n,m,top,ans,head[100005],ru[100005],b[100005],f[100005];

queue<int>q;

void add(int x,int y){

    a[++top].to=y;

    a[top].next=head[x];

    head[x]=top;

}

int main(){

    in(n);in(m);

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

        int x,y;

        in(x);in(y);

        add(x,y);

        ru[y]++;

    }

    for(int i=1;i<=n;i++)if(ru[i]==0)q.push(i),b[++b[0]]=i;

    while(!q.empty()){

        int x=q.front();

        q.pop();

        for(int i=head[x];i;i=a[i].next){

            int y=a[i].to;

            ru[y]--;

            if(ru[y]==0)q.push(y),b[++b[0]]=y;

        }

    }

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

        for(int j=head[b[i]];j;j=a[j].next){

            int k=a[j].to;

            f[k]=max(f[k],f[b[i]]+1);

        }

    }

    for(int i=1;i<=n;i++)ans=max(ans,f[i]);

    printf("%d\n",ans);

    return 0;

}
// Slower C++ solution:
#include<map>

#include<cmath>

#include<stack>

#include<queue>

#include<cstdio>

#include<vector>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

typedef long long ll;

template<class Read>void in(Read &x){

    x=0;

    int f=0;

    char ch=getchar();

    while(ch<'0'||ch>'9'){

        f|=(ch=='-');

        ch=getchar();

    }

    while(ch>='0'&&ch<='9'){

        x=(x<<1)+(x<<3)+(ch^48);

        ch=getchar();

    }

    x=f?-x:x;

    return;

}

struct Node{

    int x;

    int y;

}a[100005];

int n,m,ans,du[100005],h[100005],f[100005];

vector<int>v[100005],k[100005];

queue<int>q;

int main(){

    in(n);in(m);

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

        in(a[i].x);in(a[i].y);

        v[a[i].x].push_back(a[i].y);

        k[a[i].y].push_back(a[i].x);

        du[a[i].y]++;

    }

    for(int i=1;i<=n;i++)if(du[i]==0)q.push(i),h[++h[0]]=i;

    while(!q.empty()){

        int l=q.front();

        q.pop();

        for(int i=0;i<v[l].size();i++){

            int u=v[l][i];

            du[u]--;

            f[u]=max(f[u],f[l]+1);

            if(du[u]==0){

                q.push(u);

                h[++h[0]]=u;

            }

        }

    }

    for(int i=1;i<=n;i++)ans=max(ans,f[i]);

    printf("%d\n",ans);

	return 0;

}


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

#include<cmath>

#include<stack>

#include<queue>

#include<cstdio>

#include<vector>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

typedef long long ll;

template<class Read>void in(Read &x){

    x=0;

    int f=0;

    char ch=getchar();

    while(ch<'0'||ch>'9'){

        f|=(ch=='-');

        ch=getchar();

    }

    while(ch>='0'&&ch<='9'){

        x=(x<<1)+(x<<3)+(ch^48);

        ch=getchar();

    }

    x=f?-x:x;

    return;

}

struct Node{

    int to;

    int next;

}a[100005];

int n,m,top,ans,head[100005],ru[100005],b[100005],f[100005];

queue<int>q;

void add(int x,int y){

    a[++top].to=y;

    a[top].next=head[x];

    head[x]=top;

}

int main(){

    in(n);in(m);

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

        int x,y;

        in(x);in(y);

        add(x,y);

        ru[y]++;

    }

    for(int i=1;i<=n;i++)if(ru[i]==0)q.push(i),b[++b[0]]=i;

    while(!q.empty()){

        int x=q.front();

        q.pop();

        for(int i=head[x];i;i=a[i].next){

            int y=a[i].to;

            ru[y]--;

            if(ru[y]==0)q.push(y),b[++b[0]]=y;

        }

    }

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

        for(int j=head[b[i]];j;j=a[j].next){

            int k=a[j].to;

            f[k]=max(f[k],f[b[i]]+1);

        }

    }

    for(int i=1;i<=n;i++)ans=max(ans,f[i]);

    printf("%d\n",ans);

    return 0;

}
// Slower C++ solution:
#pragma GCC optimize("O3")

#include <bits/stdc++.h>

#define ll   long long

#define ld long double

#define endl '\n'

#define INF 10000000000000000

#define pll pair<ll,ll>

#define ff first

#define ss second



using namespace std;

const ll N = 200005;

const ll MOD = 998244353;

vector<ll> g[N];

bool use[N];

    ll n,m;

    ll in_degree[N];

ll bfs() {

    ll d[N]={0};

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

        d[i]=INF;

    }

    priority_queue<pll> q;

    ll mx = 0;

    q.push(make_pair(0,0));

    while(!q.empty()) {

        ll v = q.top().ss;

        ll dw = q.top().ff;

        q.pop();

        if(d[v]>dw) continue;

        if(d[v]>mx) mx=d[v];

        for(ll i =0;i<g[v].size();i++) {

                ll to =g[v][i];



                if(in_degree[to]>=0)

                in_degree[to]--;

             //   cout<<i<<" "<<to<<" "<<in_degree[to]<<endl;

                if(d[to]==INF || d[to]<=d[v]) {

                    d[to]=d[v]+1;

                  //  q.push({d[to],to});

                }

                if(in_degree[to]==0) {

                    in_degree[to]--;

                    q.push({d[to],to});

                }

        }

    }

    //for(ll i =0;i<=n;i++) {

   //     cout<<in_degree[i]<<" "<<d[i]<<endl;

   // }

    return mx-1;

}

int main()

{

 //freopen("input.txt","r",stdin);

 //  freopen("output.txt","w",stdout);

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    cout.tie(NULL);



    cin>>n>>m;

    for(ll i =1;i<=m;i++) {

        ll u,v;

        cin>>u>>v;

        g[u].push_back(v);

        use[v]=1;

        ++in_degree[v];

    }

    in_degree[0]=-1;

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

        if(!use[i]) {g[0].push_back(i);  in_degree[i]++;}

    }

  //  cout<<endl;

    cout<<bfs();



}


// Faster C++ solution for the same problem (measured speedup: 1.2850906323877398x):
#pragma GCC optimize("O3")

#include <bits/stdc++.h>

#define ll   long long

#define ld long double

#define endl '\n'

#define INF 10000000000000000

#define pll pair<ll,ll>

#define ff first

#define ss second



using namespace std;

const ll N = 200005;

const ll MOD = 998244353;

vector<ll> g[N];

bool vis[N];

ll d[N];

ll in_degree[N];

void dfs(ll v) {

    vis[v]=1;

    for(ll i =0;i<g[v].size();i++) {

        ll to = g[v][i];

        d[to]=max(d[to],d[v]+1);

        in_degree[to]--;

        if(in_degree[to]==0)

            dfs(to);

    }

}

int main()

{

 //freopen("input.txt","r",stdin);

 //  freopen("output.txt","w",stdout);

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    cout.tie(NULL);

    ll n,m;

    cin>>n>>m;

    for(ll i =1;i<=m;i++) {

        ll u,v;

        cin>>u>>v;

        g[u].push_back(v);

        ++in_degree[v];

    }

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

        if(!vis[i] && in_degree[i]==0) dfs(i);

    }

    ll ans =0;

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

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

    }

    cout<<ans;





}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

vector<int> dp(100100,-1),graph[100100];



int ans(int curr){

    if(dp[curr] != -1){

        return dp[curr];

    }

    int ret = 0;

    for(int i : graph[curr]){

        ret = max(ret , 1+ans(i));

    }

    dp[curr] = ret;

    return ret;

}



int main()

{

    int n,m,a,b;

    cin >> n >> m;

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

        cin >> a >> b;

        graph[a].push_back(b);

    }

    int ansi=0;

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

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

    }

    cout << ansi;

}

// Faster C++ solution for the same problem (measured speedup: 3.899021307853417x):
#include <bits/stdc++.h>

using namespace std;

int n,m,ans,indeg[100001],dp[100001];

vector<vector<int>> graph;



int main(){

	cin >> n >> m;

	graph.resize(n+1);

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

		int a,b;

		cin >> a >> b;

		graph[a].push_back(b);

		indeg[b] += 1;

	}

	queue<int> q;

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

		if(indeg[i] == 0){

			q.push(i);

		}

	}

	vector<int> order;

	while(q.size()){

		int a = q.front();

		q.pop();

		order.push_back(a);

		for(int i : graph[a]){

			indeg[i] -= 1;

			if(indeg[i] == 0){

				q.push(i);

			}

		}

	}

	for(int i : order){

		for(int j : graph[i]){

			dp[j] = max(dp[j],dp[i]+1);

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

		}

	}

	cout << ans << endl;

}
// Slower C++ solution:
#include "bits/stdc++.h"

using namespace std;

 

int dp[100005];

bool visited[100005];

vector<int> adj[100005];

 

void visit(int vertex){

	visited[vertex] = 1;

	dp[vertex] = 0;

	for(int child:adj[vertex]){

		if(!visited[child]){

			visit(child);

		}

		dp[vertex] = max(dp[vertex] , 1 + dp[child]);

	}

}

 

int main(){

	int n,m;

	cin>>n>>m;

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

		int x,y;

		cin>>x>>y;

		adj[x].push_back(y);

	}

	

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

		if(!visited[i]){

			visit(i);

		}

	}

	

	int ans = 0;

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

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

	}

	

	cout<<ans;

	

}

// Faster C++ solution for the same problem (measured speedup: 3.4446990191097413x):


// Problem : G - Longest Path

// Contest : AtCoder - Educational DP Contest

// URL : https://atcoder.jp/contests/dp/tasks/dp_g

// Memory Limit : 1024 MB

// Time Limit : 2000 ms

// Powered by CP Editor (https://github.com/cpeditor/cpeditor)



//#pragma GCC optimize "trapv"//  WA to RE int!!

#include <bits/stdc++.h>

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

#define FORR(i,n) for(int i=n;i>=0;i--)

#define pb push_back

#define vlli vector<int>

#define slli set<int>

#define mlli map<int,int>

#define int long long int 

#define test int tt1234; cin>>tt1234;while(tt1234--)

#define endl "\n"

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

#define rep(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))

#define error(x) cerr << #x <<" is " << x << endl;

#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";

#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);

#define fint fast;test

#define SI(a,n) int a[n];FOR(i,n) cin>>a[i];

#define input(a,n) int n;cin>>n; SI(a,n)

#define set(a,x) memset(a,x,sizeof(a))

#define L(x)	((x)<<1)

#define R(x)	(((x)<<1)+1)

#define ft first

#define se second

#define MOD 1000000007

using namespace std;

vector<vector<int>>adj;

vector<bool>vis;

vector<int>dp;

int dfs(int node)

{

	int ans=0;

	vis[node]=true;

	dp[node]=0;

	for(auto child:adj[node])

	{

		if(!vis[child])

		{

			dfs(child);

		}

		dp[node]=max(dp[node],1+dp[child]);

	}

	return dp[node];

}

void solve(){

	int n,e;

	cin>>n>>e;

	adj.resize(n+1,vector<int>());

	vis.resize(n+1);

	dp.resize(n+1);

	FOR(i,e)

	{

		int u,v;

		cin>>u>>v;

		adj[u].pb(v);

	}

	int ans=0;

	rep(i,1,n+1)

	{

		if(!vis[i])

		{

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

		}

	}

	cout<<ans;

	return;	

}





int32_t main() {

    // fint{

    	fast;

    	solve();

    // }

    return 0;

}