#include #include #include #include using namespace std; const int INF = 1 << 30; const int MAX_N = 100100; #define mn first #define mx second struct RangeTree { RangeTree() : r(4 * MAX_N) {} vector> r; void update(int node, int lo, int hi, int pos, const pair &vals); pair query(int node, int lo, int hi, int a, int b); } RT; int N, M; set graph[MAX_N]; vector> edges; void add_edge(int a, int b); void remove_edge(int edge); void update(int node); bool query(int a, int b); inline pair best_pair(const pair &a, const pair &b); int main() { cin >> N >> M; for (int i = 1; i <= N; i += 1) RT.update(1, 1, N, i, make_pair(i, i)); for (int i = 1, op, a, b; i <= M; i += 1) { cin >> op >> a; if (op == 1) { cin >> b; add_edge(a, b); } else if (op == 2) { remove_edge(a); } else { cin >> b; if (query(a, b)) { cout << "YES\n"; } else { cout << "NO\n"; } } } } inline void add_edge(int a, int b) { edges.push_back(make_pair(a, b)); graph[a].insert(b); graph[b].insert(a); update(a); update(b); } inline void remove_edge(int edge) { int a = edges[edge - 1].first; int b = edges[edge - 1].second; graph[a].erase(b); graph[b].erase(a); update(a); update(b); } inline void update(int node) { pair vals; if (graph[node].empty()) { vals = make_pair(node, node); } else { vals = make_pair(*graph[node].begin(), *graph[node].rbegin()); } RT.update(1, 1, N, node, vals); } inline bool query(int a, int b) { pair vals = RT.query(1, 1, N, a, b); return (vals.mn >= a && vals.mx <= b); } void RangeTree::update(int node, int lo, int hi, int pos, const pair &vals) { if (lo == hi) { r[node] = vals; return; } int mid = lo + (hi - lo) / 2; int st = node * 2, dr = st + 1; if (pos <= mid) update(st, lo, mid, pos, vals); else update(dr, mid + 1, hi, pos, vals); r[node] = best_pair(r[st], r[dr]); } pair RangeTree::query(int node, int lo, int hi, int a, int b) { if (lo == hi || (a <= lo && hi <= b)) { return r[node]; } int mid = lo + (hi - lo) / 2; int st = node * 2, dr = st + 1; pair result = make_pair(INF, -INF); if (a <= mid) { result = best_pair(result, query(st, lo, mid, a, b)); } if (b > mid) { result = best_pair(result, query(dr, mid + 1, hi, a, b)); } return result; } inline pair best_pair(const pair &a, const pair &b) { return make_pair(min(a.mn, b.mn), max(a.mx, b.mx)); }