#include <bits/stdc++.h>
  
using namespace std;
  
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second
  
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

// ?????¶?????¬segtree
template <typename T>
struct SegTree {
    int n;
    vector<T> dat, lazy;
    const T NIL = 2e18;
    const T DFLT;    // ???????????§????????? minQuery -> 1e18, maxQuery -> -1e18
    SegTree(int n_, const T& initV, const T& dflt) : DFLT(dflt) {
        n = 1;
        while (n < n_) n *= 2;
        dat.assign(2 * n - 1, initV);
        lazy.assign(2 * n - 1, NIL);
    }
    void add(int l, int r, const T& t) {
        add(l, r, t, 0, 0, n);
    }
    T query(int l, int r) {
        return query(l, r, 0, 0, n);
    }
private:
    T f(const T& a, const T& b) {
        return min(a, b);
    }
    void fix(int k) {
        dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
    void setLazy(int k, const T& v) {
        lazy[k] = v;
        dat[k] = v;
    }
    void push(int k) {
        if (lazy[k] == NIL) return;
        setLazy(k * 2 + 1, lazy[k]);
        setLazy(k * 2 + 2, lazy[k]);
        lazy[k] = NIL;
    }
    void add(int queryL, int queryR, const T& val, int k, int nodeL, int nodeR) {
        // ?????¨???????????¨????????????????????????????????????????????????????????\?????????????????????????????????
        if (nodeR <= queryL || queryR <= nodeL) {
            return;
        }
        // ???????????????????????¨?????????????????¨??????????????????????????¶????????????????????????????????£?????¨??°???
        if (queryL <= nodeL && nodeR <= queryR) {
            setLazy(k, val);
            return;
        }
        // ???????????????????????¨??????????????????push??????
        push(k);
        int nodeM = (nodeL + nodeR) / 2;
        add(queryL, queryR, val, k * 2 + 1, nodeL, nodeM);
        add(queryL, queryR, val, k * 2 + 2, nodeM, nodeR);

        // ???????????????????????¨??????????????±???fix??????
        fix(k);
    }
    T query(int queryL, int queryR, int k, int nodeL, int nodeR) {
        // ?????¨???????????¨???????????????????????????????????????
        if (nodeR <= queryL || queryR <= nodeL) {
            return DFLT;
        }
        // ???????????????????????¨?????????????????¨???????????????
        if (queryL <= nodeL && nodeR <= queryR) {
            return dat[k];
        }
        // ???????????????????????¨??????????????????push??????
        push(k);
        int nodeM = (nodeL + nodeR) / 2;
        T vl = query(queryL, queryR, k * 2 + 1, nodeL, nodeM);
        T vr = query(queryL, queryR, k * 2 + 2, nodeM, nodeR);
        return f(vl, vr);
    }
};

int main(){
    int n, q;
    cin >> n >> q;
    SegTree<ll> st(n, INT_MAX, INT_MAX);
    rep(i, q) {
        int a;
        cin >> a;
        if(a == 0) {
            int s, t, x;
            cin >> s >> t >> x;
            ++t;
            st.add(s, t, x);
        }
        else {
            int s, t;
            cin >> s >> t;
            ++t;
            cout << st.query(s, t) << endl;
        }
    }
    return 0;
}

Measured memory_bytes: 6960