output_description: For each find operation, print the minimum element.
input_description: 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).
attempt: import operator
  
  
  class SegmentTree:
      # http://tsutaj.hatenablog.com/entry/2017/03/29/204841
      def __init__(self, size, fn=operator.add, default=0):
          """
          :param int size:
          :param callable fn: 区間に適用する関数。引数を 2 つ取る。min, max, operator.xor など
          """
          # size 以上である最小の 2 冪
          n = 1
          while n < size:
              n *= 2
          self._size = n
          self._tree = [default for _ in range(self._size * 2 - 1)]
          self._fn = fn
  
      def set(self, i, value):
          """
          i 番目に value を設定
          :param int i:
          :param int value:
          :return:
          """
          x = self._size - 1 + i
          self._tree[x] = value
  
          while x > 0:
              x = (x - 1) // 2
              self._tree[x] = self._fn(self._tree[x * 2 + 1], self._tree[x * 2 + 2])
  
      def add(self, i, value):
          """
          もとの i 番目と value に fn を適用したものを i 番目に設定
          :param int i:
          :param int value:
          :return:
          """
          x = self._size - 1 + i
          self.set(i, self._fn(self._tree[x], value))
  
      def get(self, from_i, to_i, k=0, L=None, r=None):
          """
          [from_i, to_i) に fn を適用した結果を返す
          :param int from_i:
          :param int to_i:
          :param int k: self._tree[k] が、[L, r) に fn を適用した結果を持つ
          :param int L:
          :param int r:
          :return:
          """
          L = 0 if L is None else L
          r = self._size if r is None else r
  
          if from_i <= L and r <= to_i:
              return self._tree[k]
  
          if to_i <= L or r <= from_i:
              return None
  
          ret_L = self.get(from_i, to_i, k * 2 + 1, L, (L + r) // 2)
          ret_r = self.get(from_i, to_i, k * 2 + 2, (L + r) // 2, r)
          if ret_L is None:
              return ret_r
          if ret_r is None:
              return ret_L
          return self._fn(ret_L, ret_r)
  
      def __len__(self):
          return self._size
  
  
  N, Q = list(map(int, input().split()))
  com, X, Y = zip(*[input().split() for _ in range(Q)])
  X = list(map(int, X))
  Y = list(map(int, Y))
  
  if __name__ == "__main__":
      st = SegmentTree(size=N + 1, fn=min, default=2**31 - 1)
      for c, x, y in zip(com, X, Y):
          if c == "0":
              st.set(x, y)
          if c == "1":
              print(st.get(x, y + 1))
  
problem_description: 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.
samples: [{"input": "3 5\n    0 0 1\n    0 1 2\n    0 2 3\n    1 0 2\n    1 1 2", "output": "1\n    2"}, {"input": "1 3\n    1 0 0\n    0 0 5\n    1 0 0", "output": "2147483647\n    5"}]