#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int n,m,a[100005];
struct matrix
{
int n,m;
long long a[3][3];
matrix()
{
memset(a,0,sizeof(a));
}
matrix operator*(const matrix &W) const
{
matrix res;
res.n=n;
res.m=W.m;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=W.m;++j)
{
for(int k=1;k<=m;++k)
{
res.a[i][j]=(res.a[i][j]+a[i][k]*W.a[k][j])%mod;
}
}
}
return res;
}
};
matrix qwq;
void init()
{
qwq.n=qwq.m=2;
qwq.a[1][1]=qwq.a[1][2]=qwq.a[2][1]=1;
}
matrix qpow(matrix base,int b)
{
matrix res;
res.n=res.m=base.n;
for(int i=1;i<=res.n;++i)
{
res.a[i][i]=1;
}
while(b)
{
if(b&1) res=res*base;
base=base*base;
b>>=1;
}
return res;
}
matrix tree[400005];
matrix tag[400005];
void fa_change(int u)
{
tree[u].a[1][1]=(tree[u<<1].a[1][1]+tree[u<<1|1].a[1][1])%mod;
tree[u].a[1][2]=(tree[u<<1].a[1][2]+tree[u<<1|1].a[1][2])%mod;
}
void add(int u,int x)
{
tag[u]=tag[u]*qpow(qwq,x);
tree[u]=tree[u]*qpow(qwq,x);
}
bool tag_empty(int u)
{
return (tag[u].a[1][1]==1)&&(tag[u].a[2][2]==1)&&(tag[u].a[2][1]==0)&&(tag[u].a[1][2]==0);
}
void push_down(int u)
{
if(tag_empty(u)) return;
tree[u<<1]=tree[u<<1]*tag[u];
tree[u<<1|1]=tree[u<<1|1]*tag[u];
tag[u<<1]=tag[u<<1]*tag[u];
tag[u<<1|1]=tag[u<<1|1]*tag[u];
tag[u].a[1][1]=tag[u].a[2][2]=1;
tag[u].a[1][2]=tag[u].a[2][1]=0;
}
void creattree(int u,int l,int r)
{
tree[u].n=1;
tree[u].m=2;
tag[u].n=2;
tag[u].m=2;
tag[u].a[1][1]=tag[u].a[2][2]=1;
if(l==r)
{
if(a[l]==1) tree[u].a[1][1]=1;
else tree[u].a[1][1]=tree[u].a[1][2]=1;
if(a[l]>2) tree[u]=tree[u]*qpow(qwq,a[l]-2);
return;
}
int mid=l+r>>1;
creattree(u<<1,l,mid);
creattree(u<<1|1,mid+1,r);
fa_change(u);
}
void update(int u,int l,int r,int L,int R,int x)
{
if(L<=l&&r<=R)
{
add(u,x);
return;
}
push_down(u);
int mid=l+r>>1;
if(L<=mid) update(u<<1,l,mid,L,R,x);
if(R>mid) update(u<<1|1,mid+1,r,L,R,x);
fa_change(u);
}
long long query(int u,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
return tree[u].a[1][1];
}
push_down(u);
int mid=l+r>>1;
long long res=0;
if(L<=mid) res=(res+query(u<<1,l,mid,L,R))%mod;
if(R>mid) res=(res+query(u<<1|1,mid+1,r,L,R))%mod;
return res;
}
signed main()
{
init();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
}
creattree(1,1,n);
while(m--)
{
int op,l,r,x;
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%d",&l,&r,&x);
update(1,1,n,l,r,x);
}
else
{
scanf("%d%d",&l,&r);
printf("%d\n",query(1,1,n,l,r));
}
}
return 0;
}