#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct {
int l;
int r;
long long val;
long long lazy;
}tree[401000];
long long nums[401000];
void push_down(int u, int m) {
if (tree[u].lazy) {
tree[u << 1].lazy += tree[u].lazy;
tree[u << 1 | 1].lazy += tree[u].lazy;
tree[u << 1].val += tree[u].lazy * (m - (m >> 1));
tree[u << 1 | 1].val += tree[u].lazy * (m - (m >> 1));
tree[u].lazy = 0;
}
}
void buildTree(int l, int r, int u)
{
tree[u].lazy = 0;
tree[u].l = l;
tree[u].r = r;
if (l == r) {
tree[u].val = nums[l];
return;
}
int mid = l + ((r - l) >> 1);
buildTree(l, mid, u << 1);
buildTree(mid + 1, r, u << 1 | 1);
tree[u].val = tree[u << 1].val + tree[u << 1 | 1].val;
}
void update(int l, int r, long long k, int u = 1) {
if (tree[u].l >= l && tree[u].r <= r) {
tree[u].val += (tree[u].r - tree[u].l + 1) * k;
tree[u].lazy += k;
return;
}
push_down(u, tree[u].r - tree[u].l + 1);
int mid = (tree[u].l + tree[u].r) >> 1;
if (l <= mid) {
update(l, r, k, u << 1);
}
if (r > mid) {
update(l, r, k, u << 1 | 1);
}
tree[u].val = tree[u << 1].val + tree[u << 1 | 1].val;
}
long long query(int l, int r, int u = 1) {
if (tree[u].l >= l && tree[u].r <= r)
return tree[u].val;
push_down(u, tree[u].r - tree[u].l + 1);
long long ans = 0;
int mid = (tree[u].l + tree[u].r) >> 1;
if (l <= mid)
ans += query(l, r, u << 1);
if (r > mid)
ans += query(l, r, u << 1 | 1);
return ans;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &nums[i]);
buildTree(1, n, 1);
while(m--) {
int s;
scanf("%d", &s);
if (s == 1) {
int x, y, k;
scanf("%d%d%d", &x, &y, &k);
update(x, y, k);
} else if (s == 2) {
int x, y;
scanf("%d%d", &x, &y);
long long ans = query(x, y);
printf("%lld\n",ans);
}
}
return 0;
}