#include #include #include #include #include using namespace std; void fastIO() { ios::sync_with_stdio(false); cin.tie(0); } const int MAXN = 100000; vector graph[MAXN]; vector tree[MAXN]; int tin[MAXN], low[MAXN], timer; bool visited[MAXN]; vector> bridges; unordered_set bridgeSet; long long edgeKey(int a, int b) { return 1LL * min(a, b) * MAXN + max(a, b); } void findBridges(int v, int parent = -1) { visited[v] = true; tin[v] = low[v] = timer++; for (int to : graph[v]) { if (to == parent) continue; if (visited[to]) { low[v] = min(low[v], tin[to]); } else { findBridges(to, v); low[v] = min(low[v], low[to]); if (low[to] > tin[v]) { bridges.push_back({v, to}); bridgeSet.insert(edgeKey(v, to)); } } } } void buildComponentGraph(int v, int compID, vector& component, vector& visitedComp) { visitedComp[v] = true; component.push_back(v); for (int to : graph[v]) { if (!visitedComp[to] && bridgeSet.find(edgeKey(v, to)) == bridgeSet.end()) { buildComponentGraph(to, compID, component, visitedComp); } } } int main() { #ifdef ONLINE_JUDGE freopen("connection.in", "r", stdin); freopen("connection.out", "w", stdout); #endif fastIO(); int N, M; cin >> N >> M; for (int i = 0; i < M; i++) { int a, b; cin >> a >> b; a--; b--; graph[a].push_back(b); graph[b].push_back(a); } timer = 0; fill(visited, visited + N, false); for (int i = 0; i < N; i++) { if (!visited[i]) { findBridges(i); } } vector visitedComp(N, false); long long alwaysConnectedPairs = 0; for (int i = 0; i < N; i++) { if (!visitedComp[i]) { vector component; buildComponentGraph(i, i, component, visitedComp); int size = component.size(); alwaysConnectedPairs += 1LL * size * (size - 1) / 2; } } cout << alwaysConnectedPairs << endl; return 0; }