#include #include #include struct DSU { std::vector parent; std::vector sz; DSU(int n) { parent.resize(n + 1); std::iota(parent.begin(), parent.end(), 0); sz.assign(n + 1, 1); } int find(int i) { if (parent[i] == i) return i; return parent[i] = find(parent[i]); } void unite(int i, int j) { int root_i = find(i); int root_j = find(j); if (root_i != root_j) { if (sz[root_i] < sz[root_j]) std::swap(root_i, root_j); parent[root_j] = root_i; sz[root_i] += sz[root_j]; } } }; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int N, M; std::cin >> N >> M; std::vector> edges(M); for (int i = 0; i < M; ++i) { std::cin >> edges[i].first >> edges[i].second; } int Q; std::cin >> Q; std::vector query_edges(Q); std::vector is_removed(M, false); for (int i = 0; i < Q; ++i) { std::cin >> query_edges[i]; query_edges[i]--; // 0-indexed is_removed[query_edges[i]] = true; } DSU dsu(N); for (int i = 0; i < M; ++i) { if (!is_removed[i]) { dsu.unite(edges[i].first, edges[i].second); } } long long current_disconnected_pairs = 0; std::vector visited_root(N + 1, false); long long connected_nodes = 0; for (int i = 1; i <= N; ++i) { int root = dsu.find(i); if (!visited_root[root]) { long long size = dsu.sz[root]; current_disconnected_pairs += size * (N - connected_nodes - size); connected_nodes += size; visited_root[root] = true; } } std::vector ans(Q); for (int i = Q - 1; i >= 0; --i) { ans[i] = current_disconnected_pairs; int u = edges[query_edges[i]].first; int v = edges[query_edges[i]].second; int root_u = dsu.find(u); int root_v = dsu.find(v); if (root_u != root_v) { current_disconnected_pairs -= (long long)dsu.sz[root_u] * dsu.sz[root_v]; } dsu.unite(u, v); } for (int i = 0; i < Q; ++i) { std::cout << ans[i] << "\n"; } return 0; }