#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef map<int, int> mii;
typedef map<ll, ll> mll;
typedef set<int> si;
typedef set<ll> sll;
typedef priority_queue<int> max_heap_i;
typedef priority_queue<int, vi, greater<int>> min_heap_i;
typedef priority_queue<ll> max_heap_ll;
typedef priority_queue<ll, vll, greater<ll>> min_heap_ll;
#define FOR(a, b, c) for (int a = (b); a <= (c); a++)
#define FORD(a, b, c) for (int a = (b); a >= (c); a--)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define REPD(i, n) for (int i = (n) - 1; i >= 0; i--)
#define endl '\n'
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define BIT(n) (1 << (n))
#define SET(k, n) ((n) | BIT(k))
#define CLEAR(k, n) ((n) & ~BIT(k))
#define TOGGLE(k, n) ((n) ^ BIT(k))
#define CHECK(k, n) (!!((n) & BIT(k)))
#define MSB(x) ((x) == 0 ? -1 : 63 - __builtin_clzll(x))
#define debug(x) clog << #x << " = " << (x) << endl
const int MAXARR = 1e7 + 15;
const int INF = 1e9 + 7;
const ll INF64 = 2e18 + 7;
const int MOD = 1e9 + 7;
void fixIO()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
}
void File(const string &fileName = "")
{
if (fopen((fileName + ".INP").c_str(), "r"))
{
freopen((fileName + ".INP").c_str(), "r", stdin);
freopen((fileName + ".OUT").c_str(), "w", stdout);
}
}
int n, q;
void Read()
{
cin >> n >> q;
}
vll tree, lazyadd, lazymul;
// $x \rightarrow (x \times mul + add) \pmod{MOD}$
void Apply(int node, int left, int right, ll mul, ll add)
{
ll len = right - left + 1;
tree[node] = (tree[node] * mul % MOD + add * len % MOD) % MOD;
lazymul[node] = (lazymul[node] * mul) % MOD;
lazyadd[node] = (lazyadd[node] * mul % MOD + add) % MOD;
}
void Pushdown(int node, int left, int right)
{
if (lazyadd[node] == 0 && lazymul[node] == 1)
{
return;
}
int mid = left + (right - left) / 2;
Apply(node * 2, left, mid, lazymul[node], lazyadd[node]);
Apply(node * 2 + 1, mid + 1, right, lazymul[node], lazyadd[node]);
lazymul[node] = 1;
lazyadd[node] = 0;
}
void Update1(int node, int left, int right, int qleft, int qright, ll val)
{
if (qleft <= left && right <= qright)
{
Apply(node, left, right, 1, val % MOD);
return;
}
Pushdown(node, left, right);
int mid = left + (right - left) / 2;
if (qleft <= mid)
{
Update1(node * 2, left, mid, qleft, qright, val);
}
if (qright > mid)
{
Update1(node * 2 + 1, mid + 1, right, qleft, qright, val);
}
tree[node] = (tree[node * 2] + tree[node * 2 + 1]) % MOD;
}
void Update2(int node, int left, int right, int qleft, int qright, ll val)
{
if (qleft <= left && right <= qright)
{
Apply(node, left, right, val % MOD, 0);
return;
}
Pushdown(node, left, right);
int mid = left + (right - left) / 2;
if (qleft <= mid)
{
Update2(node * 2, left, mid, qleft, qright, val);
}
if (qright > mid)
{
Update2(node * 2 + 1, mid + 1, right, qleft, qright, val);
}
tree[node] = (tree[node * 2] + tree[node * 2 + 1]) % MOD;
}
ll Query(int node, int left, int right, int qleft, int qright)
{
if (qleft <= left && right <= qright)
{
return tree[node];
}
Pushdown(node, left, right);
int mid = left + (right - left) / 2;
ll res = 0;
if (qleft <= mid)
{
res = (res + (Query(node * 2, left, mid, qleft, qright))) % MOD;
}
if (qright > mid)
{
res = (res + (Query(node * 2 + 1, mid + 1, right, qleft, qright))) % MOD;
}
return res;
}
void Solve()
{
tree.assign(4 * n + 7, 0);
lazyadd.assign(4 * n + 7, 0);
lazymul.assign(4 * n + 7, 1);
while(q --)
{
int type;
cin >> type;
if (type == 1)
{
int left, right, val;
cin >> left >> right >> val;
Update1(1, 1, n, left, right, val);
}
else if (type == 2)
{
int left, right, val;
cin >> left >> right >> val;
Update2(1, 1, n, left, right, val);
}
else
{
int left, right;
cin >> left >> right;
cout << Query(1, 1, n, left, right) << endl;
}
}
}
int main()
{
fixIO();
File("queryit");
Read();
Solve();
return 0;
}
/*
* Code by github/nmkdeveloper.
* I didn't fall in love with you. I walked into love with you, with my eyes wide open, choosing to take every step along the way <3.
*/
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIGxvbmcgbG9uZyBsbDsKdHlwZWRlZiB1bnNpZ25lZCBsb25nIGxvbmcgdWxsOwp0eXBlZGVmIGxvbmcgZG91YmxlIGxkOwp0eXBlZGVmIHZlY3RvcjxpbnQ+IHZpOwp0eXBlZGVmIHZlY3RvcjxsbD4gdmxsOwp0eXBlZGVmIHZlY3Rvcjxib29sPiB2YjsKdHlwZWRlZiB2ZWN0b3I8c3RyaW5nPiB2czsKdHlwZWRlZiBwYWlyPGludCwgaW50PiBwaWk7CnR5cGVkZWYgcGFpcjxsbCwgbGw+IHBsbDsKdHlwZWRlZiBwYWlyPGludCwgbGw+IHBpbDsKdHlwZWRlZiBwYWlyPGxsLCBpbnQ+IHBsaTsKdHlwZWRlZiB2ZWN0b3I8cGlpPiB2cGlpOwp0eXBlZGVmIHZlY3RvcjxwbGw+IHZwbGw7CnR5cGVkZWYgbWFwPGludCwgaW50PiBtaWk7CnR5cGVkZWYgbWFwPGxsLCBsbD4gbWxsOwp0eXBlZGVmIHNldDxpbnQ+IHNpOwp0eXBlZGVmIHNldDxsbD4gc2xsOwp0eXBlZGVmIHByaW9yaXR5X3F1ZXVlPGludD4gbWF4X2hlYXBfaTsKdHlwZWRlZiBwcmlvcml0eV9xdWV1ZTxpbnQsIHZpLCBncmVhdGVyPGludD4+IG1pbl9oZWFwX2k7CnR5cGVkZWYgcHJpb3JpdHlfcXVldWU8bGw+IG1heF9oZWFwX2xsOwp0eXBlZGVmIHByaW9yaXR5X3F1ZXVlPGxsLCB2bGwsIGdyZWF0ZXI8bGw+PiBtaW5faGVhcF9sbDsKCiNkZWZpbmUgRk9SKGEsIGIsIGMpIGZvciAoaW50IGEgPSAoYik7IGEgPD0gKGMpOyBhKyspCiNkZWZpbmUgRk9SRChhLCBiLCBjKSBmb3IgKGludCBhID0gKGIpOyBhID49IChjKTsgYS0tKQojZGVmaW5lIFJFUChpLCBuKSBmb3IgKGludCBpID0gMDsgaSA8IChuKTsgaSsrKQojZGVmaW5lIFJFUEQoaSwgbikgZm9yIChpbnQgaSA9IChuKSAtIDE7IGkgPj0gMDsgaS0tKQojZGVmaW5lIGVuZGwgJ1xuJwojZGVmaW5lIGZpIGZpcnN0CiNkZWZpbmUgc2Ugc2Vjb25kCiNkZWZpbmUgcGIgcHVzaF9iYWNrCiNkZWZpbmUgZWIgZW1wbGFjZV9iYWNrCiNkZWZpbmUgYWxsKHgpICh4KS5iZWdpbigpLCAoeCkuZW5kKCkKI2RlZmluZSByYWxsKHgpICh4KS5yYmVnaW4oKSwgKHgpLnJlbmQoKQojZGVmaW5lIHN6KHgpIChpbnQpKHgpLnNpemUoKQoKI2RlZmluZSBCSVQobikgKDEgPDwgKG4pKQojZGVmaW5lIFNFVChrLCBuKSAoKG4pIHwgQklUKGspKQojZGVmaW5lIENMRUFSKGssIG4pICgobikgJiB+QklUKGspKQojZGVmaW5lIFRPR0dMRShrLCBuKSAoKG4pIF4gQklUKGspKQojZGVmaW5lIENIRUNLKGssIG4pICghISgobikgJiBCSVQoaykpKQojZGVmaW5lIE1TQih4KSAoKHgpID09IDAgPyAtMSA6IDYzIC0gX19idWlsdGluX2NsemxsKHgpKQoKI2RlZmluZSBkZWJ1Zyh4KSBjbG9nIDw8ICN4IDw8ICIgPSAiIDw8ICh4KSA8PCBlbmRsCgpjb25zdCBpbnQgTUFYQVJSID0gMWU3ICsgMTU7CmNvbnN0IGludCBJTkYgPSAxZTkgKyA3Owpjb25zdCBsbCBJTkY2NCA9IDJlMTggKyA3Owpjb25zdCBpbnQgTU9EID0gMWU5ICsgNzsKCnZvaWQgZml4SU8oKQp7CiAgICBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKICAgIGNpbi50aWUobnVsbHB0cik7Cn0KCnZvaWQgRmlsZShjb25zdCBzdHJpbmcgJmZpbGVOYW1lID0gIiIpCnsKICAgIGlmIChmb3BlbigoZmlsZU5hbWUgKyAiLklOUCIpLmNfc3RyKCksICJyIikpCiAgICB7CiAgICAgICAgZnJlb3BlbigoZmlsZU5hbWUgKyAiLklOUCIpLmNfc3RyKCksICJyIiwgc3RkaW4pOwogICAgICAgIGZyZW9wZW4oKGZpbGVOYW1lICsgIi5PVVQiKS5jX3N0cigpLCAidyIsIHN0ZG91dCk7CiAgICB9Cn0KCmludCBuLCBxOwoKdm9pZCBSZWFkKCkKewogICAgY2luID4+IG4gPj4gcTsKfQoKdmxsIHRyZWUsIGxhenlhZGQsIGxhenltdWw7CgoKLy8gJHggXHJpZ2h0YXJyb3cgKHggXHRpbWVzIG11bCArIGFkZCkgXHBtb2R7TU9EfSQKdm9pZCBBcHBseShpbnQgbm9kZSwgaW50IGxlZnQsIGludCByaWdodCwgbGwgbXVsLCBsbCBhZGQpCnsKICAgIGxsIGxlbiA9IHJpZ2h0IC0gbGVmdCArIDE7CiAgICB0cmVlW25vZGVdID0gKHRyZWVbbm9kZV0gKiBtdWwgJSBNT0QgKyBhZGQgKiBsZW4gJSBNT0QpICUgTU9EOwogICAgbGF6eW11bFtub2RlXSA9IChsYXp5bXVsW25vZGVdICogbXVsKSAlIE1PRDsKICAgIGxhenlhZGRbbm9kZV0gPSAobGF6eWFkZFtub2RlXSAqIG11bCAlIE1PRCArIGFkZCkgJSBNT0Q7Cn0KCnZvaWQgUHVzaGRvd24oaW50IG5vZGUsIGludCBsZWZ0LCBpbnQgcmlnaHQpCnsKICAgIGlmIChsYXp5YWRkW25vZGVdID09IDAgJiYgbGF6eW11bFtub2RlXSA9PSAxKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGludCBtaWQgPSBsZWZ0ICsgKHJpZ2h0IC0gbGVmdCkgLyAyOwogICAgQXBwbHkobm9kZSAqIDIsIGxlZnQsIG1pZCwgbGF6eW11bFtub2RlXSwgbGF6eWFkZFtub2RlXSk7CiAgICBBcHBseShub2RlICogMiArIDEsIG1pZCArIDEsIHJpZ2h0LCBsYXp5bXVsW25vZGVdLCBsYXp5YWRkW25vZGVdKTsKICAgIGxhenltdWxbbm9kZV0gPSAxOwogICAgbGF6eWFkZFtub2RlXSA9IDA7Cn0KCnZvaWQgVXBkYXRlMShpbnQgbm9kZSwgaW50IGxlZnQsIGludCByaWdodCwgaW50IHFsZWZ0LCBpbnQgcXJpZ2h0LCBsbCB2YWwpCnsKICAgIGlmIChxbGVmdCA8PSBsZWZ0ICYmIHJpZ2h0IDw9IHFyaWdodCkKICAgIHsKICAgICAgICBBcHBseShub2RlLCBsZWZ0LCByaWdodCwgMSwgdmFsICUgTU9EKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBQdXNoZG93bihub2RlLCBsZWZ0LCByaWdodCk7CiAgICBpbnQgbWlkID0gbGVmdCArIChyaWdodCAtIGxlZnQpIC8gMjsKICAgIGlmIChxbGVmdCA8PSBtaWQpCiAgICB7CiAgICAgICAgVXBkYXRlMShub2RlICogMiwgbGVmdCwgbWlkLCBxbGVmdCwgcXJpZ2h0LCB2YWwpOwogICAgfQogICAgaWYgKHFyaWdodCA+IG1pZCkKICAgIHsKICAgICAgICBVcGRhdGUxKG5vZGUgKiAyICsgMSwgbWlkICsgMSwgcmlnaHQsIHFsZWZ0LCBxcmlnaHQsIHZhbCk7CiAgICB9CiAgICB0cmVlW25vZGVdID0gKHRyZWVbbm9kZSAqIDJdICsgdHJlZVtub2RlICogMiArIDFdKSAlIE1PRDsKfQoKdm9pZCBVcGRhdGUyKGludCBub2RlLCBpbnQgbGVmdCwgaW50IHJpZ2h0LCBpbnQgcWxlZnQsIGludCBxcmlnaHQsIGxsIHZhbCkKewogICAgaWYgKHFsZWZ0IDw9IGxlZnQgJiYgcmlnaHQgPD0gcXJpZ2h0KQogICAgewogICAgICAgIEFwcGx5KG5vZGUsIGxlZnQsIHJpZ2h0LCB2YWwgJSBNT0QsIDApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFB1c2hkb3duKG5vZGUsIGxlZnQsIHJpZ2h0KTsKICAgIGludCBtaWQgPSBsZWZ0ICsgKHJpZ2h0IC0gbGVmdCkgLyAyOwogICAgaWYgKHFsZWZ0IDw9IG1pZCkKICAgIHsKICAgICAgICBVcGRhdGUyKG5vZGUgKiAyLCBsZWZ0LCBtaWQsIHFsZWZ0LCBxcmlnaHQsIHZhbCk7CiAgICB9CiAgICBpZiAocXJpZ2h0ID4gbWlkKQogICAgewogICAgICAgIFVwZGF0ZTIobm9kZSAqIDIgKyAxLCBtaWQgKyAxLCByaWdodCwgcWxlZnQsIHFyaWdodCwgdmFsKTsKICAgIH0KICAgIHRyZWVbbm9kZV0gPSAodHJlZVtub2RlICogMl0gKyB0cmVlW25vZGUgKiAyICsgMV0pICUgTU9EOwp9CgpsbCBRdWVyeShpbnQgbm9kZSwgaW50IGxlZnQsIGludCByaWdodCwgaW50IHFsZWZ0LCBpbnQgcXJpZ2h0KQp7CiAgICBpZiAocWxlZnQgPD0gbGVmdCAmJiByaWdodCA8PSBxcmlnaHQpCiAgICB7CiAgICAgICAgcmV0dXJuIHRyZWVbbm9kZV07CiAgICB9CiAgICBQdXNoZG93bihub2RlLCBsZWZ0LCByaWdodCk7CiAgICBpbnQgbWlkID0gbGVmdCArIChyaWdodCAtIGxlZnQpIC8gMjsKICAgIGxsIHJlcyA9IDA7CiAgICBpZiAocWxlZnQgPD0gbWlkKQogICAgewogICAgICAgIHJlcyA9IChyZXMgKyAoUXVlcnkobm9kZSAqIDIsIGxlZnQsIG1pZCwgcWxlZnQsIHFyaWdodCkpKSAlIE1PRDsKICAgIH0KICAgIGlmIChxcmlnaHQgPiBtaWQpCiAgICB7CiAgICAgICAgcmVzID0gKHJlcyArIChRdWVyeShub2RlICogMiArIDEsIG1pZCArIDEsIHJpZ2h0LCBxbGVmdCwgcXJpZ2h0KSkpICUgTU9EOwogICAgfQogICAgcmV0dXJuIHJlczsKfQoKdm9pZCBTb2x2ZSgpCnsKICAgIHRyZWUuYXNzaWduKDQgKiBuICsgNywgMCk7CiAgICBsYXp5YWRkLmFzc2lnbig0ICogbiArIDcsIDApOwogICAgbGF6eW11bC5hc3NpZ24oNCAqIG4gKyA3LCAxKTsKICAgIHdoaWxlKHEgLS0pCiAgICB7CiAgICAgICAgaW50IHR5cGU7CiAgICAgICAgY2luID4+IHR5cGU7CiAgICAgICAgaWYgKHR5cGUgPT0gMSkKICAgICAgICB7CiAgICAgICAgICAgIGludCBsZWZ0LCByaWdodCwgdmFsOwogICAgICAgICAgICBjaW4gPj4gbGVmdCA+PiByaWdodCA+PiB2YWw7CiAgICAgICAgICAgIFVwZGF0ZTEoMSwgMSwgbiwgbGVmdCwgcmlnaHQsIHZhbCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gMikKICAgICAgICB7CiAgICAgICAgICAgIGludCBsZWZ0LCByaWdodCwgdmFsOwogICAgICAgICAgICBjaW4gPj4gbGVmdCA+PiByaWdodCA+PiB2YWw7CiAgICAgICAgICAgIFVwZGF0ZTIoMSwgMSwgbiwgbGVmdCwgcmlnaHQsIHZhbCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGludCBsZWZ0LCByaWdodDsKICAgICAgICAgICAgY2luID4+IGxlZnQgPj4gcmlnaHQ7CiAgICAgICAgICAgIGNvdXQgPDwgUXVlcnkoMSwgMSwgbiwgbGVmdCwgcmlnaHQpIDw8IGVuZGw7CiAgICAgICAgfQogICAgfQp9CgppbnQgbWFpbigpCnsKICAgIGZpeElPKCk7CiAgICBGaWxlKCJxdWVyeWl0Iik7CiAgICBSZWFkKCk7CiAgICBTb2x2ZSgpOwogICAgcmV0dXJuIDA7Cn0KCi8qCiAqIENvZGUgYnkgZ2l0aHViL25ta2RldmVsb3Blci4KICogSSBkaWRuJ3QgZmFsbCBpbiBsb3ZlIHdpdGggeW91LiBJIHdhbGtlZCBpbnRvIGxvdmUgd2l0aCB5b3UsIHdpdGggbXkgZXllcyB3aWRlIG9wZW4sIGNob29zaW5nIHRvIHRha2UgZXZlcnkgc3RlcCBhbG9uZyB0aGUgd2F5IDwzLgogKi8=