#include "bits/stdc++.h"

#define REP(i,num) for(ll i=0;i<(num);++i)
#define FOR(i,c,num) for(ll (i)=(c);(i)<(num);++(i))
#define LOOP(i) while(i--)
#define ALL(c) c.begin(),c.end()
#define PRINTALL(c) for(auto pitr=c.begin();pitr!=c.end();++pitr){cout<<*pitr;if(next(pitr,1)!=c.end())cout<<' ';}cout<<endl;
#define PAIRCOMP(c,comp) [](const pair<ll,ll>& lhs,const pair<ll,ll>& rhs){return lhs.c comp rhs.c;}

using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;

constexpr ll atcoder_mod = 1e9+7;

template<typename T=ll>
T in(){T x; cin >> x; return (x);}
template<typename T=ll,typename C=vector<T>>
C vecin(int N){C x(N);REP(i,N){x[i]=in<T>();}return x;}

void vout(){cout << endl;}
template<typename Head,typename... Tail>
void vout(Head&& h,Tail&&... t){cout << ' ' << h;vout(forward<Tail>(t)...);}
void out(){cout << endl;}
template<typename Head,typename... Tail>
void out(Head&& h,Tail&&... t){cout << h;vout(forward<Tail>(t)...);}

template<typename T>
bool chmax(T& a,T b){if(a<b){a=b;return true;}return false;}
template<typename T>
bool chmin(T& a,T b){if(a>b){a=b;return true;}return false;}

/* 処理：範囲加算　出力：範囲合計値
auto fx = [](ll x1, ll x2){ return x1 + x2; };
auto fa = [](ll x, ll m){ return x + m; };
auto fm = [](ll m1, ll m2){ return m1 + m2; };
auto fp = [](ll m, ll n){ return m * n; };
long long ex = 0;
long long em = 0;
*/

auto fx = [](ll x1, ll x2){ return min(x1 , x2); };
auto fa = [](ll x, ll m){ return x + m; };
auto fm = [](ll m1, ll m2){ return m1 + m2; };
auto fp = [](ll m, ll n){ return m; };
long long ex = numeric_limits<ll>::max();
long long em = 0;

/* SegTreeLazyProportional<X,M>(n,fx,fa,fm,fp,ex,em): モノイド(集合X, 二項演算fx,fa,fm,p 単位元ex,em)についてサイズnで構築
set(int i, X x), build(): i番目の要素をxにセット。まとめてセグ木を構築する。O(n)
update(i,x): i 番目の要素を x に更新。O(log(n))
query(a,b):  [a,b) 全てにfxを作用させた値を取得。O(log(n))
*/
template <typename X, typename M>
struct SegTreeLazyProportional {
	using FX = function<X(X, X)>;
	using FA = function<X(X, M)>;
	using FM = function<M(M, M)>;
	using FP = function<M(M, int)>;
	int n;
	FX fx;
	FA fa;
	FM fm;
	FP fp;
	const X ex;
	const M em;
	vector<X> dat;
	vector<M> lazy;
	SegTreeLazyProportional(int n_, FX fx_, FA fa_, FM fm_, FP fp_, X ex_, M em_)
		: n(), fx(fx_), fa(fa_), fm(fm_), fp(fp_), ex(ex_), em(em_), dat(n_ * 4, ex), lazy(n_ * 4, em) {
		int x = 1;
		while (n_ > x) x *= 2;
		n = x;
	}
	void set(int i, X x) { dat[i + n - 1] = x; }
	void build() {
		for (int k = n - 2; k >= 0; k--) dat[k] = fx(dat[2 * k + 1], dat[2 * k + 2]);
	}
	/* lazy eval */
	void eval(int k, int len) {
		if (lazy[k] == em) return;  // 更新するものが無ければ終了
		if (k < n - 1) {            // 葉でなければ子に伝搬
			lazy[k * 2 + 1] = fm(lazy[k * 2 + 1], lazy[k]);
			lazy[k * 2 + 2] = fm(lazy[k * 2 + 2], lazy[k]);
		}
		// 自身を更新
		dat[k] = fa(dat[k], fp(lazy[k], len));
		lazy[k] = em;
	}
	void update(int a, int b, M x, int k, int l, int r) {
		eval(k, r - l);
		if (a <= l && r <= b) {  // 完全に内側の時
			lazy[k] = fm(lazy[k], x);
			eval(k, r - l);
		} else if (a < r && l < b) {                     // 一部区間が被る時
			update(a, b, x, k * 2 + 1, l, (l + r) / 2);  // 左の子
			update(a, b, x, k * 2 + 2, (l + r) / 2, r);  // 右の子
			dat[k] = fx(dat[k * 2 + 1], dat[k * 2 + 2]);
		}
	}
	void update(int a, int b, M x) { update(a, b, x, 0, 0, n); }
	X query_sub(int a, int b, int k, int l, int r) {
		eval(k, r - l);
		if (r <= a || b <= l) {  // 完全に外側の時
			return ex;
		} else if (a <= l && r <= b) {  // 完全に内側の時
			return dat[k];
		} else {  // 一部区間が被る時
			X vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
			X vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
			return fx(vl, vr);
		}
	}
	X query(int a, int b) { return query_sub(a, b, 0, 0, n); }
};

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	auto N=in(),Q=in();

	using X = long long;
	using M = long long;
	SegTreeLazyProportional<X, M> rsq(N, fx, fa, fm, fp, ex, em);
	for (int i = 0; i < N; i++) {
		rsq.set(i, 0);
	}
	rsq.build();

	vector<long long> ans;
	for (int i = 0; i < Q; i++) {
		int c;
		cin >> c;
		if (c == 0) {
			int s, t;
			long long x;
			cin >> s >> t >> x;
			//s--, t--;
			rsq.update(s, t + 1, x);
		} else if (c == 1) {
			int s, t;
			cin >> s >> t;
			//s--, t--;
			ans.push_back(rsq.query(s, t + 1));
		}
	}
	for (auto i : ans) {
		cout << i << endl;
	}
	return 0;
}



Measured memory_bytes: 10232