З`єднання та роз`єднання
Ви коли-небудь чули про обхід в глибину? Наприклад, використовуючи цей алгоритм, ви можете перевірити, чи є граф зв'язним, за час O(E). Ви можете навіть порахувати кількість компонент зв'язності за цей же час.
А ви коли-небудь чули про систему множин, які не перетинаються? Використовуючи цю структуру, ви можете швидко опрацьовувати запити "Додати ребро в граф" та "Порахувати кількість компонент зв'язності у графі".
А ви коли-небудь чули про динамічну задачі зв'язності? У цій задачі вам потрібно опрацьовувати три типи запитів:
Додати ребро в граф.
Видалити ребро з графа.
Порахувати кількість компонент зв'язності у графі.
Вхідні дані
Спочатку граф порожній.
У першому рядку знаходяться два цілих числа N та K - кількість вершин та кількість запитів відповідно (1 ≤ N ≤ 300000, 0 ≤ K ≤ 300000). Наступні K рядків містять запити, по одному у рядку. Є три типи запитів:
+ u v: Додати ребро між вершинами u та v. Гарантується, що такого ребра немає.
- u v: Видалити ребро між u та v. Гарантується, що таке ребро є.
?: Порахувати кількість компонент зв'язності у графі.
Вершини пронумеровано цілими числами від 1 до N. У всіх запитах u ≠ v. граф вважається неорієнтовним.
Вихідні дані
Для кожного запиту типу "?", виведіть кількість компонент зв'язності у момент запиту.