#include<bits/stdc++.h>
using namespace std;
const long long MaxN = 1e5 + 5, MOD=1e9+7;
long long n,q,a[MaxN];
struct Segtree_lazy
{
    vector<long long> st,lazy_x,lazy_y;
    void init(long long n)
    {
        if(n==0)
        {
            return;
        }
        st.assign(4*n+1,0);
        lazy_x.assign(4*n+1,0);
        lazy_y.assign(4*n+1,0);
    }
    void build(long long id, long long l, long long r)
    {
        if(l==r)
        {
            st[id]=a[l]%MOD;
            return;
        }
        long long mid=(l+r)>>1;
        build(2*id,l,mid);
        build(2*id+1,mid+1,r);
        st[id]=(st[2*id]+st[2*id+1])%MOD;
    }
    long long cnt(long long x, long long y)
    {
        return y-x+1;
    }
    long long sum(long long x, long long y)
    {
        return ((x+y)%MOD*cnt(x,y)%MOD*500000004)%MOD;
    }
    void push_down(long long id, long long l, long long r)
    {
        if(l==r) return;

        long long mid=(l+r)>>1;
        long long x=lazy_x[id];
        long long y=lazy_y[id];

        lazy_x[2*id]=(lazy_x[2*id]+x)%MOD;
        lazy_y[2*id]=(lazy_y[2*id]+y)%MOD;
        st[2*id]=(st[2*id]+y*cnt(l,mid)%MOD
                  +x*sum(0,mid-l)%MOD)%MOD;

        lazy_x[2*id+1]=(lazy_x[2*id+1]+x)%MOD;
        lazy_y[2*id+1]=(lazy_y[2*id+1]+y+x*(mid+1-l)%MOD)%MOD;
        st[2*id+1]=(st[2*id+1]+y*cnt(mid+1,r)%MOD
                    +x*sum(mid+1-l,r-l)%MOD)%MOD;

        lazy_x[id]=0;
        lazy_y[id]=0;
    }
    void update(long long id,long long l, long long r, long long u, long long v, long long x, long long y)
    {
        if(l>v||r<u)
        {
            return;
        }
        if(u<=l&&r<=v)
        {
            long long val=(y+x*(l-u)%MOD)%MOD;

            st[id]=(st[id]+val*cnt(l,r)%MOD
                    +x*sum(0,r-l)%MOD)%MOD;

            lazy_x[id]=(lazy_x[id]+x)%MOD;
            lazy_y[id]=(lazy_y[id]+val)%MOD;
            return;
        }
        long long mid=(l+r)>>1;
        push_down(id,l,r);
        update(2*id,l,mid,u,v,x,y);
        update(2*id+1,mid+1,r,u,v,x,y);
        st[id]=(st[2*id]+st[2*id+1])%MOD;
    }
    long long get(long long id, long long l, long long r, long long u, long long v)
    {
        if(l>v||r<u)
        {
            return 0;
        }
        if(u<=l&&r<=v)
        {
            return st[id];
        }
        long long mid=(l+r)>>1;
        push_down(id,l,r);
        return (get(2*id,l,mid,u,v)
                +get(2*id+1,mid+1,r,u,v))%MOD;
    }
    void update(long long u, long long v, long long x, long long y)
    {
        update(1,1,n,u,v,x,y);
    }
    long long get(long long u, long long v)
    {
        return get(1,1,n,u,v);
    }
};
Segtree_lazy segtree;

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin>>n>>q;
    segtree.init(n);

    for(long long i=1; i<=q; i++)
    {
        long long type,l,r;
        cin>>type>>l>>r;
        if(type==1)
        {
            long long x,y;
            cin>>x>>y;
            segtree.update(l,r,x,y);
        }
        else
        {
            cout<<segtree.get(l,r)%MOD<<"\n";
        }
    }
}
