#include <cstdio>
#include <queue>
#include <stack>
#include <algorithm>
const int MAXN = 1e5 + 5;
std::vector<int> G[MAXN], G_scc[MAXN], G_scc_back[MAXN];
int n, m, low[MAXN], dfn[MAXN], _dfn, cnt_scc, scc[MAXN], w[MAXN], in_deg[MAXN], out_deg[MAXN], dis[MAXN], dis_back[MAXN];
std::stack<int> st;
inline void Tarjan (const int &u) {
st.push(u), low[u] = dfn[u] = ++_dfn;
for (int v : G[u])
if (!dfn[v])
Tarjan(v),
low[u] = std::min(low[u], low[v]);
else if (!scc[v])
low[u] = std::min(low[u], dfn[v]);
if (low[u] == dfn[u]) {
cnt_scc++; int t;
do w[scc[t = st.top()] = cnt_scc]++, st.pop();
while (t != u);
}
}
inline void rebuild () {
for (int u = 1; u <= n; u++)
for (int v : G[u])
if (scc[u] != scc[v])
G_scc[scc[u]].push_back(scc[v]),
G_scc_back[scc[v]].push_back(scc[u]);
}
bool vis[MAXN];
inline void SPFA (const std::vector<int> *g, int *d) {
for (int i = 1; i <= cnt_scc; i++) vis[i] = false, d[i] = 0;
std::queue<int> q;
q.push(scc[1]), d[scc[1]] = w[scc[1]], vis[scc[1]] = true;
while (!q.empty()) {
int u = q.front(); q.pop(), vis[u] = false;
for (int v : g[u]) {
if (d[v] < d[u] + w[v]) {
d[v] = d[u] + w[v];
if (!vis[v]) q.push(v), vis[v] = true;
}
}
}
}
int main () {
scanf("%d%d", &n, &m);
for (int i = 1, u, v; i <= m; i++)
scanf("%d%d", &u, &v), G[u].push_back(v);
for (int i = 1; i <= n; i++) if (!dfn[i]) Tarjan(i);
rebuild(), SPFA(G_scc, dis), SPFA(G_scc_back, dis_back);
int ans = w[scc[1]];
for (int u = 1; u <= cnt_scc; u++)
for (int v : G_scc[u])
ans = std::max(ans, dis[v] + dis_back[u] - w[scc[1]]),
ans = std::max(ans, dis[u] + dis_back[v] - w[scc[1]]);
printf("%d", ans);
return 0;
}