![]()
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#define num ch-'0'
#define int long long
using namespace std;
typedef long long ll;
const int N=100000+10;
const int mod=1e9+7;
void read(int &x){
char ch;x=0;
while(!isdigit(ch=getchar()));
for(x=num;isdigit(ch=getchar());x=x*10+num);
}
void red(ll &x){
char ch;x=0;
while(!isdigit(ch=getchar()));
for(x=num;isdigit(ch=getchar());x=x*10+num);
}
int n,m;
ll a[N];
struct T{
ll a[3][3];
//T() {memset(a,0,sizeof a);laz[1][1]=laz[2][2]=1;}
void clear(){
//memset(a,0,sizeof a);
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
a[i][j]=0;
}
void init(){
a[1][1]=a[2][2]=1;
}
bool empty(){
if(a[1][1]!=1) return 0;
if(a[1][2]!=0) return 0;
if(a[2][1]!=0) return 0;
if(a[2][2]!=1) return 0;
return 1;
}
T operator + (T b){
T c;c.clear();
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
c.a[i][j]=(c.a[i][j]+b.a[i][j]+a[i][j])%mod;
return c;
}/*void print(){
for(int i=1;i<=2;i++)
{
for(int j=1;j<=2;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}*/
T operator * (T b){
T c;c.clear();
for(int i=1;i<=2;i++)
for(int k=1;k<=2;k++)
for(int j=1;j<=2;j++)
c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mod;
//c.print();
return c;
}
}t[4*N],laz[4*N],M,B;
T qm(T a,ll y){
T ret,base;
ret.clear(),ret.init();
while(y){
if(y&1) ret=ret*a;
a=a*a;
y>>=1;
}
return ret;
}
void pushup(int x){
t[x]=t[x<<1]+t[x<<1|1];
}
void build(int x,int l,int r){
laz[x].clear();laz[x].init();
t[x].clear();
if(l==r){
t[x]=qm(M,a[l]-1);
//cout<<l<<" : "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
//laz[x].print();
return;
}
//laz[x].clear(),laz[x].init();
int mid=l+r>>1;
build(x<<1,l,mid);build(x<<1|1,mid+1,r);
pushup(x);
// if(l==1&&r==3){
// cout<<" get "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
// }
}
void pushdown(int x,int l,int r)
{
//if(laz[x].empty()) return;
//if(laz[x].a[1][1]==1&&laz[x].a[2][2]==1&&laz[x].a[2][1]==0&&laz[x].a[1][2]==0) return;
if(laz[x].empty()) return;
int ls=(x<<1),rs=(x<<1|1);
//cout<<" here "<<l<<" "<<r<<endl;
//if(l==10&&r==14) laz[x].print();
//cout<<" before "<<endl;
//t[ls].print(); puts("");t[rs].print();
// laz[x].print();
//cout<<" ans "<<endl;
//(t[ls]*laz[x]).print();
t[ls]=t[ls]*laz[x];
//cout<<" cc "<<endl;cc.print();
//t[ls]=cc;
//cout<<"ls:";t[ls].print();
//T dd=t[rs]*laz[x];
t[rs]=t[rs]*laz[x];
//t[ls].print(),puts(""),t[rs].print();
//cout<<"laz "<<laz[rs].pr
laz[ls]=laz[ls]*laz[x];
laz[rs]=laz[rs]*laz[x];
//cout<<" after "<<endl;
// puts("");t[rs].print();
// t[x].laz[1][1]=t[x].laz[2][2]=1;
laz[x].clear();laz[x].init();
//t[x].laz=0;
}
void update(int x,int l,int r,int L,int R,T c)
{
//cout<<" ffff "<<l<<" "<<r<<" "<<endl;
if(L<=l&&r<=R){
// cout<<" l and r "<<l<<" "<<r<<endl;
// cout<<" laz1 "<<lz<<" laz2 "<<t[x].laz<<endl;
t[x]=t[x]*c;
// cout<<" lazy "<<t[x].laz<<endl;
//t[x]=t[x]*c;
laz[x]=laz[x]*c;
//if(l==1&&r==5) laz[x].print();
//if(L==8&&R==15) c.print();
//if(l==10&&r==14) laz[x].print();
// if(l==1&&r==3){
// cout<<" get222 "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
//}
return;
}
pushdown(x,l,r);
int mid=l+r>>1;
if(L<=mid) update(x<<1,l,mid,L,R,c);
if(mid<R) update(x<<1|1,mid+1,r,L,R,c);
pushup(x);
//if(l==1&&r==3){
// cout<<" get222 "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
//}
}
T query(int x,int l,int r,int L,int R)
{
//if(L==1&&R==3) cout<<"finding "<<l<<" "<<r<<endl;
//cout<<" finding "<<l<<" "<<r<<endl;
//if(l==1&&r==5) laz[x].print();
if(L<=l&&r<=R){
// if(l==4&&r==5) t[x].print();
return t[x];
}
//cout<<" dfdfdfdfd "<<l<<" "<<r<<endl;
pushdown(x,l,r);
//cout<<" fdfdfdf "<<l<<" "<<r<<endl;
T ret;ret.clear();
//ret.print();
int mid=l+r>>1;
//query(x<<1,l,mid,L,R).print();
if(L<=mid) ret=ret+query(x<<1,l,mid,L,R);
if(mid<R) ret=ret+query(x<<1|1,mid+1,r,L,R);
//cout<<" after "<<l<<" "<<r<<" : "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
return ret;
}
ll work(int l,int r)
{
T ret;ret.clear();
ret=B*query(1,1,n,l,r);
return ret.a[1][1];
}
signed main()
{
B.clear(),M.clear();
B.a[1][1]=1;//B.a[1][2]=1;
M.a[1][1]=M.a[1][2]=M.a[2][1]=1;
//scanf("%I64d%I64d",&n,&m);
read(n);read(m);
for(int i=1;i<=n;i++)
red(a[i]);
//scanf("%I64d",&a[i]);
build(1,1,n);
int op,l,r;
ll z;
while(m--){
// scanf("%I64d",&op);
//cout<<"mmmm "<<m<<endl;
read(op);
if(op==1){
//scanf("%I64d%I64d%I64d",&l,&r,&z);
read(l);read(r);red(z);
//cout<<" before "<<z<<" "<<endl;
T k;k=qm(M,z);
//cout<<" after "<<z<<endl;
//cout<<k.a[1][1]<<" "<<k.a[1][2]<<" "<<k.a[2][1]<<" "<<k.a[2][2]<<endl;
update(1,1,n,l,r,k);
}
else{
//scanf("%I64d%I64d",&l,&r);
read(l);read(r);
printf("%I64d\n",work(l,r));
}
}
return 0;
}