#include <bits/stdc++.h>
using namespace std;
struct Node {
int L;
int R;
long long sum;
long long lz;
Node() {
L = 0;
R = 0;
sum = 0;
lz = 0;
}
Node(long long x) {
L = 0;
R = 0;
sum = x;
lz = 0;
}
};
int n, q;
vector<long long> a;
vector<Node> t;
vector<int> root;
long long comb(long long x, long long y) {
return x + y;
}
int new_node() {
t.push_back(Node());
return (int)t.size() - 1;
}
int clone(int x) {
t.push_back(t[x]);
return (int)t.size() - 1;
}
void pull(int x, int l, int r) {
if (l == r) {
return;
}
t[x].sum = comb(t[t[x].L].sum, t[t[x].R].sum) + t[x].lz * (r - l + 1);
}
void apply(int x, int l, int r, long long y) {
t[x].sum += y * (r - l + 1);
t[x].lz += y;
}
int build(int l, int r) {
int x = new_node();
if (l == r) {
t[x] = Node(a[l]);
return x;
}
int m = (l + r) / 2;
t[x].L = build(l, m);
t[x].R = build(m + 1, r);
pull(x, l, r);
return x;
}
int upd(int x, int l, int r, int tl, int tr, long long y) {
if (tl > tr) {
return x;
} else if (l == tl && r == tr) {
int cur = clone(x);
apply(cur, l, r, y);
return cur;
}
int cur = clone(x);
int m = (l + r) / 2;
t[cur].L = upd(t[cur].L, l, m, tl, min(m, tr), y);
t[cur].R = upd(t[cur].R, m + 1, r, max(m + 1, tl), tr, y);
pull(cur, l, r);
return cur;
}
long long get(int x, int l, int r, int tl, int tr) {
if (tl > tr) {
return 0;
} else if (l == tl && r == tr) {
return t[x].sum;
}
int m = (l + r) / 2;
long long res = 0;
res += get(t[x].L, l, m, tl, min(m, tr));
res += get(t[x].R, m + 1, r, max(m + 1, tl), tr);
res += t[x].lz * (tr - tl + 1);
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> q;
a.assign(n + 1, 0);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
t.reserve((n + q) * 70);
t.push_back(Node());
root.push_back(build(1, n));
while (q--) {
int type;
cin >> type;
if (type == 1) {
int v, l, r;
long long y;
cin >> v >> l >> r >> y;
root.push_back(upd(root[v], 1, n, l, r, y));
} else {
int v, l, r;
cin >> v >> l >> r;
cout << get(root[v], 1, n, l, r) << '\n';
}
}
return 0;
}