Problem:
Range Minimum Query (RMQ)

Write a program which manipulates a sequence A = {a0, a1, . . . , an-1} with the following operations:

find(s, t): report the minimum element in as, as+1, . . . ,at.

update(i, x): change ai to x.

Note that the initial values of ai (i = 0, 1, . . . , n−1) are 231-1.

Input

n q
com0 x0 y0
com1 x1 y1
...
comq−1 xq−1 yq−1

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, q queries are given where com represents the type of queries. '0' denotes update(xi, yi) and '1' denotes find(xi, yi).

Output

For each find operation, print the minimum element.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

If comi is 0, then 0 ≤ xi < n, 0 ≤ yi < 231-1.

If comi is 1, then 0 ≤ xi < n, 0 ≤ yi < n.

Sample Input 1

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

Sample Output 1

1
2

Sample Input 2

1 3
1 0 0
0 0 5
1 0 0

Sample Output 2

2147483647
5

Solution in Scala (judge verdict: Memory Limit Exceeded)

trait Monoid[T] {
  def empty: T
  def append(a: T,B: T): T
}

sealed trait Segtree[M] {
  def value: M
  def size: Int
  def rangeQuery(a: Int, b: Int): M
  def updated(k: Int, x: M): Segtree[M]
}

case class Leaf[M : Monoid](value: M) extends Segtree[M] {
  override val size = 1
  override def rangeQuery(a: Int, b: Int): M =
    if (a <= 0 && 1 <= b) value else implicitly[Monoid[M]].empty
  override def updated(k: Int, x: M) = Leaf(x)
}

case class Node[M](lch: Segtree[M], rch: Segtree[M])(implicit m: Monoid[M]) extends Segtree[M] {
  override lazy val value = m.append(lch.value, rch.value)
  override lazy val size = lch.size + rch.size
  override def rangeQuery(a: Int, b: Int): M =
    if (a <= 0 && size <= b) value
    else if (b <= 0 || size <= a) m.empty
    else {
      val lSize = lch.size
      val left = lch.rangeQuery(a, b)
      val right = rch.rangeQuery(a - lSize, b - lSize)
      m.append(left, right)
    }
  override def updated(k: Int, x: M): Segtree[M] =
    if (k < lch.size) Node(lch.updated(k, x), rch)
    else Node(lch, rch.updated(k - lch.size, x))
}

object Segtree {
  def build[M](n: Int)(implicit m: Monoid[M]): Segtree[M] =
    if (n <= 1) Leaf(m.empty)
    else Node(build(n / 2), build(n - n / 2))
}

object Main extends App {
  implicit object IntMonoid extends Monoid[Int] {
    def empty = Int.MaxValue
    def append(a: Int, b: Int) = a min b
  }

  val sc = new java.util.Scanner(System.in)
  val n, q = sc.nextInt
  Iterator.continually {
    try (Some(sc.nextInt, sc.nextInt, sc.nextInt)) catch {
      case util.control.NonFatal(t) => None
    }
  } .toStream
    .takeWhile(_.isDefined)
    .foldLeft(Segtree.build[Int](n)) { (rmq, in) =>
      in match {
        case Some((0, x, y)) => rmq.updated(x, y)
        case Some((_, x, y)) => {
          println(rmq.rangeQuery(x, y + 1))
          rmq
        }
        case None => rmq
      }
    }
}

//Main.main(null)