#include <bits/stdc++.h>
using namespace std;
using Int = int_fast64_t;

template <class value_monoid, class operator_monoid> class lazy_segment_tree{
public:
	typedef typename operator_monoid::underlying_type underlying_type;
	typedef typename value_monoid::value_type value_type;
	size_t n;
	vector<value_type> data;
	vector<underlying_type> lazy;
	value_type e_val = value_monoid::unit();
	underlying_type e_ope = operator_monoid::unit();
	lazy_segment_tree(size_t size){
		n = 1;
		while(n < size) n <<= 1;
		data.resize(2*n, e_val);
		lazy.resize(2*n, e_ope);
	}
	lazy_segment_tree(vector<value_type> _data){
		size_t size = _data.size();
		n = 1;
		while(n < size) n <<= 1;
		data.resize(2*n, e_val);
		for(size_t i=0; i<size; ++i) data[n+i] = data[i];
		lazy.resize(2*n, e_ope);
	}
	void propagate(size_t k, size_t l, size_t r){
		if(lazy[k] != operator_monoid::unit()){
			data[k] = operator_monoid::operate(lazy[k], data[k]);
			if(r-l > 1){
				lazy[2*k] = operator_monoid::compose(lazy[k], lazy[2*k]);
				lazy[2*k+1] = operator_monoid::compose(lazy[k], lazy[2*k+1]);
			}
			lazy[k] = operator_monoid::unit();
		}
	}
	void range_operate(underlying_type f, size_t a, size_t b, size_t k, size_t l, size_t r){
		propagate(k, l, r);
		if(r <= a || b <= l) return;
		if(a <= l && r <= b){
			lazy[k] = operator_monoid::compose(f, lazy[k]);
			propagate(k, l, r);
		}else{
			range_operate(f, a, b, 2*k, l, (l+r+1)/2);
			range_operate(f, a, b, 2*k+1, (l+r+1)/2, r);
			data[k] = value_monoid::product(data[2*k], data[2*k+1]);
		}
	}
	void range_operate(underlying_type f, size_t a, size_t b){
		range_operate(f, a, b, 1, 0, n);
	}
	value_type range_get(size_t a, size_t b, size_t k=1, size_t l=0, size_t r=SIZE_MAX){
		if(r == SIZE_MAX) r = n;
		if(r <= a || b <= l) return value_monoid::unit();
		propagate(k, l, r);
		if(a <= l && r <= b) return data[k];
		value_type lres = range_get(a, b, 2*k, l, (l+r+1)/2);
		value_type rres = range_get(a, b, 2*k+1, (l+r+1)/2, r);
		return value_monoid::product(lres, rres);
	}
	value_type operator[](size_t k){
		return data[k+n];
	}
};
struct assign_operator_monoid{
	using underlying_type = pair<bool, Int>;
	using value_type = Int;
	static underlying_type unit(){
		return pair<bool, int>(true, 0);
	}
	static underlying_type compose(underlying_type l, underlying_type r){
		if(l == unit()) return r;
		return l;
	}
	static value_type operate(underlying_type f, value_type x){
		return f.first ? x : f.second;
	}
};
struct add_operator_monoid{
	using underlying_type = Int;
	using value_type = Int;
	static underlying_type unit(){
		return 0;
	}
	static underlying_type compose(underlying_type l, underlying_type r){
		return l + r;
	}
	static value_type operate(underlying_type f, value_type x){
		return f + x;
	}
};
struct plus_monoid{
	using value_type = Int;
	static value_type unit(){
		return 0;
	}
	static value_type product(value_type l, value_type r){
		return l + r;
	}
};
struct min_monoid{
	using value_type = Int;
	static value_type unit(){
		return (1ll<<31)-1;
	}
	static value_type product(value_type l, value_type r){
		return min(l, r);
	}
};


int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	Int n, q; cin >> n >> q;
	lazy_segment_tree<min_monoid, assign_operator_monoid> lst(n);
	while(q--){
		Int p; cin >> p;
		if(p == 0){
			Int s, t, x; cin >> s >> t >> x;
			lst.range_operate(pair<bool, Int>(false, x), s, t+1);
		}else{
			Int s, t; cin >> s >> t;
			cout << lst.range_get(s, t+1) << "\n";
		}
//		for(size_t i=0; i<lst.lazy.size(); ++i)
//			cout << i << " " << lst.lazy[i].second << " " << lst.data[i] << "\n";
	}
}


Measured memory_bytes: 8880