Problem: Write a program which manipulates a sequence A = {a0, a1, . . . , an−1} with the following operations:

* update(s, t, x): change as, as+1, ..., at to x.
* find(s, t): report the minimum element in as, as+1, ..., at.



Note that the initial values of ai (i = 0, 1, . . . , n−1) are 231-1.

Constraints

* 1 ≤ n ≤ 100000
* 1 ≤ q ≤ 100000
* 0 ≤ s ≤ t < n
* 0 ≤ x < 231−1

Input


n q
query1
query2
:
queryq


In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, ith query queryi is given in the following format:


0 s t x


or


1 s t


The first digit represents the type of the query. '0' denotes update(s, t, x) and '1' denotes find(s, t).

Output

For each find operation, print the minimum value.

Examples

Input

3 5
0 0 1 1
0 1 2 3
0 2 2 2
1 0 2
1 1 2


Output

1
2


Input

1 3
1 0 0
0 0 0 5
1 0 0


Output

2147483647
5

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define all(V) (V).begin(),(V).end()
#define umap unordered_map
#define uset unordered_set
#define br cout<<"\n";

const int MAXN=1e5+10, MOD=1e9+7;
int n,m;
int arr[MAXN];
int t[5*MAXN],lazy[5*MAXN];

int doit(int a,int b){
	return min(a,b);
}

void build(int start,int end,int index=1){
	if(start==end){
		t[index]=INT_MAX;
		return ;
	}
	int mid = start+end >> 1;
	build(start,mid,index << 1);
	build(mid+1,end,index<<1|1);
	t[index] = doit(t[index<<1], t[index<<1|1]);
}

void propagate(int start,int end,int index){
	t[index] = lazy[index];
	// bcz leaf not hv childs
	if(start!=end){
		lazy[index<<1] = lazy[index];
		lazy[index<<1|1] = lazy[index];
	}
	lazy[index]=-1;
}

int Query(int start,int end,int l,int r,int index=1){

	if(lazy[index]!=-1){
		propagate(start,end,index);
	}
	// out range
	if(r<start or end<l){
		return INT_MAX;
	}
	// in Raange
	if( l<=start and end<=r){
		return t[index];
	}
	int mid = start+end >>1;
	return doit(Query(start,mid,l,r,index<<1), Query(mid+1,end,l,r,index<<1|1));
}

void pUpdate(int start,int end,int point,int val,int index=1){
	if(start==end){
		t[index]=val;
		return ;
	}
	int mid = start+end>>1;
	if(point <= mid){
		pUpdate(start,mid,point,val,index<<1);
	}
	else{
		pUpdate(mid+1,end,point,val,index<<1|1);
	}
	t[index] = doit(t[index <<  1] , t[index << 1 | 1]);
}


void rangeUpdate(int start,int end,int l,int r,int val,int index){
	if(lazy[index]!= -1){
		propagate(start,end,index);
	}
	if(l>end or r<start){
		return;
	}
	// in range
	if(l<=start and end<=r){
		lazy[index]=val;
		propagate(start,end,index);
		return;
	}
	int mid = start+end>>1;
	rangeUpdate(start,mid,l,r,val,index<<1);
	rangeUpdate(mid+1,end,l,r,val,index<<1|1);
	t[index] = doit(t[index<<1],t[index<<1|1]);
}




signed main()
{
// 	#ifndef ONLINE_JUDGE
// 		freopen("./input.txt","r",stdin);
// 		freopen("./output.txt","w",stdout);
// 	#endif
	ios::sync_with_stdio(false); cin.tie(nullptr);
	cin>>n>>m;
	memset(lazy,-1,sizeof lazy);
	build(0,n-1);
	for(int i=1; i<=m; i++){
		int q; cin>>q;
		if(q==1){
			int s,t; cin>>s>>t;
			cout<<Query(0,n-1,s,t,1); br;
		}
		else{
			int s,t,x; cin>>s>>t>>x;
			rangeUpdate(0,n-1,s,t,x,1);
		}
	}	

}