#include <algorithm>
#include <iostream>
#include <vector>
#include <math.h>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <iomanip>
#include <numeric>
#include <tuple>
#include <bitset>
#include <complex>
#include <unistd.h>
#include <cassert>
#include <cctype>
#include <random>
#include <time.h>
#include <functional>
#define _USE_MATH_DEFINES
#define _GLIBCXX_DEBUG
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> plglg;
typedef pair<double, ll> pdlg;
typedef tuple<int, int, int> tiii;
typedef tuple<ll, ll, ll> tlglglg;
typedef tuple<double, double, double> tddd;
typedef complex<double> xy_t;
typedef vector<ll> vll;
typedef vector< vector<ll> > matrix;
#define REP(i, x, y) for(ll i = (ll)x; i < (ll)y; i++)
#define DREP(i, x, y, d) for(ll i = (ll)x; i < (ll)y; i += (ll)d)
#define PER(i, x, y) for(ll i = (ll)x; i > (ll)y; i--)
#define DPER(i, x, y, d) for(ll i = (ll)x; i > (ll)y; i -= (ll)d)
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
double pi = 3.141592653589793;
ll mod = 1000000007;
int intmax = 2147483647;
int intmin = -2147483648;
ll llmax = 9223372036854775807;
ll llmin = -9223372036854775807;
int iinf = intmax / 8;
ll inf = llmax / 8;
double eps = 1e-12;

//abstruct lazy segment tree 抽象化遅延評価セグメント木（非再帰）
template<typename D, typename L>
struct segtree {
    using F = function<D(D, D)>;
    using G = function<D(L, D)>;
    using H = function<L(L, L)>;
    F f;
    G g;
    H h;
    D De;
    L Le;
    int n, height;
    vector<D> dat;
    vector<L> lazy;

    segtree(F f, G g, H h, D De, L Le):
        f(f), g(g), h(h), De(De), Le(Le){}
 
    void init(int n_) {
        n = 1;
        height = 0;
        while (n < n_) {
            n <<= 1;
            height++;
        }
        lazy.assign(2 * n, Le);
        dat.assign(2 * n, De);
    }

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

    D reflect(int k) {
        if (lazy[k] == Le) {
            return dat[k];
        } else {
            return g(lazy[k], dat[k]);
        }
    }

    void propagate(int k) {
        if (lazy[k] == Le) {
            return;
        }
        if (k < n) {
            lazy[k << 1] = h(lazy[k], lazy[k << 1]);
            lazy[(k << 1) | 1] = h(lazy[k], lazy[(k << 1) | 1]);
        }
        dat[k] = reflect(k);
        lazy[k] = Le;
    }

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

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

    //[a, b)の範囲に何かする
    void update(int a, int b, L x) {
        if (a >= b) {
            return;
        }
        a += n;
        thrust(a);
        b += n - 1;
        thrust(b);
        for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
            if (l & 1) {
                lazy[l] = h(x, lazy[l]);
                l++;
            }
            if (r & 1) {
                r--;
                lazy[r] = h(x, lazy[r]);
            }
        }
        recalc(a);
        recalc(b);
    }

    //k番目にaを代入する
    void setval(int a, D x) {
        a += n;
        thrust(a);
        dat[a] = x;
        lazy[a] = Le;
        recalc(a);
    }

    //[a, b)の範囲の情報を得る
    D query(int a, int b) {
        if (a >= b) {
            return De;
        }
        a += n;
        thrust(a);
        b += n - 1;
        thrust(b);
        D vl = De, vr = De;
        for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
            if (l & 1) {
                vl = f(vl, reflect(l));
                l++;
            }
            if (r & 1) {
                r--;
                vr = f(reflect(r), vr);
            }
        }
        return f(vl, vr);
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll n, q;
    cin >> n >> q;
    auto f = [](plglg a, plglg b){return plglg(a.first + b.first, a.second + b.second);};
    auto g = [](ll a, plglg b){return plglg(b.first + a * b.second, b.second);};
    auto h = [](ll a, ll b){return a + b;};
    segtree<plglg, ll> seg(f, g, h, plglg(0, 0), 0);
    seg.build(vector<plglg>(n, plglg(0, 1)));
    REP(i, 0, q) {
        ll que;
        cin >> que;
        if (que == 0) {
            ll s, t, x;
            cin >> s >> t >> x;
            seg.update(s - 1, t, x);
        } else {
            ll s, t;
            cin >> s >> t;
            cout << seg.query(s - 1, t).first << endl;
        }
        // REP(i, 0, 2 * seg.n) {
        //     cout << seg.dat[i].first << " " << seg.dat[i].second << " aaa ";
        // }
        // cout << endl;
    }
}



Measured memory_bytes: 10436