#include <bits/stdc++.h>
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) FOR(i, 1, n+1)
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define LEN(x) (int)(x).size()
#define DUMP(x) cout<<#x<<"="<<(x)<<endl;
#define pb push_back
#define eb emplace_back
using namespace std;
typedef long long lint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
typedef vector<int> vi;
typedef vector<lint> vl;
typedef vector<char> vc;
typedef vector<vector<int>> vvi;
typedef vector<vector<lint>> vvl;
typedef vector<vector<char>> vvc;
template <typename T> inline bool chmax(T &a, T b){if(a<b){a = b; return true;} return false;}
template <typename T> inline bool chmin(T &a, T b){if(a>b){a = b; return true;} return false;}
const double EPS = 1e-10;
const double PI = acos(-1);

template <class T>
class LazySegmentTree{
private:
    int n, _len;
    vector<T> dat, lazy;
    T def;

    void _eval(int k, int l, int r){
        if(lazy[k]){
            dat[k] += lazy[k];
            if(1<r-l){
                lazy[2*k+1] += lazy[k];
                lazy[2*k+2] += lazy[k];
            }
            lazy[k] = 0;
        }
    }

    T _query(int a, int b, int k, int l, int r){
        // [a, b), [l, r)
        if(r<=a or b<=l) return def;
        _eval(k, l, r);
        if(a<=l and r<=b) return dat[k];
        else{
            T c1 = _query(a, b, 2*k+1, l, (l+r)/2);
            T c2 = _query(a, b, 2*k+2, (l+r)/2, r);
            return min(c1, c2);
        }
    }

    void _change(int a, int b, T x, int k, int l, int r){
        _eval(k, l, r);
        if(b<=l or r<=a) return;
        else if(a<=l and r<=b){
            lazy[k] += x;
            _eval(k, l, r);
        } else {
            _change(a, b, x, 2*k+1, l, (l+r)/2);
            _change(a, b, x, 2*k+2, (l+r)/2, r);
            dat[k] = min(dat[2*k+1], dat[2*k+2]);
        }
    }

public:
    // [a, b)
    T query(int a, int b){
        assert(0<=a);
        assert(a<b);
        assert(b<=_len);
        return _query(a, b, 0, 0, n);
    }

    void change(int a, int b, T x){
        assert(0<=a);
        assert(a<b);
        assert(b<=_len);
        _change(a, b, x, 0, 0, n);
    }

    T operator[](int i){
        return dat[i+n-1];
    }

    LazySegmentTree(size_t _n, T _def)
            : def(_def){
        n = 1;
        while(n < _n){
            n *= 2;
        }
        dat.assign(2*n-1, def);
        lazy.resize(2*n-1);
    }

    LazySegmentTree(size_t _n, T _def, vector<T>& _v)
            : _len(_n), def(_def){
        n = 1;
        while(n < _n){
            n *= 2;
        }
        dat.assign(2*n-1, def);
        lazy.resize(2*n-1);
        for(int i=0;i<_n;++i) dat[n-1+i] = _v[i];
        for(int i=n-2;0<=i;--i) dat[i] = min(dat[2*i+1], dat[2*i+2]);
    }
};

class Task{
public:
    void solve(istream& in, ostream& out){
        int N, Q;
        in>>N>>Q;
        const int INF = (int)1e9;
        vi vec(N, 0);
        LazySegmentTree<int> dat(N, INF, vec);
        while(Q--){
            int t, l, r, x;
            in>>t>>l>>r;
            if(not t){
                in>>x;
                dat.change(l, r+1, x);
            }else{
                out<<dat.query(l, r+1)<<'\n';
            }
        }
    }
};

int main(){
    Task solver;
    istream& in(cin);
    ostream& out(cout);
    ios::sync_with_stdio(false);
    in.tie(nullptr), out.tie(nullptr);
    solver.solve(in, out);
    return 0;
}



Measured memory_bytes: 5220