Problem:
RMQ and RUQ

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.

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.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

0 ≤ s ≤ t < n

0 ≤ x < 231−1

Sample Input 1

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

Sample Output 1

1
2

Sample Input 2

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

Sample Output 2

2147483647
5

Solution in C (judge verdict: Accepted)

// AOJ DSL_2_F Range Query - RMQ and RUQ
// 2019.3.27 bal4u

#include <stdio.h>
#include <stdlib.h>

#if 1
#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)
#else
#define gc() getchar()
#define pc(c) putchar(c)
#endif
int in()  // 非負整数の入力
{
	int n = 0, c = gc();
	do n = 10 * n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void out(int n)  // 非負整数の表示（出力）
{
	int i;
	char ob[20];

	if (!n) pc('0');
	else {
		i = 0; while (n) ob[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(ob[i]);
	}
	pc('\n');
}

#define MAX (1<<17) //segment tree のサイズ。この実装では2べきにする必要がある
#define MIN(a, b)  ((a)<=(b)?(a):(b))
#define INF  0x7fffffff
int segVal[2*MAX], segLazy[2*MAX];

void lazy(int k)
{
	if (segLazy[k] != -1) {
		segVal[k] = segLazy[k];
		if (k < MAX - 1) {
			segLazy[(k << 1) + 1] = segLazy[k];
			segLazy[(k << 1) + 2] = segLazy[k];
		}
		segLazy[k] = -1;
	}
}

void update(int a, int b, int x, int k, int l, int r)
{
	if (r <= a || b <= l) {
		lazy(k);
		return;
	}
	if (a <= l && r <= b) {
		segLazy[k] = x;
		lazy(k);
		return;
	}
	lazy(k);
	update(a, b, x, (k << 1) + 1, l, (l + r) >> 1);
	update(a, b, x, (k << 1) + 2, (l + r) >> 1, r);
	segVal[k] = MIN(segVal[(k << 1) + 1], segVal[(k << 1) + 2]);
}

int getMin(int a, int b, int k, int l, int r)
{
	int le, ri;

	if (r <= a || b <= l) return INF;
	if (a <= l && r <= b) {
		lazy(k);
		return segVal[k];
	}
	lazy(k);
	le = getMin(a, b, (k<<1)+1, l, (l+r) >> 1);
	ri = getMin(a, b, (k<<1)+2, (l+r) >> 1, r);
	return MIN(le, ri);
}

int main()
{
	int N, Q, cmd, s, t, x;

	N = in(), Q = in();
	update(0, N, INF, 0, 0, N);
	while (Q--) {
		cmd = in(), s = in(), t = in() + 1;
		if (cmd == 0) {
			x = in();
			update(s, t, x, 0, 0, N);
		}
		else out(getMin(s, t, 0, 0, N));
	}
	return 0;
}