#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,bmi")
#include <bits/stdc++.h>
#include <ext/random>
using namespace std;
#define all(x) begin(x), end(x)
#ifdef CKISEKI
#define safe cerr << __PRETTY_FUNCTION__ << " line " << __LINE__ << " safe\n"
#define debug(a...) debug_(#a, a)
#define orange(a...) orange_(#a, a)
void debug_(auto s, auto ...a) {
cerr << "\e[1;32m(" << s << ") = (";
int f = 0;
(..., (cerr << (f++ ? ", " : "") << a));
cerr << ")\e[0m\n";
}
#include <experimental/iterator>
void orange_(auto s, auto L, auto R) {
cerr << "\e[1;33m[ " << s << " ] = [ ";
using namespace experimental;
copy(L, R, make_ostream_joiner(cerr, ", "));
cerr << " ]\e[0m\n";
}
#else
#define safe ((void)0)
#define debug(...) safe
#define orange(...) safe
#endif
namespace {
static inline int gc() {
constexpr int B = 1 << 20;
static char buf[B], *p, *q;
if (p == q)
q = (p = buf) + fread_unlocked(buf, 1, B, stdin);
return q == buf ? EOF : *p++;
}
void gn(auto &x) {
x = 0;
int c = gc();
while ('0' > c or c > '9')
c = gc();
while ('0' <= c and c <= '9')
x = x * 10 + c - '0', c = gc();
}
void gn(auto &x, auto& ...oth) {
gn(x), gn(oth...);
}
using lld = int64_t;
namespace treap {
struct Node {
lld tot_copy, sum;
int val;
int copy;
int lc, rc;
int sz;
};
const int maxn = 100025, lg = 20;
constexpr int MEM = 24'000'000;
Node T[MEM];
bool inuse[MEM];
int counter;
int inc_counter() {
while (inuse[counter+1]) {
++counter;
}
return ++counter;
}
void pull(int o) {
T[o].sz = 1;
T[o].tot_copy = T[o].copy;
T[o].sum = 1LL * T[o].copy * T[o].val;
for (int c : {T[o].lc, T[o].rc})
if (c) {
T[o].sz += T[c].sz;
T[o].tot_copy += T[c].tot_copy;
T[o].sum += T[c].sum;
}
}
int new_node(int x, int y) {
int ret = inc_counter();
T[ret].val = x;
T[ret].copy = y;
T[ret].lc = T[ret].rc = 0;
pull(ret);
return ret;
}
__gnu_cxx::sfmt19937 rng(114514);
int merge(int a, int b) {
if (!a || !b) return a ? a : b;
assert(T[a].sz + T[b].sz - 1 >= 0);
int r = uniform_int_distribution<int>(0, T[a].sz + T[b].sz - 1)(rng);
int ret = inc_counter();
if (r < T[a].sz) {
T[ret] = T[a];
T[ret].rc = merge(T[a].rc, b);
} else {
T[ret] = T[b];
T[ret].lc = merge(a, T[b].lc);
}
pull(ret);
return ret;
}
lld query(int o, lld k) {
if (!k) return 0;
const lld s = T[o].tot_copy;
assert(s >= k);
lld left = T[o].lc ? T[T[o].lc].tot_copy : 0;
if (k <= left) {
return query(T[o].lc, k);
} else if (k <= left + T[o].copy) {
return (T[o].lc ? T[T[o].lc].sum : 0) + 1LL * T[o].val * (k - left);
} else {
return (T[o].lc ? T[T[o].lc].sum : 0) + 1LL * T[o].val * T[o].copy + query(T[o].rc, k - left - T[o].copy);
}
}
int splitPrefix(int o, lld k) {
assert(o > 0);
if (!k) return 0;
lld left = T[o].lc ? T[T[o].lc].tot_copy : 0;
if (k <= left) {
return splitPrefix(T[o].lc, k);
} else if (k <= left + T[o].copy) {
int ret = inc_counter();
T[ret].val = T[o].val;
T[ret].copy = k - left;
T[ret].lc = T[o].lc;
T[ret].rc = 0;
pull(ret);
return ret;
} else {
int ret = inc_counter();
T[ret].val = T[o].val;
T[ret].copy = T[o].copy;
T[ret].lc = T[o].lc;
T[ret].rc = splitPrefix(T[o].rc, k - left - T[o].copy);
pull(ret);
return ret;
}
}
int pop_stack(int o, lld k) {
const lld s = T[o].tot_copy;
assert(s >= k);
return splitPrefix(o, s - k);
}
#ifdef CKISEKI
void dump(int o, vector<pair<lld,lld>> &v) {
if (!o) return;
dump(T[o].lc, v);
v.emplace_back(T[o].val, T[o].copy);
dump(T[o].rc, v);
}
#endif
int mark = 0;
void scan(int o) {
if (!o or inuse[o])
return;
mark++;
inuse[o] = true;
scan(T[o].lc), scan(T[o].rc);
}
}
struct Tag {
lld pop;
int push;
Tag() : pop(0), push(0) {}
Tag &operator+=(const Tag &rhs) {
lld sz = push ? treap::T[push].tot_copy : 0;
if (rhs.pop >= sz) {
pop += rhs.pop - sz;
push = rhs.push;
} else {
push = treap::pop_stack(push, rhs.pop);
push = treap::merge(push, rhs.push);
}
return *this;
}
};
namespace std {
template <typename U, typename V>
ostream &operator<<(ostream &o, pair<U, V> p) {
return o<<p.first<<','<<p.second;
}
}
struct Segtree {
int n;
vector<Tag> st;
Segtree(int n_) : n(n_), st(n * 2) {}
void upd(int p, const Tag &tg) {
st[p] += tg;
}
void push(int p) {
for (int h = __lg(n); h >= 0; h--) {
int i = p >> h;
if (i <= 1) continue;
upd(i, st[i >> 1]);
upd(i ^ 1, st[i >> 1]);
st[i >> 1] = Tag();
}
}
void apply(int l, int r, const Tag &tg) {
push(l + n), push(r - 1 + n);
for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
if (l & 1) upd(l++, tg);
if (r & 1) upd(--r, tg);
}
}
lld query(int p, lld L, lld R) {
--L;
push(p += n);
int node = st[p].push;
lld sz = node ? treap::T[node].tot_copy : 0;
L = clamp<lld>(L, 0, sz);
R = clamp<lld>(R, 0, sz);
// vector<pair<lld,lld>> v;
// treap::dump(node, v);
// orange(all(v));
return treap::query(node, R) - treap::query(node, L);
}
void scan() {
for (int i = 0; i < 2*n; ++i) {
treap::scan(st[i].push);
}
}
};
}
int main() {
//cin.tie(nullptr)->sync_with_stdio(false);
int n, m;
gn(n, m);
//cin >> n >> m;
Segtree sgt(n);
while (m--) {
if (treap::counter > treap::MEM - 2000) {
if (treap::mark) {
memset(treap::inuse, 0, sizeof(treap::inuse));
treap::mark = 0;
}
sgt.scan();
debug("rebuild", treap::counter, treap::mark);
treap::counter = 0;
}
int t;
//cin >> t;
gn(t);
if (t == 1) {
int l, r, x, y;
//cin >> l >> r >> x >> y;
gn(l, r, x, y);
--l;
Tag tg;
tg.push = treap::new_node(y, x);
sgt.apply(l, r, tg);
} else if (t == 2) {
int l, r;
lld w;
//cin >> l >> r >> w;
gn(l, r, w);
--l;
Tag tg;
tg.pop = w;
sgt.apply(l, r, tg);
} else {
int k;
lld p, q;
//cin >> k >> p >> q;
gn(k, p, q);
--k;
//cout << sgt.query(k, p, q) << '\n';
printf("%" PRId64 "\n", sgt.query(k, p, q));
}
}
return 0;
}