/**
 ____ ____ ____ ____ ____ ____
||l |||e |||i |||n |||a |||d ||
||__|||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|/__\|

**/

#include<bits/stdc++.h>
#define endl '\n'

using namespace std;
typedef long long ll;

void speed()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
}
const int maxn = 1e5 + 10;
int n, q;
ll a[maxn], group[maxn], num[maxn];

struct node
{
    ll val, type;

    node()
    {
        val = 0;
        type = 1;
    }
};

int lazy[4 * maxn];
node tree[4 * maxn];

void push_lazy(int root, int left, int right)
{
    lazy[root] %= 2;
    if (lazy[root] == 0)
        return;

    if (left == right)
        tree[root].type *= -1;

    if (left != right)
    {
        lazy[root * 2] += lazy[root];
        lazy[root * 2 + 1] += lazy[root];
    }

    lazy[root] = 0;
}

void range_update(int root, int left, int right, int qleft, int qright)
{
    push_lazy(root, left, right);
    if (left > qright || right < qleft)
        return;

    if (left >= qleft && right <= qright)
    {
        lazy[root] ++;
        push_lazy(root, left, right);
        return;
    }

    int mid = (left + right) / 2;
    range_update(root * 2, left, mid, qleft, qright);
    range_update(root * 2 + 1, mid + 1, right, qleft, qright);
}

void point_update(int root, int left, int right, int idx, int upd_val)
{
    push_lazy(root, left, right);

    if (left == right)
    {
        tree[root].val += upd_val;
        return;
    }

    int mid = (left + right) / 2;
    if (idx <= mid)
        point_update(root * 2, left, mid, idx, upd_val);
    else
        point_update(root * 2 + 1, mid + 1, right, idx, upd_val);
}

ll query(int root, int left, int right, int idx)
{
    push_lazy(root, left, right);
    if (left == right)
        return tree[root].val * tree[root].type;

    int mid = (left + right) / 2;
    if (idx <= mid)
        return query(root * 2, left, mid, idx);

    return query(root * 2 + 1, mid + 1, right, idx);
}

ll query_type(int root, int left, int right, int idx)
{
    push_lazy(root, left, right);
    if (left == right)
        return tree[root].type;// * tree[root].type;

    int mid = (left + right) / 2;
    if (idx <= mid)
        return query_type(root * 2, left, mid, idx);
    return query_type(root * 2 + 1, mid + 1, right, idx);
}


void solve()
{
    cin >> n >> q;
    int type, p, c, l, r;
    ll s;

    lazy[1] = 1;


    for (int i = 1; i <= q; i ++)
    {
        cin >> type;
        if (type == 1 || type == 2)
        {
            cin >> p;
            range_update(1, 1, n, p + 1, n);
        }
        else if (type == 3)
        {
            cin >> c >> s;
            point_update(1, 1, n, c, s);

        }
        else if (type == 4)
        {
            cin >> l >> r;
            ll ans = query(1, 1, n, l);
      /**for (int i = 1; i <= n; i ++)
            cout << query_type(1, 1, n, i) << " ";
            cout << endl;*/
            cout << max(ans, (ll)0) << endl;

        }

    }
}

int main()
{
    speed();
    solve();
    return 0;
}

