#include <bits/stdc++.h>
using namespace std;
using ll = long long;

template <typename Monoid, typename OperatorMonoid> struct LazySegmentTree {
    using F = function<Monoid(Monoid, Monoid)>;
    using G = function<Monoid(Monoid, OperatorMonoid, int)>;
    using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

    int sz, height;
    vector<Monoid> data;
    vector<OperatorMonoid> lazy;
    vector<int> len;
    const F f;
    const G g;
    const H h;
    const Monoid M0;
    const OperatorMonoid O0;

    LazySegmentTree(F f, G g, H h, Monoid M0, OperatorMonoid O0)
        : f(f), g(g), h(h), M0(M0), O0(O0) {}

    constexpr void init(const int n) {
        sz = 1;
        height = 0;
        while(sz < n)
            sz <<= 1, height++;
        data.assign(sz << 1, M0);
        lazy.assign(sz << 1, O0);
        len.assign(sz << 1, 1);
        for(int i = sz - 1; i; i--)
            len[i] = len[i << 1] << 1;
    }

    constexpr void build(const vector<Monoid> &v) {
        int n = v.size();
        init(n);
        for(int i = 0; i < n; i++)
            data[sz + i] = v[i];
        for(int i = sz - 1; i; i--)
            data[i] = f(data[i << 1], data[i << 1 | 1]);
    }

    constexpr Monoid reflect(int k) const {
        return lazy[k] == O0 ? data[k] : g(data[k], lazy[k], len[k]);
    }

    constexpr void propagate(int k) {
        if(lazy[k] == O0) return;
        lazy[k << 1] = h(lazy[k << 1], lazy[k]);
        lazy[k << 1 | 1] = h(lazy[k << 1 | 1], lazy[k]);
        data[k] = reflect(k);
        lazy[k] = O0;
    }

    constexpr void thrust(int k) {
        for(int i = height; i; i--)
            propagate(k >> i);
    }

    constexpr void thrust(const int l, const int r) {
        if(l == r) {
            thrust(l);
            return;
        }
        int Xor = l ^ r, i = height;
        for(; !(Xor >> i); i--)
            propagate(l >> i);
        for(; i; i--) {
            propagate(l >> i);
            propagate(r >> i);
        }
    }

    constexpr void recalc(int k) {
        while(k >>= 1)
            data[k] = f(reflect(k << 1), reflect(k << 1 | 1));
    }

    constexpr void recalc(int l, int r) {
        int Xor = l ^ r;
        while(Xor >>= 1) {
            l >>= 1;
            r >>= 1;
            data[l] = f(reflect(l << 1), reflect(l << 1 | 1));
            data[r] = f(reflect(r << 1), reflect(r << 1 | 1));
        }
        while(l >>= 1)
            data[l] = f(reflect(l << 1), reflect(l << 1 | 1));
    }

    constexpr void update(int a, int b, const OperatorMonoid x) {
        if(a >= b) return;
        thrust(a += sz, b += sz - 1);
        for(int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
            if(l & 1) lazy[l] = h(lazy[l], x), l++;
            if(r & 1) --r, lazy[r] = h(lazy[r], x);
        }
        recalc(a, b);
    }

    constexpr void set_val(int a, const Monoid x) {
        thrust(a += sz);
        data[a] = x;
        lazy[a] = O0;
        recalc(a);
    }

    constexpr Monoid query(int a, int b) {
        if(a >= b) return M0;
        thrust(a += sz, b += sz - 1);
        Monoid vl = M0, vr = M0;
        for(int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
            if(l & 1) vl = f(vl, reflect(l++));
            if(r & 1) vr = f(reflect(--r), vr);
        }
        return f(vl, vr);
    }

    template <typename C>
    constexpr int find(const int st, const C check, Monoid &acc, const int k,
                       const int l, const int r) {
        if(l + 1 == r) {
            acc = f(acc, reflect(k));
            return check(acc) ? k - sz : -1;
        }
        propagate(k);
        int m = (l + r) >> 1;
        if(m <= st) return find(st, check, acc, k << 1 | 1, m, r);
        if(st <= l && !check(f(acc, data[k]))) {
            acc = f(acc, data[k]);
            return -1;
        }
        int vl = find(st, check, acc, k << 1, l, m);
        if(~vl) return vl;
        return find(st, check, acc, k << 1 | 1, m, r);
    }

    template <typename C> constexpr int find(const int st, const C check) {
        Monoid acc = M0;
        return find(st, check, acc, 1, 0, sz);
    }
};

inline int readint() {
    int res = 0;
    char c = getchar();
    while('0' <= c && c <= '9') {
        (res *= 10) += c - '0';
        c = getchar();
    }
    return res;
}
char memo[100];
inline void writeint(ll x) {
    int p = 0;
    do {
        memo[p++] = x % 10 + '0';
        x /= 10;
    } while(x);
    while(p--)
        putchar(memo[p]);
    putchar('\n');
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    auto f = [](ll a, ll b) { return a + b; };
    auto g = [](ll a, ll b, int len) { return a + b * len; };
    auto h = [](ll a, ll b) { return a + b; };
    LazySegmentTree<ll, ll> seg(f, g, h, 0, 0);
    seg.init(readint());

    int q, l, r, x;
    q = readint();
    while(q--) {
        if(readint() == 0) {
            l = readint() - 1;
            r = readint();
            x = readint();
            seg.update(l, r, x);
        } else {
            l = readint() - 1;
            r = readint();
            writeint(seg.query(l, r));
        }
    }
}


Measured memory_bytes: 8068