差不多是板子了:
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repl(i,x,y) for(ll i=(x);i<(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;
const ll N=1e5+5;
const ll Inf=1e18;
ll n,m,ans;
ll top,tim,scc,vis[N],dfn[N],low[N],bel[N],size[N],stack[N];
struct node {
ll vis[N],dis[N];
ll cnt,from[N],to[N],nxt[N],head[N];
void ins(ll x,ll y) {
from[++cnt]=x;to[cnt]=y;nxt[cnt]=head[x];head[x]=cnt;
}
void spfa() {
queue<ll>q;
rep(i,1,n) dis[i]=-Inf;
q.push(bel[1]);vis[bel[1]]=1;dis[bel[1]]=0;
while(q.size()) {
ll x=q.front();q.pop();vis[x]=0;
for(ll i=head[x];i;i=nxt[i]) {
ll y=to[i],z=size[y];
if(dis[x]+z>dis[y]) {
dis[y]=dis[x]+z;
if(vis[y]==0) {
vis[y]=1;q.push(y);
}
}
}
}
}
};
node G1,G2,G3;
inline ll read() {
ll x=0;char ch=getchar();bool f=0;
while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?-x:x;
}
void tarjan(ll x) {
dfn[x]=low[x]=++tim;vis[x]=1;stack[++top]=x;
for(ll i=G1.head[x];i;i=G1.nxt[i]) {
ll y=G1.to[i];
if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
else if(vis[y]) low[x]=min(low[x],dfn[y]);
}
if(dfn[x]!=low[x]) return ;
scc++;
while(true) {
ll y=stack[top--];
vis[y]=0;bel[y]=scc;size[scc]++;
if(x==y) return ;
}
}
void File() {
freopen("taste.in","r",stdin);
freopen("taste.out","w",stdout);
}
int main() {
// File();
n=read(),m=read();
rep(i,1,m) {
ll x=read(),y=read();G1.ins(x,y);
}
rep(i,1,n) if(!dfn[i]) tarjan(i);
rep(i,1,m) {
ll x=G1.from[i],y=G1.to[i];
if(bel[x]!=bel[y]) G2.ins(bel[x],bel[y]),G3.ins(bel[y],bel[x]);
}
G2.spfa();
G3.spfa();
rep(i,1,G2.cnt) {
ll x=G2.to[i],y=G2.from[i];
ans=max(ans,G2.dis[x]+G3.dis[y]+size[bel[1]]);
}
printf("%lld",ans);
return 0;
}