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>
using namespace std;

typedef long long ll;

struct LazySegment
{
	vector<ll> node;
	vector<ll> lazy;
	vector<bool> lazyFlag;
	ll n;


	ll init = (1LL << 31) - 1;

	LazySegment(const vector<ll>& vec)
	{
		int sz = vec.size();

		n = 1;
		while(n < sz) n <<= 1;

		node.resize(2 * n - 1);
		lazy.resize(2 * n - 1,init);
		lazyFlag.resize(2 * n - 1,false);

		for(int i = 0;i < sz;i++)
		{
			node[n - 1 + i] = vec[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[k];
				lazy[2 * k + 2] = lazy[k];
				lazyFlag[2 * k + 1] = true;
				lazyFlag[2 * k + 2] = true;
			}

			lazy[k] = 0;
			lazyFlag[k] = false;
		}
	}

	void add_inter(int a,int b,ll 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
		{
			add_inter(a,b,x,2 * k + 1,l,(l + r) / 2);
			add_inter(a,b,x,2 * k + 2,(l + r) / 2,r);
			node[k] = min(node[2 * k + 1] , node[2* k + 2]);
		}
	}

	ll get_inter(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 init;

		if(a <= l && r <= b) return node[k];

		ll lv = get_inter(a,b,k * 2 + 1,l , (l + r) / 2);
		ll rv = get_inter(a,b,k * 2 + 2,(l + r) / 2 , r);

		return min(lv , rv);
	}
};

signed main()
{
	int n;
	int q;
	cin >> n >> q;
	LazySegment seg(vector<ll>(n,(1LL << 31) - 1));

	for(int i = 0;i < q;i++)
	{
		int t;
		cin >> t;
		if(t == 0)
		{
			int a,b;
			ll x;
			cin >> a >> b >> x;
			seg.add_inter(a,b + 1,x);
		}
		else
		{
			int a,b;
			cin >> a >> b;

			cout << seg.get_inter(a,b + 1) << endl;
		}
	}

	return 0;
}