#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
template <typename Monoid, typename LazyMonoid> class LazySegmentTree {
public:
  using FunctionMonoid = function<Monoid(Monoid, Monoid)>;
  using FunctionAction = function<Monoid(Monoid, LazyMonoid)>;
  using FunctionLazy = function<LazyMonoid(LazyMonoid, LazyMonoid)>;
  FunctionMonoid fm;
  FunctionAction fa;
  FunctionLazy fl;
  int n, height;
  vector<Monoid> data;
  vector<LazyMonoid> lazy;
  Monoid M_UNITY;
  LazyMonoid L_UNITY;
  void build (const int siz) {
    n = 1;
    height = 0;
    while (n < siz) n <<= 1, ++height;
    data.assign(2 * n, M_UNITY);
    lazy.assign(2 * n, L_UNITY);
  }
public:
  LazySegmentTree (FunctionMonoid f, FunctionAction g, FunctionLazy h, const Monoid& m_unity, const LazyMonoid& l_unity, int siz = 1) 
  : fm(f), fa(g), fl(h), M_UNITY(m_unity), L_UNITY(l_unity) {
    build(siz);
  }
  inline Monoid reflect (int k) {
    return lazy[k] == L_UNITY ? data[k] : fa(data[k], lazy[k]);
  }
  inline void propagate (int k) {
    if (lazy[k] == L_UNITY) return;
    lazy[(k << 1) | 0] = fl(lazy[(k << 1) | 0], lazy[k]);
    lazy[(k << 1) | 1] = fl(lazy[(k << 1) | 1], lazy[k]);
    data[k] = reflect(k);
    lazy[k] = L_UNITY;
  }
  inline void thrust (int k) {
    for (int i = height; i > 0; --i) propagate(k >> i);
  }
  inline void recalc (int k) {
    while (k >>= 1) data[k] = fm(reflect((k << 1) | 0), reflect((k << 1) | 1));
  }
  void modify (int left, int right, LazyMonoid val) {
    thrust(left += n);
    thrust(right += n - 1);
    for (int l = left, r = right + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1) lazy[l] = fl(lazy[l], val), l++;
      if (r & 1) --r, lazy[r] = fl(lazy[r], val);
    }
    recalc(left);
    recalc(right);
  }
  void modify (int idx, LazyMonoid val) {
    thrust(idx += n);
    data[idx] = val;
    lazy[idx] = L_UNITY;
    recalc(idx);
  }
  Monoid get (int left, int right) {
    thrust(left += n);
    thrust(right += n - 1);
    Monoid val_l = M_UNITY, val_r = M_UNITY;
    for (int l = left, r = right + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1) val_l = fm(val_l, reflect(l++));
      if (r & 1) val_r = fm(reflect(--r), val_r);
    }
    return fm(val_l, val_r);
  }
};
// template<typename Monoid, typename OperatorMonoid=Monoid>
// struct LazySegmentTree{
// 	using F=function<Monoid(Monoid, Monoid)>;
// 	using G=function<Monoid(Monoid, OperatorMonoid, int)>;
// 	using H=function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
// 	int sz;
// 	vector<Monoid> data;
// 	vector<OperatorMonoid> lazy;
// 	const F f;
// 	const G g;
// 	const H h;
// 	const Monoid e1;
// 	const OperatorMonoid e0;

// 	LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &e1, const OperatorMonoid &e0): f(f), g(g), h(h), e1(e1), e0(e0){
// 		sz=1;
// 		while(sz<n) sz<<=1;
// 		data.resize(2*sz-1, e1);
// 		lazy.resize(2*sz-1, e0);
// 	}

// 	void build(vector<Monoid> v){
// 		for(int i=0; i<v.size(); i++) data[i+sz-1]=v[i];
// 		for(int i=sz-2; i>=0; i--) data[i]=f(data[2*i+1], data[2*i+2]);
// 	}

// 	void eval(int k, int l, int r){
// 		if(lazy[k]!=e0){
// 			data[k]=g(data[k], lazy[k], r-l);
// 			if(k<sz-1){
// 				lazy[2*k+1]=h(lazy[2*k+1], lazy[k]);
// 				lazy[2*k+2]=h(lazy[2*k+2], lazy[k]);
// 			}
// 		}
// 		lazy[k]=e0;
// 	}

// 	void update(int a, int b, const OperatorMonoid &x, int k, int l, int r){
// 		eval(k, l, r);
// 		if(r<=a || b<=l) return;
// 		if(a<=l && r<=b){
// 			lazy[k]=h(lazy[k], x);
// 			eval(k, l, r);
// 		}else{
// 			update(a, b, x, 2*k+1, l, (l+r)/2);
// 			update(a, b, x, 2*k+2, (l+r)/2, r);
// 			data[k]=f(data[2*k+1], data[2*k+2]);
// 		}
// 	}
// 	void update(int a, int b, const OperatorMonoid &x){
// 		return update(a, b, x, 0, 0, sz);
// 	}

// 	Monoid find(int a, int b, int k, int l, int r){
// 		eval(k, l, r);
// 		if(b<=l || r<=a) return e1;
// 		if(a<=l && r<=b) return data[k];
// 		else return f(find(a, b, 2*k+1, l, (l+r)/2), find(a, b, 2*k+2, (l+r)/2, r));
// 	}
// 	Monoid find(int a, int b){
// 		return find(a, b, 0, 0, sz);
// 	}
// };
// template<typename Monoid> class SegmentTree {
// private:
//   using Func = function<Monoid(Monoid, Monoid)>;
//   Func func;
//   Monoid unity;
//   int siz;
//   vector<Monoid> data;
//   int n;
//   int height;
//   inline void build() {
//     siz = 1;
//     while (siz < n) siz <<= 1, ++height;
//     data.assign(siz << 1, unity);
//     for (int i = 0; i < n; i++) set(i, unity);
//     for (int idx = siz - 1; idx > 0; idx--) data[idx] = func(data[(idx << 1) | 0], data[(idx << 1) | 1]);
//   }
//   template<typename T> inline void build(const T& arr) {
//     if (!~n) n = (int) arr.size();
//     siz = 1;
//     while (siz < n) siz <<= 1, ++height;
//     data.assign(siz << 1, unity);
//     for (int i = 0; i < n; i++) set(i, arr[i]);
//     for (int idx = siz - 1; idx > 0; idx--) data[idx] = func(data[(idx << 1) | 0], data[(idx << 1) | 1]);
//   }
//   inline void set(int idx, const Monoid& val) { assert(idx + siz < (int) data.size()); data[idx + siz] = val;}

// public:
//   SegmentTree() {}
//   SegmentTree (const Func f, const Monoid& u, const int& n_) : func(f), unity(u), n(n_) { build(); }
//   template<typename T> SegmentTree (const T& arr, const Func f, const Monoid& u, int n_ = -1) : func(f), unity(u), n(n_) { build(arr); }
  

//   void initialize (const Func f, const Monoid &u, const int& n_) { func = f; unity = u; n = n_; build(); }
//   template<typename T> void initialize (const T& arr, const Func f, const Monoid& u, int n_ = -1) { func = f; unity = u; n = n_; buld(arr); }

//   void modify (int idx, const Monoid& val) {
//     idx += siz;
//     data[idx] = val;
//     while (idx >>= 1) data[idx] = func(data[(idx << 1) | 0], data[(idx << 1) | 1]);
//   }
//   //[left, right) 
//   Monoid get (int left, int right) {
//     if (left > right) swap(left, right);
//     Monoid val_left = unity, val_right = unity;
//     for (int l = left + siz, r = right + siz; l < r; l >>= 1, r >>= 1) {
//       if (l & 1) val_left = func(val_left, data[l++]);
//       if (r & 1) val_right = func(data[--r], val_right);
//     }
//     return func(val_left, val_right);
//   }

//   template<typename U>
//   int find (int start, int left, int right, int cur, Monoid& val, const U& f) {
//     if (left + 1 == right) {
//       val = func(val, data[cur]);
//       return f(val) ? cur - siz : -1;
//     }
//     int mid = (left + right) >> 1;
//     if (mid <= start) return find(start, mid, right, (cur << 1) | 1, val, f);
//     if (start <= left && !f(func(val, data[cur]))) {
//       val = func(val, data[cur]);
//       return -1;
//     }
//     int val_left = find(start, left, mid, (cur << 1) | 0, val, f);
//     if (~val_left) return val_left;
//     return find(start, mid, right, (cur << 1) | 1, val, f);
//   }
//   template<typename U>
//   int find (int start, const U& f) {
//     Monoid val = unity;
//     return find(start, 0, siz, 1, val, f);
//   }

//   inline Monoid operator[] (int idx) { return data[idx + siz]; }
//   void print() {
//     for (int i = 0; i < siz; i++) {
//       cout << (*this)[i];
//       if (i != siz - 1) cout << ", ";
//     }
//     cout << '\n';
//   }
// };

// // long long max
// function<long long(long long, long long)> LLMAX = [] (long long a, long long b) -> long long { return max(a, b); };
// const long long LLMAX_UNITY = numeric_limits<long long>::min();
// // int max
// function<int(int, int)> INTMAX = [] (int a, int b) -> int { return max(a, b); };
// const int INTMAX_UNITY = numeric_limits<int>::min();
// // long long min
// function<long long(long long, long long)> LLMIN = [] (long long a, long long b) -> long long { return min(a, b); };
// const long long LLMIN_UNITY = numeric_limits<long long>::max();
// // int min
// function<int(int, int)> INTMIN = [] (int a, int b) -> int { return min(a, b); };
// const int INTMIN_UNITY = numeric_limits<int>::max();
// // long long sum
// function<long long(long long, long long)> LLSUM = [] (long long a, long long b) -> long long { return a + b; };
// const long long LLSUM_UNITY = 0LL;
// // int sum
// function<int(int, int)> INTSUM = [] (int a, int b) -> int { return a + b; };
// const int INTSUM_UNITY = 0;

signed main() {
  ios::sync_with_stdio(false); cin.tie(0);
  int n, q;
  cin >> n >> q;
  auto fm = [] (long long a, long long b) {return min(a, b);};
  auto fa = [] (long long a, long long b) {return a + b;};
  auto fl = [] (long long a, long long b) {return a + b;};
  LazySegmentTree<long long, long long> sgt(fm, fa, fl, 1 << 30, 0, n + 10);
  for (int i = 0; i < n; i++) sgt.modify(i, 0);
  //LazySegmentTree<long long, long long> sgt(, fm, fa, fl, 0, 0, n + 10);
  for (int i = 0; i < q; i++) {
    int c;
    cin >> c;
    if (c == 0) {
      int l, r, x;
      cin >> l >> r >> x;
      sgt.modify(l, r + 1, x);
    } else {
      int l, r;
      cin >> l >> r;
      cout << sgt.get(l, r + 1) << '\n';
      // for (int i = 0; i < n; i++) {
      //   cerr << sgt.query(i, i + 1) << " ";
      // }
      // cerr << endl;
    }
  }
  // int n;
  // cin >> n;
  // string s;
  // cin >> s;
  // auto gmax = [] (int a, int b) {return max(a, b);};
  // auto gmin = [] (int a, int b) {return max(a, b);};
  // auto gsum = [] (int a, int b) {return a + b;};
  // SegmentTree<int> sum(INTSUM, INTSUM_UNITY, n + 10);
  // LazySegmentTree<int, int> mi(gmin, gsum, gsum, 0, 0, n + 10);
  // LazySegmentTree<int, int> mx(gmax, gsum, gsum, 0, 0, n + 10);
  // vector<int> v(n + 10);
  // int cur = 0;
  // for (int i = 0; i < n; i++) {
  //   if (s[i] == 'L') cur = max(0, cur - 1);
  //   else if (s[i] == 'R') cur++;
  //   else if (s[i] == '(') {
  //     if (v[cur] == 0) {
  //       sum.modify(cur, 1);
  //       mi.modify(cur, n + 5, 1);
  //       mx.modify(cur, n + 5, 1);
  //     } else if (v[cur] == -1) {
  //       sum.modify(cur, 1);
  //       mi.modify(cur, n + 5, 2);
  //       mx.modify(cur, n + 5, 2);
  //     }
  //     v[cur] = 1;
  //   } else if (s[i] == ')') {
  //     if (v[cur] == 0) {
  //       sum.modify(cur, -1);
  //       mi.modify(cur, n + 5, -1);
  //       mx.modify(cur, n + 5, -1);
  //     } else if (v[cur] == 1) {
  //       sum.modify(cur, -1);
  //       mi.modify(cur, n + 5, -2);
  //       mx.modify(cur, n + 5, -2);
  //     }
  //     v[cur] = -1;
  //   } else {
  //     if (v[cur] == 1) {
  //       sum.modify(cur, 0);
  //       mi.modify(cur, n + 5, -1);
  //       mx.modify(cur, n + 5, -1);
  //     } else if (v[cur] == -1) {
  //       sum.modify(cur, 0);
  //       mi.modify(cur, n + 5, 1);
  //       mx.modify(cur, n + 5, 1);
  //     }
  //     v[cur] = 0;
  //   }
  //   if (i > 0) cout << " ";
  //   if (sum.get(0, n + 8) == 0 && mi.get(0, n + 8) >= 0) cout << mx.get(0, n + 8);
  //   else cout << -1;
  //   cerr << "i = " << i << " s[i] = " << s[i] << " cur = " << cur << endl;
  //   cerr << sum.get(0, n + 8) << " " << mi.get(0, n + 8) << " " << mx.get(0, n + 8) << endl;
  // }
  // cout << '\n';
  return 0;
}


Measured memory_bytes: 7076