#include using namespace std; struct Query { int type, a, b; }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector> initial(m); vector vertices; vertices.reserve(2 * m + 2 * 3000); for (auto& [u, v] : initial) { cin >> u >> v; vertices.push_back(u); vertices.push_back(v); } int q; cin >> q; vector queries(q); for (auto& [type, a, b] : queries) { cin >> type >> a >> b; vertices.push_back(a); if (type == 1) vertices.push_back(b); } sort(vertices.begin(), vertices.end()); vertices.erase(unique(vertices.begin(), vertices.end()), vertices.end()); auto compress = [&](int x) { return int(lower_bound(vertices.begin(), vertices.end(), x) - vertices.begin()); }; int sz = vertices.size(); for (auto& [u, v] : initial) { u = compress(u); v = compress(v); } for (auto& [type, a, b] : queries) { a = compress(a); if (type == 1) b = compress(b); } vector> edges = initial; for (auto [type, a, b] : queries) { if (type == 1) edges.emplace_back(a, b); } sort(edges.begin(), edges.end()); edges.erase(unique(edges.begin(), edges.end()), edges.end()); int e = edges.size(); vector> out(sz); for (int i = 0; i < e; ++i) { out[edges[i].first].push_back(i); } vector active(e, false); for (auto [u, v] : initial) { int id = lower_bound(edges.begin(), edges.end(), pair{u, v}) - edges.begin(); active[id] = true; } const int B = max(1, int(sqrt(e)) + 1); vector heavy, heavy_id(sz, -1); for (int u = 0; u < sz; ++u) { if ((int)out[u].size() > B) { heavy_id[u] = heavy.size(); heavy.push_back(u); } } vector locked(sz, false); vector cnt(heavy.size(), 0); int locked_count = 0; for (auto [type, a, b] : queries) { if (type == 1) { int id = lower_bound(edges.begin(), edges.end(), pair{a, b}) - edges.begin(); active[id] = !active[id]; if (heavy_id[a] != -1 && locked[b]) { cnt[heavy_id[a]] += active[id] ? 1 : -1; } } else { locked[a] = !locked[a]; int delta = locked[a] ? 1 : -1; locked_count += delta; for (int i = 0; i < (int)heavy.size(); ++i) { int u = heavy[i]; auto it = lower_bound( edges.begin(), edges.end(), pair{u, a}); if (it == edges.end() || *it != pair{u, a}) continue; int id = it - edges.begin(); if (active[id]) cnt[i] += delta; } } int c = 0; if (heavy_id[a] != -1) { c = cnt[heavy_id[a]]; } else { for (int id : out[a]) { if (active[id] && locked[edges[id].second]) ++c; } } cout << n - locked_count + c - !locked[a] << '\n'; } return 0; }