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

using namespace std;

#define ALL(x) (x).begin(),(x).end()

#define uniq(x) (x).erase(unique(ALL(x)),(x).end())

#define SORT(x) sort(ALL(x))

#define REV(x) reverse(ALL(x))

#define foreach(it,x) for(__typeof((x).begin()) it=(x).begin();it!=(x).end();it++)

#define debug(x) cerr<<#x<<"="<<(x)<<endl

#define gett() cerr<<"Time:"<<clock()<<"ms."<<endl

#define ri(x) scanf("%d",&x)

#define rl(x) scanf("%lld",&x)

#define rlcfpoj(x) scanf("%I64d",&x)

#define pi(x) printf("%d",x)

#define pl(x) printf("%lld",x)

#define plcfpoj(x) printf("%I64d",x)

#define lfd() printf("\n")

#define sp() printf(" ")

#define inrep(x) int x;scanf("%d",&x);while(x--)

#define testbit(mask,i) (((mask)>>(i))&1)

#define setbit(mask,i) ((mask)|(1<<i))

#define delbit(mask,i) ((mask)^(1<<i))

int dp[100100];

int n,m;

vector<int> ga[100100];

int u,v;

int d(int x){

	if(dp[x]!=-1)

		return dp[x];

	int &res=dp[x];

	res=0;

	for(int i=0;i<ga[x].size();i++){

		int y=ga[x][i];

		res=max(res,d(y)+1);

	}

	return res;

}

int main(){

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

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

	ios::sync_with_stdio(false);

	cin.tie(NULL);

	cout.tie(NULL);

	cin>>n>>m;

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

		cin>>u>>v;

		ga[u].push_back(v);

	}

	int res=0;

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

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

		res=max(res,d(i));

	}

	cout<<res<<endl;

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.1201448289992222x):
//بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيمِ

//لا إله إلا الله محمد رسول الله



#include <bits/stdc++.h>



#pragma GCC optimize("Ofast")



#define ll long long

#define pb push_back

#define fr first

#define sc second

#define in freopen("input.txt", "r" , stdin)

#define out freopen("snakes.out", "w", stdout)

using namespace std;



vector <ll> g[100005];

vector<ll> ans;

ll n , m;

ll d[100005];

bool used[100005];

bool used1[100005];

ll an = 0;

void dfs1 (ll v) {

    used1[v] = 1;

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

        ll to = g[v][i];

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

        if (!used1[to])

            dfs1 (to);

    }

}

void dfs (ll v) {

    used[v] = 1;

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

        ll to = g[v][i];

        if (!used[to]) {

            dfs (to);

        }

    }

    ans.pb (v);

}



int main(){

    //in;

    //out;

    cin >> n >> m;

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

        ll a , b;

        cin >> a >> b;

        g[a].pb (b);

    }





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

        if (!used[i]) {

            dfs (i);

        }

    }



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



    for (int i = 0; i < ans.size(); i++) {

            dfs1 (ans[i]);

    }



    for (int i = 1; i <= n; i++) an = max (an, d[i]);



    cout << an;

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

using namespace std;

#define ALL(x) (x).begin(),(x).end()

#define uniq(x) (x).erase(unique(ALL(x)),(x).end())

#define SORT(x) sort(ALL(x))

#define REV(x) reverse(ALL(x))

#define foreach(it,x) for(__typeof((x).begin()) it=(x).begin();it!=(x).end();it++)

#define debug(x) cerr<<#x<<"="<<(x)<<endl

#define gett() cerr<<"Time:"<<clock()<<"ms."<<endl

#define ri(x) scanf("%d",&x)

#define rl(x) scanf("%lld",&x)

#define rlcfpoj(x) scanf("%I64d",&x)

#define pi(x) printf("%d",x)

#define pl(x) printf("%lld",x)

#define plcfpoj(x) printf("%I64d",x)

#define lfd() printf("\n")

#define sp() printf(" ")

#define inrep(x) int x;scanf("%d",&x);while(x--)

#define testbit(mask,i) (((mask)>>(i))&1)

#define setbit(mask,i) ((mask)|(1<<i))

#define delbit(mask,i) ((mask)^(1<<i))

int dp[100100];

int n,m;

vector<int> ga[100100];

int u,v;

int d(int x){

	if(dp[x]!=-1)

		return dp[x];

	int &res=dp[x];

	res=0;

	for(int i=0;i<ga[x].size();i++){

		int y=ga[x][i];

		res=max(res,d(y)+1);

	}

	return res;

}

int main(){

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

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

	ios::sync_with_stdio(false);

	cin.tie(NULL);

	cout.tie(NULL);

	cin>>n>>m;

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

		cin>>u>>v;

		ga[u].push_back(v);

	}

	int res=0;

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

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

		res=max(res,d(i));

	}

	cout<<res<<endl;

	return 0;

}


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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

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

using namespace std;

typedef long long int ll;

const int MAX=1e5 + 10;

int n,m,Sub[MAX];

vector<int>g[MAX];

bool vis[MAX];

int dfs(int root)

{

    if(vis[root])return Sub[root];

    vis[root]=1;

    int ans=0;

    for(int x:g[root]){

            ans=max(ans,1+ dfs(x));

    }

    return Sub[root]=ans;

}

int main ()

{

    cin >> n >> m;

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

        int u,v;

        cin >> u >> v;

        g[u].push_back(v);

    }

    int ans=0;

    for(int i=1;i<=n;i++) if(!vis[i])ans = max(ans,dfs(i));

    cout<<ans;

    return 0;

}


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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

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

using namespace std;



#define MX 100005

#define ll long long



vector < int > G[MX];

vector < int > topsort;

bool vis[MX];

ll dp[MX];



void dfs(int n){

    vis[n] = 1;

    for (int i = 0; i < G[n].size(); i++){

        int nxt = G[n][i];

        if (!vis[nxt])

            dfs(nxt);

    }

    topsort.push_back(n);

}



void solve(){

    for (int x = 0; x < topsort.size(); x++){

        int cur = topsort[x];

        if (G[cur].size() == 0){

            dp[cur] = 0;

        }

        else{

            ll mx = 0;

            for (int i = 0; i < G[cur].size(); i++){

                int nxt = G[cur][i];

                mx = max(mx, dp[nxt]);

            }

            dp[cur] = mx + 1;

        }

    }





}



int main()

{

    int n, m; scanf("%d%d", &n, &m);

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

        int u, v; scanf("%d%d", &u, &v);

        G[u].push_back(v);

    }



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

        if (!vis[i])

            dfs(i);

    }

    solve();

    ll res = 0;

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

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



    printf("%lld\n", res);

    return 0;

}




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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

}
// Slower C++ solution:
// PUJI TUHAN !!! YES

#include<iostream>

#include<queue>

#include<vector>

#define ii pair<int,int>

#define iii pair<int,ii> 

using namespace std;

int v,e,a,b;

vector<int> adjl[110000];

int vis[110000];

int memo[110000];

int start = 0;

int dp(int nodes){

//	cout<<nodes<<"\n";

	int sz = adjl[nodes].size();

	if(sz == 0) return 0;

	if(memo[nodes]!=-1) return memo[nodes];

	int ret = 0;

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

//		cout<<" visit "<<adjl[nodes][i]<<"\n";

		ret = max(ret, dp(adjl[nodes][i]) + 1);

	}

//	cout<<"\n";

	return memo[nodes] = ret;

}





int main(){

	cin>>v>>e;

	for(int i = 1;i<=v;i++) adjl[0].push_back(i);

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

		cin>>a>>b;

		adjl[a].push_back(b);

	}

	int ans = 0;

	for(int i = 0;i<=v;i++) memo[i] = -1;

	ans = dp(0) -1 ;

	cout<<ans<<"\n";

//	for(int i = 0;i<=v;i++) cout<<memo[i]<<" ";cout<<"\n";

//	for(int i = 0;i<=v;i++) ans = max(ans,)

	return 0;

}

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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

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

using namespace std;

int ans,n,m,a[100010],b[100010],dp[100010];

vector < int > adj[100010];

bool visit[100010];

int dfs(int x)

{

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

	dp[x] = 1;

	for(int i=0;i<adj[x].size();i++)

	{

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

	}

	return dp[x];

}

int main()

{

	scanf("%d %d",&n,&m);

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

	{

		scanf("%d %d",&a[i],&b[i]);

		adj[a[i]].push_back(b[i]);

	}

	for(int i=1;i<=n;i++) dp[i] = -1;

	ans = 1;

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

	{

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

	}

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

	return 0;

}

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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

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

using namespace std;

#define db(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<'\n'

const int N = 1e5;

vector<int> adj[N+9];

int vis[N+9], mxdist[N+9];



int dfs(int r) {

	if(vis[r]) return mxdist[r];

	vis[r]=1;

	int res=0;

	for(int x: adj[r]) {

		res=max(res, dfs(x)+1);

	}

	return mxdist[r] = res;

}

int main(){

	ios_base::sync_with_stdio(0);

	int a,b,n,m,T,cas=0;

	cin>>n>>m;

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

		cin>>a>>b;

		adj[a].emplace_back(b);

	}

	int res=0;

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

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

	}

	cout<<res<<endl;

	return 0;

}

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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

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



using namespace std;

 

typedef long long ll;

typedef long double ld;

typedef unsigned long long ull;

 

#define nl '\n'

 

#define y1 aza_ibagaliev

 

#define f first

#define s second

	

#define ed end()

#define bg begin()

#define rbg rbegin()

 

#define rv reverse

#define mp make_pair

#define pb push_back

#define ppb pop_back

#define ppf pop_front

 

#define sz size()

#define all(x) x.bg, x.ed

 

#define pll pair < ll, ll >

#define pii pair < int, int >

 

#define sqr(x) ((x) * 1ll * (x))

#define sqrd(x) ((x) * 1.0 * (x))

 

#define speed ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)

 

#define rnl cout << "----------------------------------------" << nl

 

#define bit __builtin_popcount

 

inline ll bip(ll x, ll n, ll mod){ll res=1;while(n){if(n & 1){res=(res*x)%mod;}x=(x*x)%mod;n>>=1;}return res;}

        	

const int ppr = 257;

const ll INF = 2e18;

const int inf = 2e9;

const int mod = 1e9 + 7;

const int N = 1e5 + 123;

const ld pi = 3.1741592653589793238462643;

 

const int dx[] = {1, 0, -1, 0};

const int dy[] = {0, 1, 0, -1};



int n, m, dp[N], ans, cnt[N], gr[N];

vector<int>g[N],ord;

bool u[N];



void top(int v) {

	u[v] = 1;

	for(int to : g[v]) 

		if(!u[to]) top(to);

	ord.pb(v);

}



void dfs(int v) {

	u[v] = 1;

	for(int to : g[v])

		if(!u[to]) dfs(to);

}



main() {             	

//  freopen(".in", "r", stdin);

//  freopen(".out", "w", stdout);



//	srand(time(NULL));



//	speed;



	scanf("%d%d", &n, &m);



	while(m--) {

		int x, y;

		scanf("%d%d", &x, &y);

		g[x].pb(y);

		gr[y]++;

	}



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

		if(!u[i]) top(i);

            

	rv(all(ord));



	queue<int>q;



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

		if(!gr[i]) q.push(i);



	while(!q.empty()) {

		int v = q.front();

		q.pop();



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



		for(int to : g[v]) {

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

			cnt[to]++;

			if(cnt[to] == gr[to]) q.push(to);

		}

	}



	cout << ans;



    return 0;                                        

}


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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

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

#include<iostream>

#include<cstring>

#include<algorithm>

#include<vector>

#include<queue>



using namespace std;

const int maxn = 1e5 + 5;



vector<int>vc[maxn];

queue<int> que;



int in[maxn], sum[maxn];

int n, m, ans;





int main(){

	scanf("%d %d", &n, &m);

	int u, v;

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

		scanf("%d %d", &u, &v); //u -> v

		vc[u].push_back(v);

		in[v]++;

	}

	int p = 0;

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

		if(!in[i]) 

			que.push(i);

	}

	int x;

	while(!que.empty()){

		x = que.front();

		que.pop();

		int len = vc[x].size();

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

			int y = vc[x][i];

			in[y]--;

			if(!in[y]) {

				que.push(y);

				sum[y] = sum[x] + 1;

			}

		}

	}

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

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

	}

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

}

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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

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

using namespace std;



#define ll long long

#define pb push_back

#define mp make_pair

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

#define f first

#define se second

#define lb lower_bound

#define ub upper_bound

#define pii pair<int, int>

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



const int N = 1e5 + 144, mod = 1e9 + 7, inf = 1e9 + 7;

int n, m, dp[N];

vector <int> g[N];

bool was[N];



ll bp(ll x, ll y){

    if(y == 0)

        return 1;

    if(y & 1)

        return (x * bp(x, y - 1));

    ll z = bp(x, y / 2);

    return (z * z) % mod;

}



void dfs(int x){

    was[x] = true;

    for(auto to: g[x]){

        if(!was[to])

            dfs(to);

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

    }

}



int main(){

    boost;

    cin >> n >> m;

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

        int x, y;

        cin >> x >> y;

        g[x].pb(y);

    }

    int ans = 0;

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

        if(!was[i])

            dfs(i);

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

    }

    cout << ans;

    return 0;

}




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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

}
// Slower C++ solution:
//بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيمِ

//لا إله إلا الله محمد رسول الله



#include <bits/stdc++.h>



#pragma GCC optimize("Ofast")



#define ll long long

#define pb push_back

#define fr first

#define sc second

#define in freopen("input.txt", "r" , stdin)

#define out freopen("snakes.out", "w", stdout)

using namespace std;



vector <ll> g[100005];

vector<ll> ans;

ll n , m;

ll d[100005];

bool used[100005];

bool used1[100005];

ll an = 0;

void dfs1 (ll v) {

    used1[v] = 1;

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

        ll to = g[v][i];

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

        if (!used1[to])

            dfs1 (to);

    }

}

void dfs (ll v) {

    used[v] = 1;

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

        ll to = g[v][i];

        if (!used[to]) {

            dfs (to);

        }

    }

    ans.pb (v);

}



int main(){

    //in;

    //out;

    cin >> n >> m;

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

        ll a , b;

        cin >> a >> b;

        g[a].pb (b);

    }





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

        if (!used[i]) {

            dfs (i);

        }

    }



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



    for (int i = 0; i < ans.size(); i++) {

            dfs1 (ans[i]);

    }



    for (int i = 1; i <= n; i++) an = max (an, d[i]);



    cout << an;

}




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

using namespace std;

#define ll long long

int head[100009],nxt[100009<<1],to[100009<<1],tot=0;

void add(int x,int y){

    to[++tot]=y;

    nxt[tot]=head[x];

    head[x]=tot;

}

int n,m;

int vis[100009],num[100009];

int  dfs(int x){

    if(vis[x])return num[x];

    vis[x]=1;

    for(int i=head[x];i;i=nxt[i]){

        int ver=to[i];

        num[x]=max(num[x],dfs(ver));

    }

    return ++num[x];

}

int main()

{

    cin>>n>>m;

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

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

        add(x,y);

    }

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

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

    cout<<*max_element(num+1,num+n+1)-1<<endl;

    return 0;

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

using namespace std;

#define ALL(x) (x).begin(),(x).end()

#define uniq(x) (x).erase(unique(ALL(x)),(x).end())

#define SORT(x) sort(ALL(x))

#define REV(x) reverse(ALL(x))

#define foreach(it,x) for(__typeof((x).begin()) it=(x).begin();it!=(x).end();it++)

#define debug(x) cerr<<#x<<"="<<(x)<<endl

#define gett() cerr<<"Time:"<<clock()<<"ms."<<endl

#define ri(x) scanf("%d",&x)

#define rl(x) scanf("%lld",&x)

#define rlcfpoj(x) scanf("%I64d",&x)

#define pi(x) printf("%d",x)

#define pl(x) printf("%lld",x)

#define plcfpoj(x) printf("%I64d",x)

#define lfd() printf("\n")

#define sp() printf(" ")

#define inrep(x) int x;scanf("%d",&x);while(x--)

#define testbit(mask,i) (((mask)>>(i))&1)

#define setbit(mask,i) ((mask)|(1<<i))

#define delbit(mask,i) ((mask)^(1<<i))

int dp[100100];

int n,m;

vector<int> ga[100100];

int u,v;

int d(int x){

	if(dp[x]!=-1)

		return dp[x];

	int &res=dp[x];

	res=0;

	for(int i=0;i<ga[x].size();i++){

		int y=ga[x][i];

		res=max(res,d(y)+1);

	}

	return res;

}

int main(){

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

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

	ios::sync_with_stdio(false);

	cin.tie(NULL);

	cout.tie(NULL);

	cin>>n>>m;

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

		cin>>u>>v;

		ga[u].push_back(v);

	}

	int res=0;

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

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

		res=max(res,d(i));

	}

	cout<<res<<endl;

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.9076802781503406x):
#define _CRT_SECURE_NO_WARNINGS

/*                   وتزودوا فإن خير الزاد التقوى                    */

/*       وما تدري نفس ماذا تکسب غدا وما تدري نفس باي ارض تموت      */

#include <bits/stdc++.h>

#include<unordered_map>

#include<iomanip>

#include<fstream>

using namespace std;

#define endl '\n'

#define ll long long

#define ull unsigned long long

#define dll double

#define PI acos(-1)

#define watch(x) cout<<#x<<" = "<<x<<" \n"

#define sz(n) n.size()

#define M_Sayed fast() 

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

#define allr(v) v.rbegin(),v.rend()

#define RT(v) return cout<<v,0

#define MP					make_pair

int dx[] = { 0, 1, 0, -1, 1, 1, -1, -1 };

int dy[] = { 1, 0, -1, 0, 1, -1, 1, -1 };

const double EPS = (1e-7);

const ll  mod = (1e9 + 7), OO = 1e9;

ll Ceil(ll x, ll y) { return (x + y - 1) / y; }

void run() {

#ifndef ONLINE_JUDGE

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

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

#else

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

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

#endif

}

void fast() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); }

// BFS (lenth && all path from an start node

vector<vector<ll>>adjList;

ll  vis[100005];

ll  y;

ll ca = 0, x;

ll dfs(int u) {

	if (vis[u])return vis[u];

	for (auto e : adjList[u])

		vis[u] = max(vis[u], 1 + dfs(e));

	return vis[u];

}

int main()

{

	M_Sayed;

	//run();

	int n, e,k;

	cin >> n >> e;

	adjList.resize(n + 1);

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

		int from, to;

		cin >> from >> to;

		adjList[from].push_back(to);

	}

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

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

	}

	//cout << round(12.3);

	RT(y);

}