# Original solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 5
0 0 1
0 1 2
0 2 3
1 0 2
1 1 2

output:
1
2
"""

import math
import sys


class SegmentTree(object):
    __slots__ = ('dat', 'tree_range')

    def __init__(self, n):
        """
        Init a SegmentTree with update and find for range minimum queries.
        """
        self.tree_range = pow(2, math.ceil(math.log2(n)))
        self.dat = [float('inf')] * (2 * self.tree_range - 1)

    # let A[k]=a
    def update(self, k, a):
        k += self.tree_range - 1
        self.dat[k] = a
        while k > 0:
            k = (k - 1) // 2
            self.dat[k] = min(self.dat[k * 2 + 1], self.dat[k * 2 + 2])

    # get min(A[s] A[s+1] ... A[t])
    def find(self, s, t, k=0, left=0, right=float('inf')):
        if right <= s or t <= left:
            return float('inf')
        elif s <= left <= right <= t:
            return self.dat[k]
        else:
            vl = self.find(s, t, k * 2 + 1, left, (left + right) // 2)
            vr = self.find(s, t, k * 2 + 2, (left + right) // 2, right)
            return min(vl, vr)


def cmd_exec(cmd_list, n_num):
    case = SegmentTree(n_num)
    end = pow(2, math.ceil(math.log2(n_num)))
    init_max = pow(2, 31) - 1

    for query in cmd_list:
        cmd, ele_1, ele_2 = map(int, query)
        if cmd == 0:
            case.update(ele_1, ele_2)
        elif cmd == 1:
            assert ele_1 <= ele_2
            res = case.find(s=ele_1, t=ele_2 + 1, right=end)
            print(res) if not math.isinf(res) else print(init_max)

    return None


def solve():
    _input = sys.stdin.readlines()
    n_num, q_num = map(int, _input[0].split())
    q_list = map(lambda x: x.split(), _input[1:])

    cmd_exec(q_list, n_num)
    return None


if __name__ == '__main__':
    solve()


# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 5
0 0 1
0 1 2
0 2 3
1 0 2
1 1 2

output:
1
2
"""

import math
import sys

INIT_MAX = pow(2, 31) - 1


class SegmentTree(object):
    __slots__ = ('dat', 'tree_range')

    def __init__(self, n):
        """
        Init a SegmentTree with update and find for range minimum queries.
        """
        self.tree_range = pow(2, math.ceil(math.log2(n)))
        self.dat = [INIT_MAX] * (2 * self.tree_range - 1)

    # let A[k]=a
    def update(self, k, a):
        k += self.tree_range - 1
        self.dat[k] = a
        while k > 0:
            k = (k - 1) // 2
            self.dat[k] = min(self.dat[k * 2 + 1], self.dat[k * 2 + 2])

    # get min(A[s] A[s+1] ... A[t])
    def find(self, s, t, k=0, left=0, right=float('inf')):
        if right <= s or t <= left:
            return INIT_MAX
        elif s <= left <= right <= t:
            return self.dat[k]
        else:
            vl = self.find(s, t, k * 2 + 1, left, (left + right) // 2)
            vr = self.find(s, t, k * 2 + 2, (left + right) // 2, right)
            return min(vl, vr)


def cmd_exec(cmd_list, n_num):
    case = SegmentTree(n_num)
    end = pow(2, math.ceil(math.log2(n_num)))

    for query in cmd_list:
        cmd, ele_1, ele_2 = list(map(int, query))
        if cmd == 0:
            case.update(ele_1, ele_2)
        elif cmd == 1:
            assert ele_1 <= ele_2
            res = case.find(s=ele_1, t=ele_2 + 1, right=end)
            print(res)

    return None


def solve():
    _input = sys.stdin.readlines()
    n_num, q_num = list(map(int, _input[0].split()))
    q_list = [x.split() for x in _input[1:]]

    cmd_exec(q_list, n_num)
    return None


if __name__ == '__main__':
    solve()