/* Problem URL: https://codeforces.com/contest/1000/problem/E */ #include #include #include using namespace std; using namespace __gnu_pbds; template > using ordered_set = tree; #define V vector #define rmin(a, b) a = min(a, b) #define rmax(a, b) a = max(a, b) #define rep(i, lim) for (int i = 0; i < (lim); i++) #define nrep(i, s, lim) for (int i = s; i < (lim); i++) #define repv(i, v) for (auto &i : (v)) #define fillv(v) for (auto &itr_ : (v)) { cin >> itr_; } #define sortv(v) sort(v.begin(), v.end()) #define all(v) (v).begin(), (v).end() using vi = vector; using vvi = vector; using vvvi = vector; using vvvvi = vector; using ll = long long; using vl = vector; using vvl = vector; using vvvl = vector; using vvvvl = vector; template auto operator<<(ostream &os, const vector &vec)->ostream& { os << vec[0]; for (size_t i = 1; i < vec.size(); i++) { os << ' ' << vec[i]; } os << '\n'; return os; } template auto operator>>(istream &is, vector &vec)->istream& { for (auto &i : vec) { is >> i; } return is; } template auto operator<<(ostream &os, const vector> &vec)->ostream& { for (auto &i : vec) { os << i[0]; for (size_t j = 1; j < i.size(); j++) { os << ' ' << i[j]; } os << '\n'; } return os; } template auto operator>>(istream &is, vector> &vec)->istream& { for (auto &i : vec) { for (auto &j : i) { is >> j; } } return is; } set> inv; V> act; int c = 0; void IS_BRIDGE(int v,int to) { inv.emplace(v, to); inv.emplace(to, v); act.emplace_back(v, to); c++; }; // some function to process the found bridge int n; // number of nodes vector> adj; // adjacency list of graph vector visited; vector tin, low; int timer; void dfs(int v, int p = -1) { visited[v] = true; tin[v] = low[v] = timer++; bool parent_skipped = false; for (int to : adj[v]) { if (to == p && !parent_skipped) { parent_skipped = true; continue; } if (visited[to]) { low[v] = min(low[v], tin[to]); } else { dfs(to, v); low[v] = min(low[v], low[to]); if (low[to] > tin[v]) IS_BRIDGE(v, to); } } } void find_bridges() { timer = 0; visited.assign(n, false); tin.assign(n, -1); low.assign(n, -1); for (int i = 0; i < n; ++i) { if (!visited[i]) dfs(i); } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int m; cin >> n >> m; adj.resize(n); while (m--) { int a, b; cin >> a >> b; a--, b--; adj[a].push_back(b); adj[b].push_back(a); } find_bridges(); int g = 0; V vis(n); vi group(n); function att = [&](int i) { vis[i] = true; group[i] = g; for (auto j : adj[i]) { if (vis[j] || inv.find({i, j}) != inv.end()) { continue; } att(j); } }; rep(i, n) { if (vis[i]) { continue; } att(i); g++; } vvi graph(c + 1); for (auto [u, v] : act) { graph[group[u]].push_back(group[v]); graph[group[v]].push_back(group[u]); } int oo = INT32_MAX >> 1; auto bfs = [&](int u) -> pair { vi dis(c + 1, oo); dis[u] = 0; queue q; q.push(u); int ans = u; while (!q.empty()) { auto i = q.front(); q.pop(); for (auto j : graph[i]) { if (dis[j] > dis[i] + 1) { dis[j] = dis[i] + 1; q.push(j); ans = j; } } } return {ans, dis[ans]}; }; auto [u, _] = bfs(0); auto [v, ans] = bfs(u); cout << ans << '\n'; }