#include<cstdio>
#pragma GCC optimize(3)
using namespace std;
const int N = 1e5+10;
typedef long long ll;
struct xds{
int l,r;
ll sumh,sump;
int add,mul;
}tr[N*4];
int n,m;
ll a[N];
inline void pushup(xds&u,xds&l,xds&r){
u.sumh=l.sumh+r.sumh;
u.sump=l.sump+r.sump;
}
inline void eval(xds&u,int add,int mul){
ll a=u.sumh;
u.sumh=(u.sumh*mul+(u.r-u.l+1)*add);
u.sump=(u.sump*mul*mul+a*2*add*mul+(u.r-u.l+1)*add*add);
u.add=(u.add*mul+add);
u.mul=(u.mul*mul);
}
inline void pushdown(int u){
eval(tr[u<<1],tr[u].add,tr[u].mul);
eval(tr[u<<1|1],tr[u].add,tr[u].mul);
tr[u].add=0,tr[u].mul=1;
}
inline void pushup(int u){pushup(tr[u],tr[u<<1],tr[u<<1|1]);}
inline void build(int u,int l,int r){
if(l==r){
tr[u]={l,r,a[r],a[r]*a[r],0,1};
}
else {
tr[u]={l,r,0,0,0,1};
int mid=l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
}
inline ll query(int u,int l,int r,bool flag){
if(l<=tr[u].l&&r>=tr[u].r){
if(flag==0)return tr[u].sumh;
else return tr[u].sump;
}
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
ll res(0);
if(l<=mid)res+=query(u<<1,l,r,flag);
if(r>mid)res+=query(u<<1|1,l,r,flag);
return res;
}
inline void modify(int u,int l,int r,int add,int mul){
if(tr[u].r<=r&&tr[u].l>=l){
eval(tr[u],add,mul);
}
else {
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid)modify(u<<1,l,r,add,mul);
if(r>mid)modify(u<<1|1,l,r,add,mul);
pushup(u);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i(1);i<=n;i++)scanf("%d",&a[i]);
build(1,1,n);
while(m--)
{
int op,l,r;
ll x;
scanf("%d",&op);
if(op==1){
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,l,r,0));
}
else if(op==2){
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,l,r,1));
}
else if(op==3){
scanf("%d%d%lld",&l,&r,&x);
modify(1,l,r,0,x);
}
else {
scanf("%d%d%lld",&l,&r,&x);
modify(1,l,r,1,x);
}
}
}