c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 300005, M = 600005;
int n, m;
struct Edge {
int u, v;
} e[N];
int head[N], to[M], nxt[M], cnt = 2;
int dfn[N], low[N], tot;
int stk[N], top;
int bel[N], ebcc_cnt;
int dep[N];
int far_node;
void add(int u, int v) { to[cnt] = v, nxt[cnt] = head[u], head[u] = cnt++; }
void tarjan(int u, int in_edge) {
dfn[u] = low[u] = ++tot;
stk[++top] = u;
for (int i = head[u]; i; i = nxt[i]) {
if (i == (in_edge ^ 1)) continue;
int v = to[i];
if (!dfn[v]) {
tarjan(v, i);
low[u] = min(low[u], low[v]);
} else {
low[u] = min(low[u], dfn[v]);
}
}
if (dfn[u] == low[u]) {
++ebcc_cnt;
do {
bel[stk[top]] = ebcc_cnt;
} while (stk[top--] != u);
}
}
void cand() {
cnt = 1;
for (int i = 1; i <= ebcc_cnt; i++) head[i] = 0;
for (int i = 0; i < m; i++) {
int u = bel[e[i].u], v = bel[e[i].v];
if (u != v) {
add(v, u);
add(u, v);
}
}
}
void dfs(int x, int fa) {
if (dep[x] > dep[far_node]) {
far_node = x;
}
for (int i = head[x]; i; i = nxt[i]) {
int y = to[i];
if (y == fa) continue;
dep[y] = dep[x] + 1;
dfs(y, x);
}
}
int get_tree_diameter(int root, int n) {
for (int i = 1; i <= n; ++i) dep[i] = 0;
far_node = root;
dfs(root, 0);
int st = far_node;
for (int i = 1; i <= n; ++i) dep[i] = 0;
far_node = st;
dfs(st, 0);
return dep[far_node];
}
void fc() {
std::cin >> n >> m;
for (int i = 0; i < m; i++) {
std::cin >> e[i].u >> e[i].v;
add(e[i].u, e[i].v);
add(e[i].v, e[i].u);
}
tarjan(1, 0);
cand();
std::cout << get_tree_diameter(bel[1], ebcc_cnt);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// std::cin>>t;
while (t--) fc();
return 0;
}