/*
 * RSQ and RAQ
 *  Created on: 2017/06/28
 *      Author: LitMc
 */
//#define MYDEBUG
#include <bits/stdc++.h>
#ifdef MYDEBUG
#define dbp(x) cout<<#x<<": "<<x<<endl
#define dbp2(x,y) cout<<#x<<","<<#y<<": "<<x<<","<<y<<endl
#define dbp3(x,y,z) cout<<#x<<","<<#y<<","<<#z<<": "<<x<<","<<y<<","<<z<<endl
#define dbp4(w,x,y,z) cout<<#w<<","<<#x<<","<<#y<<","<<#z<<": "<<w<<","<<x<<","<<y<<","<<z<<endl
#define ifcin(x) std::ifstream cin(x)
#else
#define dbp(x)
#define dbp2(x,y)
#define dbp3(x,y,z)
#define dbp4(w,x,y,z)
#define ifcin(x)
#endif
#define ll long long
#define ull unsigned long long
#define all(x) x.begin(), x.end()
#define rep(i, from, to) for(int i=from; i<to; ++i)
#define REP(i, from, to) for(int i=from; i<=to; ++i)
#define EPS = 1e-14;
using std::vector;
using std::cout;
using std::cin;
using std::endl;
using std::max;
using std::min;
using std::swap;
using std::string;
using std::fill;
using std::pair;
using std::sort;
using std::reverse;
using std::pair;
using std::greater;
using std::priority_queue;
using std::ostream;
using std::unique;

template<typename T>
ostream& operator<<(ostream& out, const vector<vector<T> >& v) {
	for (size_t i = 0; i < v.size(); ++i) {
		out << v[i] << endl;
	}
	return out;
}

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& v) {
	out << "[";
	size_t last = v.size() - 1;
	for (size_t i = 0; i < v.size(); ++i) {
		out << v[i];
		if (i != last) {
			out << ",";
		}
	}
	out << "]";
	return out;
}

struct edge {
	int from, to, cost;
	edge() {
		*this = edge(-1, -1, -1);
	}
	edge(int from_, int to_, int cost_) {
		from = from_;
		to = to_;
		cost = cost_;
	}
	bool operator<(const edge& e) const {
		return cost < e.cost;
	}
};

static const int MAX_N = 1 << 19;
static const int VAL_INIT = 0;
static const int LAZY_INIT = 0;
int N;
ll sum[MAX_N * 2], lazy[MAX_N * 2];

void init(int n_) {
	N = 1;
	while (N < n_) {
		N *= 2;
	}
	rep(i,0,N*2-1)
	{
		sum[i] = VAL_INIT;
		lazy[i] = LAZY_INIT;
	}
}

void setLazy(int k, int x, int nodeL, int nodeR) {
	lazy[k] += x;
	sum[k] += (nodeR - nodeL) * (ll) x;
}

void push(int k, int nodeL, int nodeR) {
	if (lazy[k] == LAZY_INIT) {
		return;
	}
	int nodeM = (nodeL + nodeR) / 2;
	setLazy(k * 2 + 1, lazy[k], nodeL, nodeM);
	setLazy(k * 2 + 2, lazy[k], nodeM, nodeR);
	lazy[k] = LAZY_INIT;
}

void fix(int k) {
	sum[k] = sum[k * 2 + 1] + sum[k * 2 + 2];
}

void add(int queryL, int queryR, int x, int k = 0, int nodeL = 0,
		int nodeR = N) {
	if (queryR <= nodeL || nodeR <= queryL) {
		return;
	}
	if (queryL <= nodeL && nodeR <= queryR) {
		setLazy(k, x, nodeL, nodeR);
		return;
	}
	push(k, nodeL, nodeR);
	int nodeM = (nodeL + nodeR) / 2;
	add(queryL, queryR, x, k * 2 + 1, nodeL, nodeM);
	add(queryL, queryR, x, k * 2 + 2, nodeM, nodeR);
	fix(k);
}

ll getSum(int queryL, int queryR, int k = 0, int nodeL = 0, int nodeR = N) {
	if (queryR <= nodeL || nodeR <= queryL) {
		return 0;
	}
	if (queryL <= nodeL && nodeR <= queryR) {
		return sum[k];
	}
	push(k, nodeL, nodeR);
	int nodeM = (nodeL + nodeR) / 2;
	ll vl = getSum(queryL, queryR, k * 2 + 1, nodeL, nodeM);
	ll vr = getSum(queryL, queryR, k * 2 + 2, nodeM, nodeR);
	fix(k);
	return vl + vr;
}

void print() {
	cout << "sum:";
	rep(i,N-1,2*N-1)
	{
		printf("%2lld ", sum[i]);
	}
	cout << endl;
}

int n, q;
int c, s, t, x;
void solve() {
	cin >> n >> q;
	init(n);
	rep(query, 0, q)
	{
		cin >> c;
		if (c == 0) {
			cin >> s >> t >> x;
			s--;
			t--;
			add(s, t + 1, x);
		} else {
			cin >> s >> t;
			s--;
			t--;
			cout << getSum(s, t + 1) << endl;
		}
	}
}

int main() {
	solve();
}

Measured memory_bytes: 7216