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<cstdio>
#include<vector>
#include<algorithm>
#include<utility>
#include<numeric>
#include<iostream>
#include<array>
#include<string>
#include<sstream>
#include<stack>
#include<queue>
#include<list>
#include<functional>
#define _USE_MATH_DEFINES

#include<math.h>
#include<map>

#define SENTINEL 1000000001

#define min(a,b) ((a)>(b)?(b):(a))
#define max(a,b) ((a)>(b)?(a):(b))

using namespace std;

typedef pair<int, int> pii;

#define NUM 2147483647

int N = 1;
int st[270000];

void init(int first_N) {
	while (N < first_N)N *= 2;
}

void update(int update_left, int update_right, int new_value, int node_id, int node_left, int node_right) {
	if (update_right < node_left || update_left > node_right)return;
	else if (update_left <= node_left && update_right >= node_right) {
		st[node_id] = new_value;
	}
	else {
		if (st[node_id] >= 0) {
			update(node_left, node_right, st[node_id], 2 * node_id + 1, node_left, (node_left + node_right) / 2);
			update(node_left, node_right, st[node_id], 2 * node_id + 2, (node_left + node_right) / 2 + 1, node_right);
			st[node_id] = -1;
		}
		update(update_left, update_right, new_value, 2 * node_id + 1, node_left, (node_left + node_right) / 2);
		update(update_left, update_right, new_value, 2 * node_id + 2, (node_left + node_right) / 2 + 1, node_right);
	}
}

int query(int search_left, int search_right, int node_id, int node_left, int node_right) {
	if (search_right < node_left || search_left > node_right) {
		return NUM;
	}
	else {
		if (st[node_id] != -1)return st[node_id];
		else {
			int left = query(search_left, search_right, 2 * node_id + 1, node_left, (node_left + node_right) / 2);
			int right = query(search_left, search_right, 2 * node_id + 2, (node_left + node_right) / 2 + 1, node_right);
			return min(left, right);
		}
	}
}

int main() {
	int first_N, Q;
	scanf("%d %d", &first_N, &Q);

	init(first_N);

	for (int i = 0; i <= 2 * N - 2; i++)st[i] = NUM;

	int command, left, right, value;

	for (int i = 0; i < Q; i++) {
		scanf("%d", &command);

		if (command == 0) {
			scanf("%d %d %d", &left, &right, &value);
			update(left, right, value, 0, 0, N - 1);
		}
		else {
			scanf("%d %d", &left, &right);
			printf("%d\n", query(left, right, 0, 0, N - 1));
		}
	}
}