#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (int)(n); i ++)
#define irep(i,n) for (int i = (int)n - 1;i >= 0;--i)
using namespace std;
using ll = long long;
using PL = pair<ll,ll>;
using P = pair<int,int>;
constexpr ll INF = 2147483647;
constexpr long long HINF = 1000000000000000;
constexpr long long MOD = 1000000007;// = 998244353;
constexpr double EPS = 1e-4;
constexpr double PI = 3.14159265358979;



template <class Monoid1,class Monoid2> struct LazySegmentTree {
    int N;
    vector<Monoid1> tree;
    vector<Monoid2> lazy;

    //depending on the problem
    Monoid1 unit_x;
    Monoid2 unit_m;
    using FX = function<Monoid1(Monoid1,Monoid1)>; FX fx;
    using FA = function<Monoid1(Monoid1,Monoid2)>; FA fa;
    using FM = function<Monoid2(Monoid2,Monoid2)>; FM fm;
    //

    LazySegmentTree(int _N,Monoid1 _unitx,Monoid2 _unitm,FX _fx,FA _fa,FM _fm):
        N(_N),unit_x(_unitx),unit_m(_unitm),fx(_fx),fa(_fm),fm(_fm) {
        tree.assign(N + N,unit_x);
        lazy.assign(N + N,unit_m);
    }

    void build(vector<Monoid1> &array) {
        for (int i = N; i < 2*N; i++) tree[i] = array[i - N];
        for (int i = N - 1; i > 0; i--) tree[i] = fx(tree[i << 1],tree[i << 1|1]);
    }

    Monoid1 eval_at(int i) {
        return fa(tree[i],lazy[i]);
    }

    void propagate_at(int i) {
        tree[i] = eval_at(i);
        lazy[i << 1] = fm(lazy[i << 1],lazy[i]);
        lazy[i << 1|1] = fm(lazy[i << 1|1],lazy[i]);
        lazy[i] = unit_m;
    }

    void propagate_above(int i) {
        int H = 0;
        while ((1<<H) < i) ++H;
        for (int h = H;h > 0;--h) {
            propagate_at(i >> h);
        }
    }

    void recalc_above(int i) {
        while (i > 1) {
            i >>= 1;
            tree[i] = fx(eval_at(i << 1),eval_at(i << 1|1));
        }
    }

    void set_val(int i,Monoid1 x) {
        i += N;
        propagate_above(i);
        tree[i] = x;
        lazy[i] = unit_m;
        recalc_above(i);
    }

    Monoid1 fold(int L,int R) {
        L += N; R += N;
        propagate_above(L/(L & -L));
        propagate_above(R/(R & -R) - 1);
        Monoid1 vL = unit_x,vR = unit_x;
        while (L < R) {
            if (L&1) {vL = fx(vL,eval_at(L)); ++L;}
            if (R&1) {--R; vR = fx(eval_at(R),vR);}
            L >>= 1; R >>= 1;
        }
        return fx(vL,vR);
    }

    void operate_range(int L,int R,Monoid2 x) {
        L += N; R += N;
        int L0 = L/(L & -L),R0 = R/(R & -R) - 1;
        propagate_above(L0); propagate_above(R0);
        while (L < R) {
            if (L&1) {lazy[L] = fm(lazy[L],x); ++L;}
            if (R&1) {--R; lazy[R] = fm(lazy[R],x);}
            L >>= 1; R >>= 1;
        }
        recalc_above(L0); recalc_above(R0);
    }

    void debug() {
        for (int i = 0;i < 2*N;++i) {printf(" st[%d] : ",i); cout << tree[i];}
        cout << '\n';
        for (int i = 0;i < 2*N;++i) {printf(" lazy[%d] : ",i); cout << lazy[i];}
        cout << '\n';
    }
};

int main() {
    int N,Q; cin >> N >> Q;
    auto fx = [](ll a,ll b){return min(a,b);};
    auto fm = [](ll a,ll b){return b;};
    auto fa = [](ll a,ll b){
        if (b == INF) return a;
        return b;
    };
    LazySegmentTree<ll,ll> st(N,INF,INF,fx,fm,fa);
    rep(_,Q) {
        int a; cin >> a;
        if (a == 0) {
            int s,t,x; cin >> s >> t >> x;
            st.operate_range(s,t + 1,x);
        }
        else {
            int s,t; cin >> s >> t;
            cout << st.fold(s,t + 1) << '\n';
        }
    }
    return 0;
}


Measured memory_bytes: 5928