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;

struct SegmentTree {
  struct Node {
    int node, lazy;
    Node() {}
    Node(int node, int lazy) : node(node), lazy(lazy) {}

    Node operator*(const Node &r) const {
      return Node(min(node, r.node), -1);
    }
  };

  Node e = Node(INT_MAX, -1);
  size_t n;
  vector<Node> seg;

  SegmentTree(size_t size) : n(1 << (32 - __builtin_clz(size - 1))), seg(2 * n - 1, e) {}

  void lazy_evaluate(int k) {
    if (seg[k].lazy != -1) {
      seg[k].node = seg[k].lazy;
      if (k < n - 1) {
        seg[2 * k + 1].lazy = seg[k].lazy;
        seg[2 * k + 2].lazy = seg[k].lazy;
      }
      seg[k].lazy = -1;
    }
  }

  void update_node(int k) {
    seg[k] = seg[2 * k + 1] * seg[2 * k + 2];
  }

  void update(int l, int r, int x, int k, int a, int b) {
    lazy_evaluate(k);

    if (r <= a || b <= l) return;
    if (l <= a && b <= r) {
      seg[k].lazy = x;
      lazy_evaluate(k);
      return;
    }

    update(l, r, x, 2 * k + 1, a, (a + b) / 2);
    update(l, r, x, 2 * k + 2, (a + b) / 2, b);
    update_node(k);
  }

  Node query(int l, int r, int k, int a, int b) {
    lazy_evaluate(k);
    if (r <= a || b <= l) return e;
    if (l <= a && b <= r) return seg[k];

    return query(l, r, 2 * k + 1, a, (a + b) / 2) * query(l, r, 2 * k + 2, (a + b) / 2, b);
  }

  void update(int l, int r, int x) {
    update(l, r, x, 0, 0, n);
  }

  int query(int l, int r) {
    return query(l, r, 0, 0, n).node;
  }

  void debug(string s, int l, int r, int k) {
    cerr << s << "[" << l << ", " << r << ") " << k << endl;
  }
};

int main() {
  int n, q;
  cin >> n >> q;

  SegmentTree seg(n);

  while (q--) {
    int c;
    cin >> c;

    if (c) {
      int l, r;
      cin >> l >> r;
      cout << seg.query(l, r + 1) << endl;
    } else {
      int l, r, x;
      cin >> l >> r >> x;
      seg.update(l, r + 1, x);
    }
  }
}