#include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using ll=long long;
using R=long double;
const R EPS=1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R& r){return(r > EPS)-(r < -EPS);}
inline R sq(R x){return sqrt(max(x,0.0L));}

const int dx[8]={1,0,-1,0,1,-1,-1,1};
const int dy[8]={0,1,0,-1,1,1,-1,-1};

const pid_t pid = getpid();
// Problem Specific Parameter:

template <typename T> 
class SegmentTree {
	public:
		struct node {
			T val = 0;
			T add = 0;
			int cnt = 1;

			void apply(int l, int r, T v) {
				val += v;
				add += v;
			}
		};

		int n;
		vector<node> data;
		const T inf = 1e9;
		const node out = {inf, 0, 1};

		SegmentTree(int _n) : n(_n) {
			assert(n > 0);
			const int m = 1 << (33-__builtin_clz(n));
			data.resize(m);
			build(0, 0, n);
		}

		template <typename M>
		SegmentTree(const vector<M> &v){
			n = v.size();
			assert(n > 0);
			const int m = 1 << (33-__builtin_clz(n));
			data.resize(m);
			build(0, 0, n, v);
		}

		inline node unite(node a, node b) {
			node res;
		    res.val = min(a.val, b.val);
		    res.add = 0;
		    res.cnt = (a.val == res.val ? a.cnt : 0) + (b.val == res.val ? b.cnt : 0);
		    return res;
  		}

	private:
		void push(int p, int l, int r) {
			const int m = (l + r) / 2;
			data[2 * p + 1].apply(l, m, data[p].add);
			data[2 * p + 2].apply(m, r, data[p].add);
			data[p].add = 0;
		}

		inline void pull(int k) {
    		data[k] = unite(data[2 * k + 1], data[2 * k + 2]);
  		}

  		void build(int k, int l, int r){
			if(r - l == 1) return;
			const int m = (l + r) / 2;
			build(2 * k + 1, l, m);
			build(2 * k + 2, m, r);
		    pull(k);
		}

		template <typename M>
		void build(int k, int l, int r, const vector<M> &v){
			if(r - l == 1){
				data[k].apply(l, r, v[l]);
				return;
			}
			const int m = (l + r) / 2;
			build(2 * k + 1, l, m);
			build(2 * k + 2, m, r);
			pull(k);
		}

		void range_update(int a, int b, int k, int l, int r, T x) {
			if (r <= a or b <= l) return;
			if (a <= l and r <= b){
				data[k].apply(l, r, x);
				return;
			}
			push(k, l, r);
			const int m = (l + r) / 2;
			range_update(a, b, 2 * k + 1, l, m, x);
			range_update(a, b, 2 * k + 2, m, r, x);
			pull(k);
		}

		node range_query(int a, int b, int k, int l, int r) {
			if (r <= a or b <= l) return out;
			if (a <= l and r <= b) return data[k];
			push(k, l, r);
			const int m = (l + r) / 2;
			node vl = range_query(a, b, 2 * k + 1, l, m);
			node vr = range_query(a, b, 2 * k + 2, m, r);
			return unite(vl, vr);
		}
	public:
		void range_update(int a, int b, T x){
			range_update(a, b, 0, 0, n, x);
		}

		node range_query(int a, int b){
			return range_query(a, b, 0, 0, n);
		}
};

int main(void){
	int n,q;
	cin >> n >> q;
	
	SegmentTree<int> seg(n);

	rep(loop,q){
		int t;
		cin >> t;
		if(t){
			int l, r;
			cin >> l >> r;
			r++;
			cout << seg.range_query(l, r).val << endl;
		} else {
			int l, r, x;
			cin >> l >> r >> x;
			r++;
			seg.range_update(l, r, x);
		}
	}

	return 0;
}


Measured memory_bytes: 6088