#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
mt19937 rng(114514);
const int maxn = 1.8e7;
struct node
{
ll cnt, sum;
node(ll cnt0 = 0, ll sum0 = 0)
{
cnt = cnt0;
sum = sum0;
}
node operator + (node n1)
{
return node(cnt + n1.cnt, sum + n1.sum);
}
node operator - (node n1)
{
return node(cnt - n1.cnt, sum - n1.sum);
}
};
unsigned int rd[maxn];
int ls[maxn], rs[maxn], tot;
node sub[maxn];
int nd(ll x, ll y) // x 个 y
{
++tot;
ls[tot] = rs[tot] = 0;
rd[tot] = rng();
sub[tot] = node(x, (ll)x * y);
return tot;
}
void push_up(int p)
{
sub[p] = sub[p] + sub[ls[p]] + sub[rs[p]];
}
int pre(int p, ll len)
{
if(!p || len <= 0)
return 0;
if(sub[p].cnt <= len)
return p;
if(len <= sub[ls[p]].cnt)
return pre(ls[p], len);
int q = ++tot;
sub[q] = sub[p] - sub[ls[p]] - sub[rs[p]];
rd[q] = rd[p];
if(len <= sub[p].cnt - sub[rs[p]].cnt)
{
sub[q].sum = sub[q].sum / sub[q].cnt * (len - sub[ls[p]].cnt);
sub[q].cnt = len - sub[ls[p]].cnt;
}
ls[q] = ls[p];
rs[q] = pre(rs[p], len - sub[p].cnt + sub[rs[p]].cnt);
push_up(q);
return q;
}
int merge(int p, int q)
{
if(!p || !q)
return p + q;
int o = ++tot;
if(rd[p] > rd[q])
{
sub[o] = sub[p] - sub[ls[p]] - sub[rs[p]];
rd[o] = rd[p];
ls[o] = ls[p];
rs[o] = merge(rs[p], q);
}
else
{
sub[o] = sub[q] - sub[ls[q]] - sub[rs[q]];
rd[o] = rd[q];
rs[o] = rs[q];
ls[o] = merge(p, ls[q]);
}
push_up(o);
return o;
}
ll qsum(int p, ll len)
{
if(!p || len <= 0)
return 0;
if(sub[p].cnt <= len)
return sub[p].sum;
if(len <= sub[ls[p]].cnt)
return qsum(ls[p], len);
if(len <= sub[p].cnt - sub[rs[p]].cnt)
return sub[ls[p]].sum + (sub[p].sum - sub[ls[p]].sum - sub[rs[p]].sum) / (sub[p].cnt - sub[ls[p]].cnt - sub[rs[p]].cnt) * (len - sub[ls[p]].cnt);
return sub[p].sum - sub[rs[p]].sum + qsum(rs[p], len - sub[p].cnt + sub[rs[p]].cnt);
}
//void print(int p)
//{
// if(!p)
// return ;
// print(ls[p]);
// printf("(%lld,%lld) ", val[p].cnt, val[p].sum / val[p].cnt);
// print(rs[p]);
//}
struct tag
{
ll w;
int rt;
tag(ll w0 = 0, int rt0 = 0)
{
w = w0;
rt = rt0;
}
tag operator + (tag t1)
{
if(t1.w >= sub[rt].cnt)
return tag(w + t1.w - sub[rt].cnt, t1.rt);
return tag(w, merge(pre(rt, sub[rt].cnt - t1.w), t1.rt));
}
};
tag T[400005];
void f(int p, tag t)
{
T[p] = T[p] + t;
}
void push_down(int p)
{
f(p << 1, T[p]);
f(p << 1 | 1, T[p]);
T[p] = tag();
}
void upd(int p, int l, int r, int ql, int qr, tag t)
{
int mid = (l + r) >> 1;
if(ql <= l && r <= qr)
{
f(p, t);
return ;
}
push_down(p);
if(ql <= mid)
upd(p << 1, l, mid, ql, qr, t);
if(qr > mid)
upd(p << 1 | 1, mid + 1, r, ql, qr, t);
}
ll qry(int p, int l, int r, int q, ll L, ll R)
{
int mid = (l + r) >> 1;
if(l == r)
return qsum(T[p].rt, R) - qsum(T[p].rt, L - 1);
push_down(p);
if(q <= mid)
return qry(p << 1, l, mid, q, L, R);
else
return qry(p << 1 | 1, mid + 1, r, q, L, R);
}
//void dfs(int p, int l, int r)
//{
// int mid = (l + r) >> 1;
// if(l == r)
// {
// printf("#%d: ", l);
// print(T[p].rt);
// printf("\n");
// return ;
// }
// push_down(p);
// dfs(p << 1, l, mid);
// dfs(p << 1 | 1, mid + 1, r);
//}
int main()
{
// freopen("stack.in", "r", stdin);
// freopen("stac.out", "w", stdout);
int n, m, o, l, r;
ll x, y;
scanf("%d%d", &n, &m);
while(m--)
{
scanf("%d", &o);
if(o == 1)
{
scanf("%d%d%lld%lld", &l, &r, &x, &y);
upd(1, 1, n, l, r, tag(0, nd(x, y)));
}
if(o == 2)
{
scanf("%d%d%lld", &l, &r, &x);
upd(1, 1, n, l, r, tag(x, 0));
}
if(o == 3)
{
scanf("%d%lld%lld", &l, &x, &y);
printf("%lld\n", qry(1, 1, n, l, x, y));
}
// dfs(1, 1, n);
}
return 0;
}