/**
 ____ ____ ____ ____ ____ ____
||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];
bool cut[maxn];


struct sub_node
{
    ll sum, lf_max, rf_max;
    int lf_group, rf_group;

    node()
    {
        sum = lf_max = rf_max = 0;
        lf_group = rf_group = 0;
    }
    node(int _sum)
    {
        sum = _sum;
    }

};

struct node
{
    sub_node even, odd;
    int is_free;

    node()
    {
        is_free = 0;
    }

    node (int _is_free)
    {
        is_free = _is_free;
    }
};

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

sub_node merge_sub_node(sub_node nd1, sub_node nd2, int ost)
{
    if (nd1.sum == -1)
        return nd2;
    if (nd2.sum == -1)
        return nd1;
    sub_node nd;
    nd.lf_group = nd1.lf_group;
    nd.rf_group = nd2.rf_group;
    nd.lf_max = nd1.lf_max;
    nd.rf_max = nd2.rf_max;
    nd.sum = nd1.sum + nd2.sum;

    ///cout << nd1.rf_group << " " << nd2.lf_group << " " << nd1.rf_max << " : " << nd2.lf_max << endl;
    if (nd1.rf_group == nd2.lf_group && nd1.rf_group % 2 == ost)
        nd.sum -= min(nd1.rf_max, nd2.lf_max);
    ///cout << nd.sum << endl;

    if (nd1.lf_group == nd1.rf_group && nd1.rf_group == nd2.lf_group)
    {
        nd.lf_max = max(nd1.lf_max, nd2.lf_max);
    }

    if (nd2.lf_group == nd2.rf_group && nd1.rf_group == nd2.lf_group)
    {
        nd.rf_max = max(nd1.rf_max, nd2.rf_max);
    }

    return nd;
}

node merge_node(node nd1, node nd2)
{
    if (nd1.is_free == -1)
        return nd2;
    if (nd2.is_free == -1)
        return nd1;

    node nd;
    nd.even = merge_sub_node(nd1.even, nd2.even, 0);
    nd.odd = merge_sub_node(nd1.odd, nd2.odd, 1);

    return nd;
}



void push_lazy(int root, int left, int right)
{
    if (abs(lazy[root]) % 2 == 1)
    {
        swap(tree[root].even, tree[root].odd);
    }

    tree[root].even.lf_group += lazy[root];
    tree[root].even.rf_group += lazy[root];
    tree[root].odd.lf_group += lazy[root];
    tree[root].odd.rf_group += lazy[root];

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

    lazy[root] = 0;
}



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

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

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

    tree[root] = merge_node(tree[root * 2], tree[root * 2 + 1]);
}

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

    if (left == right)
    {
        if (tree[root].even.lf_group % 2 == 0)
        {
            tree[root].even.sum += val;
            tree[root].even.lf_max += val;
            tree[root].even.rf_max += val;
        }
        else
        {
            tree[root].odd.sum += val;
            tree[root].odd.lf_max += val;
            tree[root].odd.rf_max += val;
        }
        return;
    }

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

    tree[root] = merge_node(tree[root * 2], tree[root * 2 + 1]);

}

node query(int root, int left, int right, int qleft, int qright)
{
    push_lazy(root, left, right);
    if (left > qright || right < qleft)
        return node(-1);

    if (left >= qleft && right <= qright)
        return tree[root];

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


/**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 precompute()
{
    for (int i = 0; i <= n; i ++)
        num[i] = 0;
    group[1] = 0;
    num[group[1]] = max(num[group[1]], a[1]);
    for (int i = 2; i <= n; i ++)
    {
        group[i] = group[i - 1];
        if (cut[i - 1])
            group[i] ++;

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


    bool first = true;

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

        }
        else if (type == 4)
        {

            cin >> l >> r;
            node ans = query(1, 1, n, l, r);
            cout << ans.odd.sum << endl;

        }

        /**for (int j = 1; j <= n; j ++)
        {
            node ans = query(1, 1, n, j, j);
            cout << ans.even.lf_group << " ";
        }
        node ans = query(1, 1, n, 1, 4);
        cout << endl;
        cout << ans.odd.sum << " " << ans.even.sum <<  endl;*/


    }
}

int main()
{
    speed();
    solve();
    return 0;
}
/**
10 20
1 4
3 3 7
3 4 1
3 5 8
3 6 5
1 1
3 10 3
3 9 2
3 8 9
1 8
3 9 8
1 7
3 2 6
2 1
4 2 9
*/
