#include<bits/stdc++.h>
#define ll long long
#define INF 1000000007
#define maxn 300005
using namespace std;
ll S[maxn];
ll lz1[maxn<<2],lz2[maxn<<2];//lz1 就是记录那个-L *x的 lz2就是记录 pos*x的
ll dat[maxn<<2];
void Add(int rt,int l,int r,int ss,int tt,ll qx,ll posx){
if(ss>r||tt<l) return;//判断是否越界
if(ss<=l&&r<=tt){//全部包含
lz1[rt]=(lz1[rt]+qx)%INF;//永久化标记
lz2[rt]=(lz2[rt]+posx)%INF;
dat[rt]=(dat[rt]+qx*(r-l+1)%INF+posx*((S[r]-S[l-1])%INF)%INF)%INF;// (S[r]-S[l-1])就是那一段等差数列的和 预处理出来了直接作一个差就行了
return;
}
int mid=(l+r)>>1;
Add(rt*2,l,mid,ss,tt,qx,posx);Add(rt*2+1,mid+1,r,ss,tt,qx,posx);
dat[rt]=(dat[rt*2]+dat[rt*2+1]+lz1[rt]*(r-l+1)%INF+lz2[rt]*((S[r]-S[l-1])%INF)%INF)%INF;
}
ll Get(int rt,int l,int r,int ss,int tt){
if(ss>r||tt<l) return 0;
if(ss<=l&&r<=tt) return dat[rt];
int lll=max(l,ss);
int rr=min(r,tt);
int mid=(l+r)>>1;
return (lz1[rt]*(rr-lll+1)%INF+lz2[rt]*((S[rr]-S[lll-1])%INF)%INF+Get(rt*2,l,mid,ss,tt)+Get(rt*2+1,mid+1,r,ss,tt))%INF;
}
int main(){
freopen("segment.in","r",stdin);freopen("segment.out","w",stdout);
int n,m;scanf("%d%d",&n,&m);//输入 不说了 哈哈
for(int i=1;i<=n;i++) S[i]=S[i-1]+i;//这里就是预处理一个前缀和
for(int i=1;i<=m;i++){
int Type;scanf("%d",&Type);
if(Type){
int l,r;ll x,posx;scanf("%d%d%lld",&l,&r,&x);
posx=(INF-l)*x%INF;//posx 就是那个-L 这里加上一个INF 是因为——L是负数 会炸的!!
Add(1,1,n,l,r,posx,x);
}
else{
int l,r;scanf("%d%d",&l,&r);
printf("%lld\n",Get(1,1,n,l,r)%INF);
}
}
return 0;
}