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;

typedef long long ll;
const int MAX_N = (1<<18);

// 遅延評価セグメント木
struct RUP {
	int n;
	// dat:区間の最小値を管理する, laz:区間の値を管理する
	vector<int> dat, laz;
	const int def = INT_MAX;
	RUP() {}
	RUP(int n_){init(n_); }

	// 初期化
	void init(int n_) {
		n = 1;
		while(n < n_) n*=2;
		dat.clear();
		dat.resize(2*n-1,def);
		laz.clear();
		laz.resize(2*n-1,-1);
	}

	// 遅延を伝搬する
	inline void eval(int len, int k) {
		if(laz[k]<0) return;
		if (k * 2 + 1 < n * 2 - 1) {
			laz[k*2+1]=laz[k];
			laz[k*2+2]=laz[k];
		}
		dat[k] = laz[k];
		laz[k] = -1;
	}

	// [a,b)を x に変更する
	int update(int a, int b, int x, int k, int l, int r) {
		// 遅延評価
		eval(r-1,k);
		if(r<=a || b<=l) return dat[k];
		if(a<=l && r<=b) return laz[k] = x;
		eval(r-1,k);
		dat[k] = min(update(a,b,x,k*2+1,l,(l+r)/2), update(a,b,x,k*2+2,(l+r)/2,r));
		return dat[k];
	}

	// [a,b)の最小値を求める
	int query(int a, int b, int k, int l, int r) {
		eval(r-1,k);
		if(r<=a || b<=l) return def;
		if(a<=l && r<=b) return dat[k];

		int vl = query(a,b,k*2+1,l,(l+r)/2);
		int vr = query(a,b,k*2+2,(l+r)/2,r);
		return min(vl,vr);
	}

	void update(int a, int b, int x) {
		update(a,b,x,0,0,n);
	}

	int query(int a, int b) {
		return query(a,b,0,0,n);
	}


};

int main() {
	int n, q;
	cin >> n >> q;
	RUP rup(n);
	for (int i = 0; i < q; i++) {
		int f;
		cin >> f;
		if (!f) {
			int s, t, x;
			cin >> s >> t >> x;
			rup.update(s,t+1,x);
		}
		else {
			int s, t;
			cin >> s >> t;
			cout << rup.query(s,t+1) << endl;
		}
	}

}