Connect and Disconnect
Are you familiar with DFS, or Depth First Search?
Using this technique, you can determine if a graph is connected in O(E) time. You can also count the number of connected components in a graph within the same time frame.
Have you heard of DSU, or Disjoint Set Union? This data structure allows you to efficiently manage queries like "Add an edge to the graph" and "Count the number of connected components in the graph." Both types of queries can be processed in O(log N).
What about the Dynamic Connectivity Problem? In this problem, you need to quickly handle 3 types of queries:
Add an edge to the graph.
Remove an edge from the graph.
Count the number of connected components in the graph.
Input
Initially, the graph is empty.
The first line of the input contains 2 numbers — N and K — representing the number of vertices and the number of queries (1 ≤ N ≤ 300000, 0 ≤ K ≤ 300000).
The following K lines contain queries, one per line. There are 3 types of queries:
+ u v: Add an edge between vertices u and v. It is guaranteed that at the time of the query, this edge does not exist in the graph.
- u v: Remove an edge between vertices u and v. It is guaranteed that at the time of the query, this edge exists in the graph.
?: Count the number of connected components in the graph at the current moment.
Vertices are numbered from 1 to N. There are no queries where u = v. The graph is undirected.
Output
For each query of type '?', output the number of connected components in the graph at that moment on a separate line.