// Problem: O - 区间方差
// Contest: Virtual Judge - 第2章:进阶数据结构2(线段树、树状数组)
// URL: https://vjudge.net/contest/629231#problem/O
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fir first
#define sec second
#define fst ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
const int N=1e6+5,INF=0x3f3f3f3f3f3f3f3f,P=1e9+7;
int ans=0;
int n,m;
int a[N];
int bit[3][N];
int lowbit(int x){return x&-x;}
void plu(int i,int x,int y){for(;x<=n;x+=lowbit(x)){bit[i][x]+=y;bit[i][x]%=P;}}
int get(int i,int x){int y=0;for(;x;x-=lowbit(x))y+=bit[i][x];return y;}
int fpm(int x,int y){
if(y==0)return 1;
int z=fpm(x,y>>1);
if(y&1)return z*z%P*x%P;
return z*z%P;
}
int f(int x){return fpm(x,P-2);}
signed main(){
fst
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> a[i];
a[i]%=P;
plu(1,i,a[i]);
plu(2,i,a[i]*a[i]%P);
}
while(m--){
int op,x,y;
cin >> op >> x >> y;
if(op==1){
plu(1,x,(y-a[x])%P);
plu(2,x,(y*y%P+P)%P-(a[x]*a[x]%P+P)%P);
a[x]=y;
}else{
int num1,num2,num3,num4,res=0;
num1=fpm(get(1,y)-get(1,x-1),2);
num2=fpm(y-x+1,2);
int num12=num1;
num1*=f(__gcd(num1,num2));num2*=f(__gcd(num12,num2));
num1%=P;num2%=P;
num3=((get(2,y)-get(2,x-1))%P+P)%P;
num4=y-x+1;
int num32=num3;
num3*=f(__gcd(num3,num4));num4*=f(__gcd(num32,num4));
num3%=P;num4%=P;
// cout << num1 << ' ' << num2 << ' ' << num3 << ' ' << num4 << endl;
num1=(((num3*num2%P+P)%P*f(__gcd(num2,num4)%P+P)%P)%P-(num1*num4%P*f((__gcd(num2,num4)%P))%P))%P;
num2*=(num4*f(__gcd(num2,num4)%P+P)%P);num2%=P;
num1*=f(__gcd(num1,num2));num2*=f(__gcd(num1,num2));
num1%=P;num2%=P;
// cout << num1 << ' ' << num2 << endl;
res=((num1%P+P)%P*fpm(num2,P-2)%P+P)%P;
cout << res << endl;
}
}
return 0;
}
pts10 ac#1