#include #include #include #include using namespace std; #define N_MAX 100010 multiset M[N_MAX], N[N_MAX]; int n, m; pair op[N_MAX]; inline int calc(int x) { return ((x&(x-1))^x); } void aib_add(multiset M[], int x, int val, int c) { for (int i = x; i <= n; i += calc(i)) { if (c == 1) { M[i].insert(val); } else { M[i].erase(val); } } } void add_edge(int a, int b) { aib_add(M, a, b, 1); aib_add(N, n-b+1, a, 1); op[++op[0].first] = make_pair(a, b); } void delete_edge(int x) { int a = op[x].first, b = op[x].second; aib_add(M, a, b, -1); aib_add(N, n-b+1, a, -1); } int query_aib(multiset M[], int a, int b, int ra, int rb) { static multiset::iterator it; for (int i = a-1; i > 0; i -= calc(i)) { it = M[i].lower_bound(ra); if (it != M[i].end() && *it <= rb) { return 0; } } return 1; } void query(int a, int b) { int sol = 1; sol &= query_aib(M, a, b, a, b); sol &= query_aib(N, n-b+1, a, a, b); if (sol) { printf("YES\n"); } else { printf("NO\n"); } } int main() { // freopen("input", "r", stdin); //freopen("output", "w", stdout); scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { int type, a, b; scanf("%d", &type); if (type == 1) { scanf("%d%d", &a, &b); add_edge(min(a, b), max(a, b)); } else if (type == 2) { scanf("%d", &a); delete_edge(a); } else { scanf("%d%d", &a, &b); query(a, b); } } return 0; }