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;
#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(...) _overload(__VA_ARGS__, repi, _rep)(__VA_ARGS__)
#define _rev(i, n) revi(i, n, 0)
#define revi(i, a, b) for(int i = (int)(a - 1); i >= (int)(b); i--)
#define rev(...) _overload(__VA_ARGS__, revi, _rev)(__VA_ARGS__)
#define each(i, n) for(auto&& i: n)
int INF = 2147483647, MOD = 1e9 + 7;
double EPS = 1e-15, PI = acos(-1);
int dx[] = {0, 0, 1, 0, -1, -1, 1, 1, -1}, dy[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
struct SegmentTree{
    int n;
    vector<int> t1, t2;
    SegmentTree(int size){
        n = 2;
        while(n < size) n *= 2;
        t1.resize(2 * n - 1, INF);
        t2.resize(2 * n - 1, -1);
    }
    void check(int k){
        if(t2[k] < 0) return;
        if(k * 2 + 1 < n * 2 - 1){
            t2[k * 2 + 1] = t2[k];
            t2[k * 2 + 2] = t2[k];
        }
        t1[k] = t2[k];
        t2[k] = -1;
    }
    int update(int a, int b, int x, int k = 0, int l = 0, int r = -1){
        if(r < 0) r = n;
        check(k);
        if(r <= a || b <= l) return t1[k];
        if(a <= l && r <= b) return t2[k] = x;
        check(k);
        t1[k] = min(
            update(a, b, x, k * 2 + 1, l, (l + r) / 2),
            update(a, b, x, k * 2 + 2, (l + r) / 2, r)
        );
        return t1[k];
    }
    int query(int a, int b, int k = 0, int l = 0, int r = -1){
        if(r < 0) r = n;
        check(k);
        if(r <= a || b <= l) return INF;
        if(a <= l && r <= b) return t1[k];
        return min(
            query(a, b, k * 2 + 1, l, (l + r) / 2),
            query(a, b, k * 2 + 2, (l + r) / 2, r)
        );
    }
};
// main
signed main() {
    int n, q, res = 0;
    cin>>n>>q;
    SegmentTree t(n);
    int a, l, r, x;
    rep(i, q){
        cin>>a>>l>>r;
        if(!a) cin>>x, t.update(l, r + 1, x);
        else cout<<t.query(l, r + 1)<<endl;
    }
}