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;
using ll = long long;
const int INF = INT_MAX;

struct LazySegmentTree {
	private:
		int n;
		vector<int> node, lazy;
		vector<bool> lazyFlag;
	public:
		LazySegmentTree(vector<int> v) {
			int sz = (int)v.size();
			n = 1;
			while(n < sz) n *= 2;
			node.resize(2*n-1);
			lazy.resize(2*n-1, INF);
			lazyFlag.resize(2*n-1, false);

			for(int i=0;i<sz;i++) node[i+n-1] = v[i];
			for(int i=n-2;i>=0;i--) node[i] = min(node[2*i+1], node[2*i+2]);
		}

		void eval(int k, int l, int r) {
			if(lazyFlag[k]) {
				node[k] = lazy[k];
				// 最下層じゃないとき
				if(r - l > 1) {
					lazy[2*k+1] = lazy[2*k+2] = lazy[k];
					lazyFlag[2*k+1] = lazyFlag[2*k+2] = true;
				}
				lazyFlag[k] = false;
			}
		}

		void update(int a, int b, int x, int k = 0, int l = 0, int r = -1) {
			if(r < 0) r = n;
			eval(k, l, r);
			if(b <= l || r <= a) return;
			if(a <= l && r <= b) {
				lazy[k] = x;
				lazyFlag[k] = true;
				eval(k, l, r);
			} else {
				update(a, b, x, 2*k+1, l, (l+r) >> 1);
				update(a, b, x, 2*k+2, (l+r) >> 1, r);
				node[k] = min(node[2*k+1], node[2*k+2]);
			}
		}

		int find(int a, int b, int k = 0, int l = 0, int r = -1) {
			if(r < 0) r = n;
			eval(k, l, r);
			if(b <= l || r <= a) return INF;
			if(a <= l && r <= b) return node[k];
			int vl = find(a, b, 2*k+1, l, (l+r)>>1);
			int vr = find(a, b, 2*k+2, (l+r)>>1, r);
			return min(vl, vr);
		}
};

int main() {
	int n, q;
	cin >> n >> q;
	LazySegmentTree st(vector<int>(n, INF));
	for(int i=0;i<q;i++) {
		int query;
		cin >> query;
		if(query == 0) {
			int s, t, x;
			cin >> s >> t >> x;
			st.update(s, t+1, x);
		} else {
			int s, t;
			cin >> s >> t;
			cout << st.find(s, t+1) << endl;
		}
	}
	return 0;
}