#include <cinttypes>
#include <climits>
#include <iostream>

template <typename Tp, typename Op>
class segment_tree{
    Tp *value;
    Op *operation;
    size_t *width;
    const size_t length;
    const Tp vid;
    const Op oid;
    Tp (*const merger)(const Tp &lhs, const Tp &rhs);
    Op (*const composition)(const Op &lhs, const Op &rhs);
    Tp (*const action)(const Op &f, const Tp &x, size_t width);

    void evaluate(size_t pos){
        if(operation[pos] == oid) return;
        if(pos < length){
            operation[pos<<1 | 0] = composition(operation[pos], operation[pos<<1 | 0]);
            operation[pos<<1 | 1] = composition(operation[pos], operation[pos<<1 | 1]);
        }
        value[pos] = action(operation[pos], value[pos], width[pos]);
        operation[pos] = oid;
    }
    void propagate(size_t left, size_t right){
        for(int i = sizeof(unsigned int) * CHAR_BIT - __builtin_clz(left ) - 1; i > 0; --i) evaluate(left  >> i);
        for(int i = sizeof(unsigned int) * CHAR_BIT - __builtin_clz(right) - 1; i > 0; --i) evaluate(right >> i);
    }
    void update(size_t left, size_t right){
        for(left  >>= __builtin_ctz(left ) + 1; left ; left  >>= 1){
            evaluate(left <<1 | 0);
            evaluate(left <<1 | 1);
            value[left ] = merger(value[left <<1 | 0], value[left <<1 | 1]);
        }
        for(right >>= __builtin_ctz(right) + 1; right; right >>= 1){
            evaluate(right <<1 | 0);
            evaluate(right <<1 | 1);
            value[right] = merger(value[right<<1 | 0], value[right<<1 | 1]);
        }
    }
public:
    segment_tree(size_t n, Tp e, Tp(*const fold)(const Tp&, const Tp&), Op id, Op (*const compose)(const Op&, const Op&), Tp (*const apply)(const Op&, const Tp&, size_t))
    : length(n), vid(e), oid(id), merger(fold), composition(compose), action(apply){
        value     = new Tp[n<<1];
        operation = new Op[n<<1];
        width     = new size_t[n<<1];
        for(size_t i = 1; i < (n<<1); ++i){ value[i] = e; operation[i] = id; width[i] = 1; }
        for(size_t i = n - 1; i > 0; --i) width[i] = width[i<<1 | 0] + width[i<<1 | 1];
    }
    void set(size_t left, size_t right, Op f){
        if(left >= right) return;
        size_t l, r;
        l = left  = left  + length;
        r = right = right + length;
        propagate(left, right);
        while(l < r){
            if(l & 1){ operation[l] = composition(f, operation[l]); ++l; }
            l >>= 1;
            if(r & 1){ --r; operation[r] = composition(f, operation[r]); }
            r >>= 1;
        }
        update(left, right);
    }
    Tp get(size_t left, size_t right){        
        if(left >= right) return vid;
        left  += length;
        right += length;
        propagate(left, right);
        Tp lval = vid, rval = vid;
        while(left < right){
            if(left  & 1){ evaluate(left ); lval = merger(lval, value[left ]); ++left ; }
            left >>= 1;
            if(right & 1){ --right; evaluate(right); rval = merger(value[right], rval); }
            right >>= 1;
        }
        return merger(lval, rval);
    }
};

int main(){
    size_t n;
    int q;
    std::cin >> n >> q;

    using Tp = int64_t;
    using Op = int64_t;
    segment_tree<Tp, Op> st{ n,
        INT64_MAX, [](auto lhs, auto rhs){ return std::min(lhs, rhs); },
        -1, [](auto lhs, auto rhs){ return lhs == -1 ? rhs : lhs; }, [](auto f, auto x, size_t w)->Tp{ return f == -1 ? x : f; } };
    st.set(0, n, (1U<<31) - 1);
    while(q--){
        int tp, s, t, x;
        std::cin >> tp;
        if(tp == 0){
            std::cin >> s >> t >> x;
            st.set(s, t+1, x);
        }else{
            std::cin >> s >> t;
            std::cout << st.get(s, t+1) << std::endl;
        }
    }
    return 0;
}



Measured memory_bytes: 7780