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>
using std::cin;
using std::cout;
using std::endl;
using ll = long long;

template <typename T>
T min(T a, T b){
  return (a < b) ? a : b;
}

template <typename T>
class SegTree{
  static const int MAXN = 100010;
  T INF;
  int n;
  T A[MAXN*4];
  T lazy[MAXN*4];
  public:
  SegTree(int size, T INF): INF(INF){
    n = 1;
    while(n < size){
      n *= 2;
    }
    // n *= 2;
    for(int i = 0; i < MAXN*4; i++) A[i] = INF;
    for(int i = 0; i < MAXN*4; i++) lazy[i] = INF;
  }

  T query(int a, int b){
    return _query(a, b, 0, 0, n);
  }

  T _query(int a, int b, int k, int l, int r){
    lazy_evaluate(k);
    if(a >= r || b <= l){
      return INF;
    }
    if(l >= a && r <= b){
      return A[k];
    }
    lazy_evaluate(k);
    T v1 = _query(a, b, 2*k + 1, l, (l+r)/2);
    T v2 = _query(a, b, 2*k + 2, (l+r)/2, r);
    return min(v1, v2);
  }

  void update(int a, int b, T v){
    _update(a, b, 0, 0, n, v);
  }

  T _update(int a, int b, int k, int l, int r, T v){
    lazy_evaluate(k);
    if(a >= r || b <= l){
      return A[k];
    }
    if(l >= a && r <= b){
      lazy[k] = v;
      lazy_evaluate(k);
      return A[k];
    }
    T v1 = _update(a, b, 2*k + 1, l, (l+r)/2, v);
    T v2 = _update(a, b, 2*k + 2, (l+r)/2, r, v);
    return A[k] = min(v1, v2);
  }

  void lazy_evaluate(int k){
    if(lazy[k] == INF) return;
    A[k] = lazy[k];
    if(k < n-1){
      lazy[2*k+1] = lazy[k];
      lazy[2*k+2] = lazy[k];
    }
    lazy[k] = INF;
  }
};

int main(void){
  int n, q; cin >> n >> q;
  SegTree<int> rmq(n, 0x7FFFFFFF);
  for(int loop = 0; loop < q; loop++){
    int com;
    cin >> com;
    if(com == 0){
      int l, r, v; cin >> l >> r >> v;
      rmq.update(l, r+1, v);
    }else{
      int x, y; cin >> x >> y;
      cout << rmq.query(x, y+1) << endl;
      // cout << rmq._query(x, y+1, 0, 0, n) << endl;
    }
  }
}