#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> l_l;
typedef pair<int , int> i_i;
typedef vector<ll> vel;
typedef vector<int> vei;
typedef vector<char> vec;
typedef vector<bool> veb;
typedef vector<string> ves;
typedef vector<vector<ll>> ve_vel;
typedef vector<vector<int>> ve_vei;
typedef vector<vector<char>> ve_vec;
typedef vector<vector<bool>> ve_veb;
typedef vector<vector<string>> ve_ves;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<(int)(n);i++)
#define rep2(i,n) for(int i=2;i<(int)(n);i++)
#define repk(i,k,n) for(int i=k;i<(int)(n);i++)
 
#define INF 2147483647 // 2^31-1

 
vector<ll> valuemi; // ノードの値を持つ配列
vector<ll> valuema; // ノードの値を持つ配列
vector<ll> value; // ノードの値を持つ配列
vector<ll> lazy;

int N;             // 葉の数
 
// i 番目の葉の値を x に変える(Range Minimum Query)
void updatemi(int i, ll x) {
    i += N - 1; // i 番目の葉のノード番号
    valuemi[i] = x;
    while (i > 0) {
        i = (i - 1) / 2; // ノード i の親ノードの番号に変える
        valuemi[i] = min(valuemi[i * 2 + 1], valuemi[i * 2 + 2]); // 左右の子の min を計算しなおす
    }
}

// i 番目の葉の値を x に変える(Range Maximum Query)
void updatema(int i, ll x) {
    i += N - 1; // i 番目の葉のノード番号
    valuema[i] = x;
    while (i > 0) {
        i = (i - 1) / 2; // ノード i の親ノードの番号に変える
        valuema[i] = max(valuema[i * 2 + 1], valuema[i * 2 + 2]); // 左右の子の max を計算しなおす
    }
}


// i 番目の葉の値に x を加える
void add(int i, ll x){
    i += N - 1;
    value[i] += x; //場所kに対応する節点にxを足す.
    while (i){
        i = (i - 1) / 2; //親に戻る
        value[i] = value[i * 2 + 1] + value[i * 2 + 2]; //親の区間の和は, 子の区間の和を足しあわせたもの.
    }
}

void eval(int k, int l, int r){

  if(lazy[k] != 0){
    value[k] += lazy[k];

    if(r-l > 1){
      lazy[2*k+1] += lazy[k] / 2;
      lazy[2*k+2] += lazy[k] / 2;
    }

    lazy[k] = 0;
  }

  return;
}

void secadd(int a, int b, ll x, int k = 0, int l = 0, int r = -1){

    if(r == -1) r = N;
    eval(k,l,r);
    if(r <= a || b <= l) return;
    if(a <= l && r <= b){
        lazy[k] += (r-l) * x;
        eval(k,l,r);
    }
    else{
        secadd(a, b, x, 2 * k + 1, l, (l+r) / 2);
        secadd(a, b, x, 2 * k + 2, (l+r) / 2, r);
        value[k] = value[2 * k + 1] + value[2 * k + 2];
    }
    return;
}

//区間[a, b)の和を求める.
ll getSum(int a, int b, int k, int l, int r){
    if(r == -1) r = N;
    eval(k, l, r);
    if (r <= a || b <= l) return 0;    
    if (a <= l && r <= b){ //[l, r)が[a, b)に完全に内包されていれば
        return (value[k]); //そのノードを返す
    }
    return getSum(a, b, k*2+1, l, (l+r)/2) + getSum(a, b, k*2+2, (l+r)/2, r); //区間を２つに分割して和を求める
}

 
// [a, b) の区間に対するクエリについてノード k （区間 [l, r) 担当）が答える 
//query(s, t + 1, 0, 0, N)でas,as+1,...,atの最小値を答える
ll querymi(int a, int b, int k, int l, int r) {
    
    if (r <= a || b <= l) return INF; // 区間が被らない場合は INF を返す
    if (a <= l && r <= b) return valuemi[k]; // ノード k の担当範囲がクエリ区間 [a, b)に完全に含まれる
    else {
        ll c1 = querymi(a, b, 2 * k + 1, l, (l + r) / 2); // 左の子に値を聞く
        ll c2 = querymi(a, b, 2 * k + 2, (l + r) / 2, r); // 右の子に値を聞く
        return min(c1, c2); // 左右の子の値の min を取る
    }
}

ll queryma(int a, int b, int k, int l, int r) {
    
    if (r <= a || b <= l) return -INF; // 区間が被らない場合は -INF を返す
    if (a <= l && r <= b) return valuema[k]; // ノード k の担当範囲がクエリ区間 [a, b)に完全に含まれる
    else {
        ll c1 = queryma(a, b, 2 * k + 1, l, (l + r) / 2); // 左の子に値を聞く
        ll c2 = queryma(a, b, 2 * k + 2, (l + r) / 2, r); // 右の子に値を聞く
        return max(c1, c2); // 左右の子の値の max を取る
    }
}

//AOJ(Range Minimum Query (RMQ))
//0-indexでの処理がよさそう?
 
int main(void) {
    int n, q;
    cin >> n >> q;
    N = 1;
    while (N < n) N *= 2; // 葉の数を計算（n以上の最小の2冪数）
 
    valuema = vector<ll>(2 * N - 1, -INF); 
    valuemi = vector<ll>(2 * N - 1, INF); 
    value = vector<ll>(2 * N - 1, 0); 
    lazy = vector<ll>(2 * N - 1, 0);

    

    for (int j = 0; j < q; j++) {
        int c; cin >> c;
        if (c == 0) {
            // update(i, x)
            int s, t, x; cin >> s >> t >> x;
            secadd(s-1, t, x);
        } 
        else {
            // find(s, t)
            int s, t; cin >> s >> t;
            cout << getSum(s - 1, t, 0, 0, N) << endl;
        }
    }
    return 0;
}


Measured memory_bytes: 11032