#include using std::cerr, std::cin, std::cout, std::endl, std::fixed, std::flush; #include using std::vector; #include using std::make_pair, std::move, std::pair, std::swap, std::tuple; static_assert(sizeof(long) == 8); struct UnionFind { vector p; UnionFind(long n) { p.assign(n, -1); } long find(long x) { if (p[x] < 0) { return x; } return p[x] = find(p[x]); } bool unite(long x, long y) { x = find(x); y = find(y); if (x == y) { return false; } if (p[x] > p[y]) { swap(x, y); } p[x] += p[y]; p[y] = x; return true; } bool same(long x, long y) { return (find(x) == find(y)); } long size(long x) { return -p[find(x)]; } }; int main() { long N, M; cin >> N >> M; vector U(M), V(M); for (long i = 0; i < M; i++) { cin >> U[i] >> V[i]; U[i]--, V[i]--; } long Q; cin >> Q; vector B(Q); vector isBrake(M, false); for (long i = 0; i < Q; i++) { cin >> B[i]; B[i]--; isBrake[B[i]] = true; } UnionFind uf(N); long count = N * (N - 1) / 2; for (long i = 0; i < M; i++) { if (not isBrake[i]) { if (uf.same(U[i], V[i])) continue; count -= uf.size(U[i]) * uf.size(V[i]); uf.unite(U[i], V[i]); } } vector ans(Q); for (long i = Q - 1; i >= 0; i--) { ans[i] = count; if (not uf.same(U[B[i]], V[B[i]])) count -= uf.size(U[B[i]]) * uf.size(V[B[i]]); uf.unite(U[B[i]], V[B[i]]); } for (long i = 0; i < Q; i++) { cout << ans[i] << '\n'; } return 0; } /* File : ~/kyopro/yukicoder/554/3200.cpp Date : 2025/07/11 Time : 21:52:00 */