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 <iostream>
#include <vector>
#include <climits>
using namespace std;

void Init();
void update(int index, int value, int searchLeft, int searchRight, int left, int right);
int find(int index, int searchLeft, int searchRight, int left, int right);
void lazy_propagate(int index);

const int INF = INT_MAX;

vector<int> tree;
vector<int> lazy;

int n, q;


int main() {

	cin >> n >> q;

	Init();

	for (int i = 0; i < q; i++) {

		int com, a, b, x;
		cin >> com;

		switch (com) {
		case 0:
			cin >> a >> b >> x;
			update(0, x, 0, n, a, b + 1);
			break;

		case 1:
			cin >> a >> b;
			cout << find(0, 0, n, a, b + 1) << endl;
			break;
		}

	}

	return 0;
}

void Init() {

	int _n = 1;
	while (_n < n)
		_n *= 2;
	n = _n;
	tree = vector<int>(2 * n - 1, INF);
	lazy = vector<int>(2 * n - 1, -1);

}

void lazy_propagate(int index) {


	if (lazy[index] == -1)
		return;

	tree[index] = lazy[index];

	if (index < n - 1) {
		lazy[index * 2 + 1] = lazy[index];
		lazy[index * 2 + 2] = lazy[index];
	}
	lazy[index] = -1;

}

void update(int index, int value, int searchLeft, int searchRight, int left, int right) {

	if (right <= searchLeft || searchRight <= left) {
		lazy_propagate(index);
	}
	else if (left <= searchLeft && searchRight <= right) {
		lazy[index] = value;
		lazy_propagate(index);
	}
	else {
		lazy_propagate(index);

		int mid = (searchLeft + searchRight) / 2;
		update(index * 2 + 1, value, searchLeft, mid, left, right);
		update(index * 2 + 2, value, mid, searchRight, left, right);

		tree[index] = min(tree[index * 2 + 1], tree[index * 2 + 2]);
	}


}

int find(int index, int searchLeft, int searchRight, int left, int right) {

	if (right <= searchLeft || searchRight <= left) {
		return INF;
	}
	else if (left <= searchLeft && searchRight <= right) {
		lazy_propagate(index);
		return tree[index];
	}
	else {
		lazy_propagate(index);
		int mid = (searchLeft + searchRight) / 2;
		int lValue = find(index * 2 + 1, searchLeft, mid, left, right);
		int rValue = find(index * 2 + 2, mid, searchRight, left, right);
		return min(lValue, rValue);
	}

}