#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;
}