#include <bits/stdc++.h>
#define IOS std::ios_base::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
using namespace std;
typedef long long ll;
const int N=10010;
int a[N];
struct ty
{
    ll sum,jia,cheng,ping; //和  +  *  平方和
}tree[4*N];
void pushup(int p, int l, int r)
{
    tree[p].sum =tree[2*p].sum + tree[2*p+1].sum;
    tree[p].ping =tree[2*p].ping + tree[2*p+1].ping;
}
void pushdown(int p, int l, int r)
{
    //先传乘法再传加法,乘标记需要改变加法标记
    //(a+b)*c =ac+bc 括号展开
    int mid = (l+r)>>1;
    ll y=tree[p].cheng;
    tree[2*p].jia *= y;
    tree[2*p+1].jia *= y;
    tree[2*p].cheng *= y;
    tree[2*p+1].cheng *= y;
    tree[2*p].sum *= y;
    tree[2*p+1].sum *= y;
    tree[2*p].ping *= y * y;
    tree[2*p+1].ping *= y * y;
    tree[p].cheng =1;//消除乘法标记!!!

    ll x=tree[p].jia;
    if( x )
    {
        tree[2*p].jia += x;
        tree[2*p+1].jia += x;

        //∑(ai+x)^2 == ∑ai^2 + 2x∑(ai^2) + 区间长度* (x^2)
        //先维护平方和,再维护和!!
        tree[2*p].ping += 2 * x * tree[2*p].sum +(mid-l+1) * x * x;
        tree[2*p+1].ping += 2 * x * tree[2*p+1].sum +(r-(mid+1)+1) * x * x;
        tree[2*p].sum += (mid-l+1) * x;
        tree[2*p+1].sum += (r-(mid+1)+1) * x;
        //标记一定记得清除!!
        tree[p].jia=0;
    }
}
void bulid(int p ,int l ,int r)
{
    tree[p].jia=0;
    tree[p].cheng=1;
    if( l == r)
    {
        tree[p].sum = a[l];
        tree[p].ping = a[l] * a[l];
        return ;
    }
    int mid=(l + r) >> 1;
    bulid(2*p,l,mid);
    bulid(2*p+1,mid+1,r);
    pushup(p,l,r);
}
void change(int p, int l, int r ,int a, int b, int num)
{
    if(a <= l && r <= b)
    {
        tree[p].jia += num;
        //先处理平方和,再处理和
        tree[p].ping += 2 * num * tree[p].sum +(r-l+1) * num * num;
        tree[p].sum += (r-l+1) * num;
        return ;
    }
    if( tree[p].jia || tree[p].cheng!=1 )  pushdown(p,l,r);
    int mid = (l+r) >> 1;

    if( a <= mid )    change(2*p, l,mid,a,b,num);
    if( b > mid )   change(2*p+1, mid+1, r,a,b,num);
    pushup(p,l,r);
}

void cheng(int p, int l, int r ,int a, int b, int num)
{
    if(a <= l && r <= b)
    {
        tree[p].cheng *= num;
        tree[p].jia *= num;
        tree[p].sum *= num; //区间每个元素乘num,即对区间和乘num
        tree[p].ping *= num * num; //区间乘num方
        return ;
    }
    if( tree[p].jia || tree[p].cheng!=1 )  pushdown(p,l,r);
    int mid = (l+r) >> 1;

    if( a <= mid )    cheng(2*p, l,mid,a,b,num);
    if( b > mid )   cheng(2*p+1, mid+1, r,a,b,num);
    pushup(p,l,r);
}

ll findsum(int p,int l,int r ,int a ,int b)
{
    if(a <= l && r <= b)
    {
        return tree[p].sum;
    }
    if( tree[p].jia || tree[p].cheng!=1 )  pushdown(p,l,r);
    int mid = (l+r) >> 1;
    ll res=0;
    if( a <= mid )    {res+=findsum(2*p, l,mid,a,b);}
    if( b > mid )   {res+=findsum(2*p+1, mid+1, r,a,b);}

    return res;
}
ll findping(int p,int l,int r ,int a ,int b)
{
    if(a <= l && r <= b)    return tree[p].ping;

    if( tree[p].jia || tree[p].cheng!=1 )  pushdown(p,l,r);
    int mid = (l+r) >> 1;
    ll res=0;
    if( a <= mid )    {res+=findping(2*p, l,mid,a,b);}
    if( b > mid )   {res+=findping(2*p+1, mid+1, r,a,b);}
    return res;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1 ;i<=n ;i++)
        cin>>a[i];
    //建树
    bulid(1,1,n);
    for(int i=1 ;i<=m ;i++)
    {
        int op,x,y,z;
        cin>>op>>x>>y;
        if( op == 1)
            cout<<findsum(1,1,n,x,y)<<endl;

        if( op == 2)
            cout<<findping(1,1,n,x,y)<<endl;
        if( op == 3)
        {
            cin>>z;
            cheng(1,1,n,x,y,z);
        }
        if( op == 4)
        {
            cin>>z;
            change(1,1,n,x,y,z);
        }
    }
}