#include <bits/stdc++.h>

using namespace std;

#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define REP(i, n) FOR(i, 0, n)

typedef int64_t ll;

ll INF = (1LL << 31) - 1;

int get_n(int n) {
    int ret = 1;
    while (ret < n) ret <<= 1;

    return ret;
}

struct SegTree {
    int N;
    vector<ll> dat;

    explicit SegTree(int n) : N(get_n(n)), dat(2 * N - 1, INF) {}

    explicit SegTree(const vector<ll> &v) {
        N = get_n(v.size());
        dat.resize(2 * N - 1, INF);

        REP(i, v.size()) dat[N + i - 1] = v[i];
        for (int i = N - 2; i > -1; --i) dat[i] = _op(dat[2 * i + 1], dat[2 * i + 2]);
    }

    ll _op(ll a, ll b) {
        return min(a, b);
    }

    void _up(ll &a, ll b) {
        a = b;
    }

    void update(int i, ll v) {
        i += N - 1;
        _up(dat[i], v);

        while (i > 0) {
            i = (i - 1) / 2;
            dat[i] = _op(dat[2 * i + 1], dat[2 * i + 2]);
        }
    }

    // query for [a, b), k: current node id, [l, r): current range.
    ll query(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = N;

        if (b <= l || r <= a) return INF;
        if (a <= l && r <= b) return dat[k];

        int mid = (l + r) / 2;
        ll c1 = query(a, b, 2 * k + 1, l, mid);
        ll c2 = query(a, b, 2 * k + 2, mid, r);

        return _op(c1, c2);
    }
};

// segment tree with lazy propagation
template<class T>
struct LazySegTree {
    using OP = function<T(T, T)>;  // function type for operation
    using UP = function<void(T &, T)>; // function type for updater

    OP op;
    UP up_d, up_l;
    T ue_d, ue_l; // unit element for dat and lazy
    int N;
    vector<T> dat, lazy;

    explicit LazySegTree(int n, const OP _op, const UP _up_d, const UP _up_l, const T _ue_d, const T _ue_l)
            : op(_op), up_d(_up_d), up_l(_up_l), ue_d(_ue_d), ue_l(_ue_l) {
        N = get_n(n);
        dat.assign(N * 2 - 1, ue_d);
        lazy.assign(N * 2 - 1, ue_l);
    }

    /* set, a is 0-indexed */
    void init(const T& v) {
        REP(i, N) dat[i + N - 1] = v;
        for(int i = N - 2; i >= 0; --i) {
            dat[i] = op(dat[i*2+1], dat[i*2+2]);
        }
    }

    inline void evaluate(int k) {
        if (lazy[k] == ue_l) return;

        if (k < N - 1) {
            up_l(lazy[k * 2 + 1], lazy[k]);
            up_l(lazy[k * 2 + 2], lazy[k]);
        }

        up_d(dat[k], lazy[k]);
        lazy[k] = ue_l;
    }

    // update [a, b). 0-indexed!!!!!!!!!!!
    void update(int a, int b, const T &v, int k = 0, int l = 0, int r = -1) {
        evaluate(k);
        if (r < 0) r = N;

        if (r <= a || b <= l) return;

        if (a <= l && r <= b) {
            up_l(lazy[k], v);
            evaluate(k);
            return;
        }

        int mid = (l + r) / 2;
        update(a, b, v, k * 2 + 1, l, mid);
        update(a, b, v, k * 2 + 2, mid, r);

        dat[k] = op(dat[k * 2 + 1], dat[k * 2 + 2]);
    }

    // query for [a, b). 0-indexed!!!!!!!!!!!
    T query(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = N;

        if (r <= a || b <= l) return ue_d;

        evaluate(k);
        if (a <= l && r <= b) return dat[k];

        int mid = (l + r) / 2;
        T q1 = query(a, b, k * 2 + 1, l, mid);
        T q2 = query(a, b, k * 2 + 2, mid, r);

        return op(q1, q2);
    }

    void debug() {
#ifdef LOCAL
        int c = 1;

        /* dat */
        cout << "### dat ###" << endl;

        REP(i, dat.size()) {
            if (i == c) {
                cout << endl;
                c = (c << 1) + 1;
            }
            cout << dat[i] << " ";
        }
        cout << endl;

        c = 1;
        /* lazy */
        cout << "### lazy ###" << endl;

        REP(i, lazy.size()) {
            if (i == c) {
                cout << endl;
                c = (c << 1) + 1;
            }
            cout << lazy[i] << " ";
        }

        cout << endl;
#endif
    }
};


// RSQ
template<typename T>
struct LSQ_LazySegTree {
    int N;
    vector<T> dat, lazy;

    explicit LSQ_LazySegTree(int n) : N(get_n(n)), dat(2 * N - 1, 0), lazy(2 * N - 1, 0) {}

    // add v to [a, b), current range: [l, r), node id: k
    void add(int a, int b, T v, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = N;

        if (r <= a || b <= l) return;

        if (a <= l && r <= b) {
            lazy[k] += v; // fl
            return;
        }

        int mid = (l + r) / 2;
        add(a, b, v, 2 * k + 1, l, mid);
        add(a, b, v, 2 * k + 2, mid, r);

        dat[k] += v * (min(b, r) - max(a, l));  // fa
    }

    T sum(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = N;

        if (r <= a || b <= l) return 0;

        if (a <= l && r <= b) {
            return dat[k] + lazy[k] * (r - l); //
        }


        int mid = (l + r) / 2;
        T r1 = sum(a, b, 2 * k + 1, l, mid);
        T r2 = sum(a, b, 2 * k + 2, mid, r);

        T ret = lazy[k] * (min(b, r) - max(a, l)); //

        return r1 + r2 + ret; //
    }
};

// starry sky tree
template<typename T>
struct LMQ_LazySegTree {
    int N;
    vector<T> dat, lazy;

    explicit LMQ_LazySegTree(int n) : N(get_n(n)), dat(2 * N - 1, 0), lazy(2 * N - 1, 0) {}

    // add v to [a, b), current range: [l, r), node id: k
    void add(int a, int b, T v, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = N;

        if (r <= a || b <= l) return;

        if (a <= l && r <= b) {
            lazy[k] += v;  //fl
            return;
        }

        int mid = (l + r) / 2;
        add(a, b, v, 2 * k + 1, l, mid);
        add(a, b, v, 2 * k + 2, mid, r);

        dat[k] = min(dat[2 * k + 1] + lazy[2 * k + 1], dat[2 * k + 2] + lazy[2 * k + 2]);  // fa
    }

    T query(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = N;

        if (r <= a || b <= l) return INF;

        if (a <= l && r <= b) {
            return dat[k] + lazy[k];
        }

        int mid = (l + r) / 2;
        T m1 = query(a, b, 2 * k + 1, l, mid);
        T m2 = query(a, b, 2 * k + 2, mid, r);

        T ret = lazy[k];

        return min(m1, m2) + ret; //
    }
};


// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A&lang=jp
int aoj_dsl_2a() {
    int n, q;
    cin >> n >> q;

    INF = (1LL << 31) - 1;

    SegTree st(n);

    REP(_, q) {
        int c, x, y;
        cin >> c >> x >> y;

        if (c == 0) st.update(x, y);
        else cout << st.query(x, y + 1) << endl;
    }

    return 0;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G&lang=jp
int aoj_dsl_2g() {
    int n, q;
    cin >> n >> q;

    LSQ_LazySegTree<ll> lst(n);

    REP(_, q) {
        int o, s, t;
        cin >> o >> s >> t;
        --s;
        --t;

        if (o == 0) {
            int x;
            cin >> x;
            lst.add(s, t + 1, x);
        } else {
            cout << lst.sum(s, t + 1) << endl;
        }
    }
    return 0;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_H&lang=jp
int aoj_dsl_2h() {
    int n, q;
    cin >> n >> q;

    LMQ_LazySegTree<ll> lst(n);

    REP(_, q) {
        int o, s, t;
        cin >> o >> s >> t;

        if (o == 0) {
            int x;
            cin >> x;
            lst.add(s, t + 1, x);
        } else {
            cout << lst.query(s, t + 1) << endl;
        }
    }
    return 0;
}

int main() {
    int n, q;
    cin >> n >> q;

    auto op = [](ll a, ll b) { return min(a, b); };
    auto up_d = [](ll &d, ll v) { d += v; };
    auto up_l = [](ll &l, ll v) { l += v; };

    LazySegTree<ll> lst(n, op, up_d, up_l, INF, 0);
    lst.init(0);

    REP(_, q) {
        int o, s, t;
        cin >> o >> s >> t;

        if (o == 0) {
            int x;
            cin >> x;
            lst.update(s, t + 1, x);
        } else {
            cout << lst.query(s, t + 1) << endl;
        }
    }
}





Measured memory_bytes: 7096