#include <iostream>
#include <vector>
using namespace std;

struct node {
    int value = 0;
    node * right, * left;
    int l, r;
    int unPushed = 0;
    node(int l, int r) : left(nullptr), right(nullptr), l(l), r(r) { }
    node * clone() {
        node * ans = new node(l, r);
        ans -> right = right;
        ans -> left = left;
        ans -> value = value;
        ans -> unPushed = unPushed;
        return ans;
    }
};
vector<node *> v;
int sum(node * left, node * right) {
    int ans = 0;
    if(left != nullptr) ans += left -> value;
    if(right != nullptr) ans += right -> value;
    return ans;
}
void push(node *(&k)) {
    k -> unPushed %= 2;
    if (k -> unPushed) {
        int center = (k -> l + k -> r) / 2;
        if (k -> left == nullptr) k -> left = new node(k -> l, center);
        else k -> left = k -> left -> clone();
        if (k -> right == nullptr) k -> right = new node(center + 1, k -> r);
        else k -> right = k -> right -> clone();
        ++k -> left -> unPushed;
        ++k -> right -> unPushed;
        k -> left -> value = (center - k -> l + 1) - k -> left -> value;
        k -> right -> value = (k -> r - center) - k -> right -> value;
        k -> unPushed = 0;
    }
   
}
void updateSegment(node *(&k), int left, int right, int l, int r) {
    if(k == nullptr) k = new node(left, right);
    else k = k -> clone();
    if(l > r) return;
    if(l == left && r == right) {
        ++k -> unPushed;
        k -> value = (r - l + 1) - k -> value;
        return;
    }
    int center = (left + right) / 2;
    push(k);
    updateSegment(k -> left, left, center, l, min(r, center));
    updateSegment(k -> right, center + 1, right, max(l, center + 1), r);
    push(k -> left);
    push(k -> right);
    k -> value = sum(k -> left, k -> right);
}
void update(node *&k, int left, int right, int pos, int a) {
    if (k == nullptr) k = new node(left, right);
    else k = k -> clone();
    if (left == right) {
        k -> value = a;
        return;
    }
    int center = (left + right) / 2;
    push(k);
    if(pos <= center) {
        update(k -> left, left, center, pos, a);
        push(k -> left);
    }
    else {
        update(k -> right, center + 1, right, pos, a);
        push(k -> right);
    }
    k -> value = sum (k -> left, k -> right);
}
int query(node *k, int left, int right, int l, int r) {
    if (l > r) return 0;
    if(k == nullptr) return 0;
    if(left == l && r == right) return k -> value;
    int center = (left + right) / 2;
    push(k);
    return query(k -> left, left, center, l, min(center, r)) + query(k -> right, center + 1, right, max(l, center + 1), r);
}

int main() {
	int n, m, type, pos, l, r;
	scanf("%d %d", &n, &m);
    v.push_back(new node(1, n));
    for(int i = 1; i <= m; i++) {
        scanf("%d", &type);
        if(type <= 2) {
            scanf("%d", &pos);
            type = 2 - type;
            v.push_back(v.back() -> clone());
            int k = query(v.back(), 1, n, pos, pos);
            if(k != type) updateSegment(v.back(), 1, n, pos, pos);
        }
        else if(type == 3) {
            scanf("%d %d", &l, &r);
            v.push_back(v.back() -> clone());
            updateSegment(v.back(), 1, n, l, r);
        }
        else if(type == 4) {
            scanf("%d", &pos);
            v.push_back(v[pos] -> clone());
        }
        else if(type == 5) {
            scanf("%d %d", &l, &r);
            v.push_back(v.back() -> clone());
            printf("%d\n", query(v.back(), 1, n, l, r));
        }
    }
    return 0;
}