#include <bits/stdc++.h>
using namespace std;
int n;
vector<int>inp;
const int MODE = 1e9+7;
struct Query
{
int a,b,c,d;
};
vector<Query> query;
vector<long long> seg;
vector<vector<long long>> segmu;
int q;
void build(int id, int l, int r)
{
if(l == r)
{
seg[id] = inp[l];
return;
}
int mid = (l+r)/2;
build(id*2, l, mid);
build(id*2+1, mid+1, r);
seg[id] = (seg[id*2] + seg[id*2+1]) % MODE;
}
void update(int id, int l, int r, int pos, int val)
{
if(l == r)
{
seg[id] =val;
return;
}
int mid = (l+r)/2;
if(mid >= pos) update(id*2, l, mid, pos, val);
else update(id*2+1, mid+1, r, pos, val);
seg[id] = (seg[id*2] + seg[id*2+1]) % MODE;
}
long long get(int id, int l, int r, int u, int v)
{
if( u > r || v < l) return 0;
if(u <= l && v >= r) return seg[id];
int mid = (l+r)/2;
return (get(id*2, l, mid, u, v) + get(id*2+1, mid+1, r, u, v)) % MODE;
}
long long pw(int x, int y)
{
long long res = 1, mul = x;
while(y > 0)
{
if(y & 1) res =(1LL*res*mul) % MODE;
mul = (1ll*mul*mul) % MODE;
y >>=1;
}
return res;
}
void buildmu(int id, int l, int r, int k, vector<long long>&seg)
{
if(l == r)
{
seg[id] = pw(inp[l], k);
return;
}
int mid = (l+r)/2;
buildmu(id*2, l, mid, k, seg);
buildmu(id*2+1, mid+1, r, k, seg);
seg[id] = (seg[id*2] + seg[id*2+1]) % MODE;
return;
}
void updatemu(int id, int l, int r, int pos, int val, int k, vector<long long>&seg)
{
if(l == r)
{
seg[id] = pw(val, k);
return;
}
int mid = (l+r)/2;
if(mid >= pos) updatemu(id*2, l, mid, pos, val, k, seg);
else updatemu(id*2+1, mid+1, r, pos, val, k, seg);
seg[id] = (seg[id*2] + seg[id*2+1]) % MODE;
}
long long getmu(int id, int l, int r, int u, int v, vector<long long>&seg)
{
if(u > r || v < l) return 0;
if(u <= l && v >= r) return seg[id];
int mid = (l+r)/2;
return (getmu(id*2, l, mid, u, v, seg) +getmu(id*2+1,mid+1, r, u, v, seg)) % MODE;
}
void sub()
{
seg.resize(4*n+1);
segmu.resize(6, vector<long long>(4*n+1));
for(int i =1; i<=5; i++) buildmu(1, 1, n, i, segmu[i]);
build(1, 1, n);
for(int i =1; i<=q;i++)
{
if(query[i].a == 1)
{
for(int j = 1; j<=5; j++) updatemu(1, 1, n, query[i].b, query[i].c, j, segmu[j]);
update(1, 1, n, query[i].b, query[i].c);
}
else
{
long long luythuatong = pw(get(1, 1, n, query[i].b, query[i].c), query[i].d);
long long tongluythua = getmu(1, 1, n, query[i].b, query[i].c, segmu[query[i].d]);
//cout << luythuatong << " " << tongluythua << endl;
int tmp = 0;
if(query[i].d == 1) tmp = query[i].c - query[i].b;
else if(query[i].d == 2)tmp = query[i].c - query[i].b +1;
else if(query[i].d == 3) tmp = query[i].c - query[i].b +1;
if(query[i].d == 3) cout << (((long long)2*luythuatong) % MODE + ((long long)(2*tmp + 4)*tongluythua) % MODE ) % MODE << '\n';
else cout << (((long long)2*luythuatong) % MODE + ((long long)2*(tmp)*tongluythua) % MODE ) % MODE << '\n';
}
}
}
int main()
{
ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
cin >> n >> q;
inp.resize(n+1);
query.resize(q+1);
for(int i =1; i<=n; i++) cin >> inp[i];
for(int i =1; i<=q; i++)
{
int a; cin >> a;
query[i].a = a;
if(a == 1)
{
int b,c; cin >> b >> c;
query[i].b = b;
query[i].c = c;
}
else
{
int b,c,d; cin >> b >> c >> d;
query[i] = {a, b, c, d};
}
}
//sub1();
sub();
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CmludCBuOwp2ZWN0b3I8aW50PmlucDsKY29uc3QgaW50IE1PREUgID0gMWU5Kzc7CnN0cnVjdCBRdWVyeQp7CglpbnQgYSxiLGMsZDsKfTsKdmVjdG9yPFF1ZXJ5PiBxdWVyeTsKdmVjdG9yPGxvbmcgbG9uZz4gc2VnOwp2ZWN0b3I8dmVjdG9yPGxvbmcgbG9uZz4+IHNlZ211OwppbnQgcTsKdm9pZCBidWlsZChpbnQgaWQsIGludCBsLCBpbnQgcikKewoJaWYobCA9PSByKQoJewoJCXNlZ1tpZF0gPSBpbnBbbF07CgkJcmV0dXJuOwoJfQoJaW50IG1pZCA9IChsK3IpLzI7CglidWlsZChpZCoyLCBsLCBtaWQpOwoJYnVpbGQoaWQqMisxLCBtaWQrMSwgcik7CglzZWdbaWRdID0gKHNlZ1tpZCoyXSArIHNlZ1tpZCoyKzFdKSAlIE1PREU7Cn0Kdm9pZCB1cGRhdGUoaW50IGlkLCBpbnQgbCwgaW50IHIsIGludCBwb3MsIGludCB2YWwpCnsKCWlmKGwgPT0gcikKCXsKCQlzZWdbaWRdID12YWw7CgkJcmV0dXJuOwoJfQoJaW50IG1pZCA9IChsK3IpLzI7CglpZihtaWQgPj0gcG9zKSB1cGRhdGUoaWQqMiwgbCwgbWlkLCBwb3MsIHZhbCk7CgllbHNlIHVwZGF0ZShpZCoyKzEsIG1pZCsxLCByLCBwb3MsIHZhbCk7CglzZWdbaWRdID0gKHNlZ1tpZCoyXSArIHNlZ1tpZCoyKzFdKSAlIE1PREU7Cn0KCmxvbmcgbG9uZyBnZXQoaW50IGlkLCBpbnQgbCwgaW50IHIsIGludCB1LCBpbnQgdikKewoJaWYoIHUgPiByIHx8IHYgPCBsKSByZXR1cm4gMDsKCWlmKHUgPD0gbCAmJiB2ID49IHIpIHJldHVybiBzZWdbaWRdOwoJaW50IG1pZCA9IChsK3IpLzI7CglyZXR1cm4gKGdldChpZCoyLCBsLCBtaWQsIHUsIHYpICsgZ2V0KGlkKjIrMSwgbWlkKzEsIHIsIHUsIHYpKSAlIE1PREU7Cn0KbG9uZyBsb25nIHB3KGludCB4LCBpbnQgeSkKewoJbG9uZyBsb25nIHJlcyA9IDEsICBtdWwgPSB4OwoJd2hpbGUoeSA+IDApCgl7CgkJaWYoeSAmIDEpIHJlcyA9KDFMTCpyZXMqbXVsKSAlIE1PREU7CgkJbXVsID0gKDFsbCptdWwqbXVsKSAlIE1PREU7CgkJeSA+Pj0xOwoJfQoJcmV0dXJuIHJlczsKfQoKdm9pZCBidWlsZG11KGludCBpZCwgaW50IGwsIGludCByLCBpbnQgaywgdmVjdG9yPGxvbmcgbG9uZz4mc2VnKQp7CglpZihsID09IHIpCgl7CgkJc2VnW2lkXSA9IHB3KGlucFtsXSwgayk7CgkJcmV0dXJuOwoJfQoJaW50IG1pZCA9IChsK3IpLzI7CglidWlsZG11KGlkKjIsIGwsIG1pZCwgaywgc2VnKTsKCWJ1aWxkbXUoaWQqMisxLCBtaWQrMSwgciwgaywgc2VnKTsKCXNlZ1tpZF0gPSAoc2VnW2lkKjJdICsgc2VnW2lkKjIrMV0pICUgTU9ERTsKCXJldHVybjsKfQoKdm9pZCB1cGRhdGVtdShpbnQgaWQsIGludCBsLCBpbnQgciwgaW50IHBvcywgaW50IHZhbCwgaW50IGssIHZlY3Rvcjxsb25nIGxvbmc+JnNlZykKewoJaWYobCA9PSByKQoJewoJCXNlZ1tpZF0gPSBwdyh2YWwsIGspOwoJCXJldHVybjsKCX0KCWludCBtaWQgID0gKGwrcikvMjsKCWlmKG1pZCA+PSBwb3MpIHVwZGF0ZW11KGlkKjIsIGwsIG1pZCwgcG9zLCB2YWwsIGssIHNlZyk7CgllbHNlIHVwZGF0ZW11KGlkKjIrMSwgbWlkKzEsIHIsIHBvcywgdmFsLCBrLCBzZWcpOwoJc2VnW2lkXSA9IChzZWdbaWQqMl0gKyBzZWdbaWQqMisxXSkgJSBNT0RFOwp9Cgpsb25nIGxvbmcgZ2V0bXUoaW50IGlkLCBpbnQgbCwgaW50IHIsIGludCB1LCBpbnQgdiwgdmVjdG9yPGxvbmcgbG9uZz4mc2VnKQp7CglpZih1ID4gciB8fCB2IDwgbCkgcmV0dXJuIDA7CglpZih1IDw9IGwgJiYgdiA+PSByKSByZXR1cm4gc2VnW2lkXTsKCWludCBtaWQgPSAobCtyKS8yOwoJcmV0dXJuIChnZXRtdShpZCoyLCBsLCBtaWQsIHUsIHYsIHNlZykgK2dldG11KGlkKjIrMSxtaWQrMSwgciwgdSwgdiwgc2VnKSkgJSBNT0RFOwp9CnZvaWQgc3ViKCkKewoJc2VnLnJlc2l6ZSg0Km4rMSk7CglzZWdtdS5yZXNpemUoNiwgdmVjdG9yPGxvbmcgbG9uZz4oNCpuKzEpKTsKCWZvcihpbnQgaSA9MTsgaTw9NTsgaSsrKSBidWlsZG11KDEsIDEsIG4sIGksIHNlZ211W2ldKTsKCWJ1aWxkKDEsIDEsIG4pOwoJZm9yKGludCBpID0xOyBpPD1xO2krKykKCXsKCQlpZihxdWVyeVtpXS5hID09IDEpCgkJewoJCQlmb3IoaW50IGogPSAxOyBqPD01OyBqKyspIHVwZGF0ZW11KDEsIDEsIG4sIHF1ZXJ5W2ldLmIsIHF1ZXJ5W2ldLmMsIGosIHNlZ211W2pdKTsKCQkJdXBkYXRlKDEsIDEsIG4sIHF1ZXJ5W2ldLmIsIHF1ZXJ5W2ldLmMpOwoJCX0KCQllbHNlCgkJewoJCQlsb25nIGxvbmcgbHV5dGh1YXRvbmcgPSBwdyhnZXQoMSwgMSwgbiwgcXVlcnlbaV0uYiwgcXVlcnlbaV0uYyksIHF1ZXJ5W2ldLmQpOwoJCQlsb25nIGxvbmcgdG9uZ2x1eXRodWEgPSBnZXRtdSgxLCAxLCBuLCBxdWVyeVtpXS5iLCBxdWVyeVtpXS5jLCBzZWdtdVtxdWVyeVtpXS5kXSk7CgkJCS8vY291dCA8PCBsdXl0aHVhdG9uZyA8PCAiICIgPDwgdG9uZ2x1eXRodWEgPDwgZW5kbDsKCQkJaW50IHRtcCA9IDA7CgkJCWlmKHF1ZXJ5W2ldLmQgPT0gMSkgdG1wID0gcXVlcnlbaV0uYyAtIHF1ZXJ5W2ldLmI7CgkJCWVsc2UgaWYocXVlcnlbaV0uZCA9PSAyKXRtcCA9IHF1ZXJ5W2ldLmMgLSBxdWVyeVtpXS5iICsxOwoJCQllbHNlIGlmKHF1ZXJ5W2ldLmQgPT0gMykgdG1wID0gcXVlcnlbaV0uYyAtIHF1ZXJ5W2ldLmIgKzE7CgkJCWlmKHF1ZXJ5W2ldLmQgPT0gMykgCWNvdXQgPDwgKCgobG9uZyBsb25nKTIqbHV5dGh1YXRvbmcpICUgTU9ERSAgKyAoKGxvbmcgbG9uZykoMip0bXAgKyA0KSp0b25nbHV5dGh1YSkgJSBNT0RFICkgJSBNT0RFIDw8ICdcbic7CgkJCWVsc2UgY291dCA8PCAoKChsb25nIGxvbmcpMipsdXl0aHVhdG9uZykgJSBNT0RFICArICgobG9uZyBsb25nKTIqKHRtcCkqdG9uZ2x1eXRodWEpICUgTU9ERSApICUgTU9ERSA8PCAnXG4nOwoJCX0KCX0KfQoKaW50IG1haW4oKQp7Cglpb3M6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7IGNpbi50aWUoTlVMTCk7IGNvdXQudGllKE5VTEwpOwoJY2luID4+IG4gPj4gcTsKCWlucC5yZXNpemUobisxKTsKCXF1ZXJ5LnJlc2l6ZShxKzEpOwoJZm9yKGludCBpID0xOyBpPD1uOyBpKyspIGNpbiA+PiBpbnBbaV07Cglmb3IoaW50ICBpID0xOyBpPD1xOyBpKyspCgl7CgkJaW50IGE7IGNpbiA+PiBhOwoJCXF1ZXJ5W2ldLmEgPSBhOwoJCWlmKGEgPT0gMSkKCQl7CgkJCWludCBiLGM7IGNpbiA+PiBiID4+IGM7CgkJCXF1ZXJ5W2ldLmIgPSBiOwoJCQlxdWVyeVtpXS5jID0gYzsKCQl9CgkJZWxzZSAKCQl7CgkJCWludCBiLGMsZDsgY2luID4+IGIgPj4gYyA+PiBkOwoJCQlxdWVyeVtpXSA9IHthLCBiLCBjLCBkfTsKCQl9Cgl9CgkvL3N1YjEoKTsKCXN1YigpOwoJcmV0dXJuIDA7Cn0=