#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int n,m;
int a[N];
int op,l,r,x;
const int mod=1e9+7;
struct matrix{
int m[4][4];
void clear(){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
m[i][j]=0;
}
}
}
void init(){
clear();
for(int i=0;i<4;i++){
m[i][i]=1;
}
}
friend matrix operator *(matrix a,matrix b){
matrix z; z.clear();
for(int i=1;i<4;i++){
for(int j=1;j<4;j++){
for(int k=1;k<4;k++){
z.m[i][j]=(a.m[i][k]*b.m[k][j]%mod+z.m[i][j])%mod;
}
}
}
return z;
}
friend matrix operator +(matrix a,matrix b){
matrix z; z.clear();
for(int i=1;i<4;i++){
for(int j=1;j<4;j++){
z.m[i][j]=(a.m[i][j]+b.m[i][j])%mod;
}
}
return z;
}
}F;
matrix qp(matrix a,int k){
matrix b;
b.init();
while(k){
if(k&1) b=b*a;
a=a*a;
k>>=1;
}
return b;
}
int rt,cnt,lc[N],rc[N];
struct node{
matrix sum,lt;
}tr[N<<2];
void pushup(int p){
tr[p].sum=tr[lc[p]].sum+tr[rc[p]].sum;
}
void build(int &p,int l,int r){
p=++cnt;
tr[p].lt.init();
tr[p].sum.clear();
if(l==r){
matrix h;
h.clear();
h.m[1][1]=h.m[1][2]=1;
tr[p].sum=h*qp(F,a[l]-1);
return ;
}
int m=l+r>>1;
build(lc[p],l,m);
build(rc[p],m+1,r);
pushup(p);
}
void pushdown(int p){
tr[lc[p]].sum=tr[lc[p]].sum*tr[p].lt;
tr[rc[p]].sum=tr[rc[p]].sum*tr[p].lt;
tr[lc[p]].lt=tr[lc[p]].lt*tr[p].lt;
tr[rc[p]].lt=tr[rc[p]].lt*tr[p].lt;
tr[p].lt.init();
}
void upd(int p,int L,int R,matrix y){
if(l<=L&&R<=r){
tr[p].sum=tr[p].sum*y;
tr[p].lt=tr[p].lt*y;
return ;
}
pushdown(p);
int m=L+R>>1;
if(m>=l) upd(lc[p],L,m,y);
if(m<r) upd(rc[p],m+1,R,y);
pushup(p);
}
matrix query(int p,int L,int R){
if(l<=L&&R<=r) return tr[p].sum;
pushdown(p);
int m=L+R>>1;
matrix ans; ans.clear();
if(m>=l) ans=ans+query(lc[p],L,m);
if(m<r) ans=ans+query(rc[p],m+1,R);
return ans;
}
signed main(){
cin>>n>>m;
F.clear();
F.m[2][2]=F.m[1][2]=F.m[2][1]=1;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(rt,1,n);
while(m--){
cin>>op>>l>>r;
if(op==1){
cin>>x;
matrix y;
y=qp(F,x);
upd(rt,1,n,y);
}
else{
matrix ans=query(rt,1,n);
cout<<ans.m[1][1]%mod<<endl;
}
}
}