Skip to content
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;
}