#include<bits/stdc++.h>
using namespace std;
const long long maxn = 200002;
long long n,q;
long long cnt = 0;
long long a[maxn];
long long lamp[maxn];
vector<long long>v;
pair<long long,long long>seg[maxn];
long long tree_a[maxn*4];
long long tree_seg[maxn*4];
void make_tree_a( long long i, long long l, long long r )
{
    if( l == r )
    {
        tree_a[i] = a[l];
        return;
    }
    long long m = ( l + r ) / 2;
    make_tree_a(i*2,l,m);
    make_tree_a(i*2+1,m+1,r);
    tree_a[i] = max( tree_a[i*2], tree_a[i*2+1] );
    return;
}
long long query_a( long long i, long long l, long long r, long long ql, long long qr )
{
    if( l == ql && r == qr ) return tree_a[i];
    long long m = ( l + r ) / 2;
    if( qr <= m ) return query_a(i*2,l,m,ql,qr);
    else if( ql > m ) return query_a(i*2+1,m+1,r,ql,qr);
    else return max( query_a(i*2,l,m,ql,m), query_a(i*2+1,m+1,r,m+1,qr) );
}
void make_tree_seg( long long i, long long l, long long r )
{
    if( l == r )
    {
        if( l % 2 == 1 ) return;
        long long from = seg[l].first;
        long long to = seg[l].second;
        tree_seg[i] = query_a(1,1,n,from,to);
        return;
    }
    long long m = ( l + r ) / 2;
    make_tree_seg(i*2,l,m);
    make_tree_seg(i*2+1,m+1,r);
    tree_seg[i] = tree_seg[i*2] + tree_seg[i*2+1];
    return;
}
long long query_seg( long long i, long long l, long long r, long long ql, long long qr )
{
    if( l == ql && r == qr ) return tree_seg[i];
    long long m = ( l + r ) / 2;
    if( qr <= m ) return query_seg(i*2,l,m,ql,qr);
    else if( ql > m ) return query_seg(i*2+1,m+1,r,ql,qr);
    else return ( query_seg(i*2,l,m,ql,m),  query_seg(i*2+1,m+1,r,m+1,qr) );
}
void fill_v_seg()
{
    lamp[n] = 1;
    for( long long i = 1; i <= n; i ++ )
    {
        if( lamp[i] == 1 )
        {
            cnt += 1;
            if( v.size() == 0 )
            {
                seg[cnt].first = 1;
                seg[cnt].second = i;
            }
            else
            {
                seg[cnt].first = v[v.size()-1] + 1;
                seg[cnt].second = i;
            }
            //cout << seg[cnt].first << " " << seg[cnt].second << endl;
            if( i != n ) v.push_back(i);
        }
    }
}
long long bin_search( long long pos )
{
    long long l = 0;
    long long r = cnt - 1;
    while( l <= r )
    {
        long long m = ( l + r ) / 2;
        if( v[m] < pos ) l = m + 1;
        else r = m - 1;
    }
    return min(r+2,cnt);
}
void read()
{
    cin >> n >> q;
    long long tlamp = 0;
    for( long long i = 1; i <= q; i ++ )
    {
        long long type;
        cin >> type;
        if( type == 1 )
        {
            long long pos;
            cin >> pos;
            lamp[pos] = 1;
        }
        else if( type == 2 )
        {
            long long pos;
            cin >> pos;
            lamp[pos] = 0;
        }
        else if( type == 3 )
        {
            long long pos,x;
            cin >> pos >> x;
            a[pos] += x;
        }
        else
        {
            if( tlamp == 0 )
            {
                fill_v_seg();
                make_tree_a(1,1,n);
                make_tree_seg(1,1,cnt);
            }
            tlamp = 1;
            long long ql,qr;
            cin >> ql >> qr;
            long long x = bin_search(ql);
            //cout << 1111 << endl;
            long long y = bin_search(qr);
            long long ans = 0;
            //cout << x << " " << y << endl;
            if( x+1 <= y-1 ) ans += query_seg(1,1,cnt,x+1,y-1);
            if( x != y )
            {
                if( x % 2 == 0 ) ans += query_a(1,1,n,ql,seg[x].second);
                if( y % 2 == 0 ) ans += query_a(1,1,n,seg[y].first,qr);
            }
            else if( x % 2 == 0 ) ans += query_a(1,1,n,ql,qr);
            cout << ans << endl;
        }
    }
}
int main()
{
    read();
    return 0;
}
