// Slower C++ solution:
#include <cstdio>

#include <algorithm>

#include <climits>

using namespace std;



const int SIZE = 1 << 17; // 2^17 = 131072

template<typename T>

struct segtree {

    // ?????????????????????

    T node[2*SIZE], I;



    // ????????¬????????§??? (update, query ??? 2 ???????????????)

    T (*upd_f)(T, T), (*qry_f)(T, T);



    // ???????????¨?????????????????????????????¨?????? node ??????????????§?????????

    segtree(T (*op1)(T, T), T (*op2)(T, T), T X) {

        upd_f = op1;

        qry_f = op2;

        I = X;

        fill(node, node+2*SIZE, I);

    }



    // ??´??? idx ?????? val ????????? (upd_f ?????¨?????? update)

    void update(int idx, T val) {

        idx += SIZE - 1;

        node[idx] = upd_f(node[idx], val);

        while(idx > 0) {

            // ????????¨?????? qry_f ??????????????¨?????¨????????????

            idx = (idx - 1) / 2;

            node[idx] = qry_f(node[2*idx+1], node[2*idx+2]);

        }

    }



    // ???????????? [a, b) ?????????????????¨???????????????

    // (qry_f ?????¨????????????)

    T query(int a, int b, int l=0, int r=SIZE, int k=0) {

        if(b <= l || r <= a) return I;

        if(a <= l && r <= b) return node[k];

        int mid = (l + r) / 2;

        T vl = query(a, b, l, mid, 2*k+1);

        T vr = query(a, b, mid, r, 2*k+2);

        return qry_f(vl, vr);

    }

};



int upd(int a, int b) {return b;}

int fnd(int a, int b) {return min(a, b);}

int main() {

    segtree<int> seg(upd, fnd, INT_MAX);

    int N, Q; scanf("%d%d", &N, &Q);

    for(int i=0; i<Q; i++) {

        int c, x, y; scanf("%d%d%d", &c, &x, &y);

        if(c == 0) seg.update(x, y);

        else printf("%d\n", seg.query(x, y+1));

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.2358798215149802x):
#include <vector>

#include <functional>

#include <algorithm>

#include <iostream>

#include <climits>

using namespace std;



// 抽象 SegmentTree (0-indexed・一点更新・区間取得)

template <typename MonoidType, typename UpdateType>

struct SegmentTree {

    using UpdateFunc  = function< MonoidType(MonoidType, UpdateType) >;

    using CombineFunc = function< MonoidType(MonoidType, MonoidType) >;



    // node, identity element

    int n;

    vector<MonoidType> node;

    MonoidType E0;



    // update / combine function

    UpdateFunc  upd_f;

    CombineFunc cmb_f;



    void build(int m, vector<MonoidType> v = vector<MonoidType>()) {

        if(v != vector<MonoidType>()) m = v.size();

        n = 1; while(n < m) n *= 2;



        node = vector<MonoidType>(2*n-1, E0);

        if(v != vector<MonoidType>()) {

            for(int i=0; i<m; i++) {

                node[n-1+i] = v[i];

            }

            for(int i=n-2; i>=0; i--) {

                node[i] = cmb_f(node[2*i+1], node[2*i+2]);

            }

        }

    }



    // initialize

    SegmentTree() {}

    SegmentTree(int n_, MonoidType E0_,

                UpdateFunc upd_f_, CombineFunc cmb_f_,

                vector<MonoidType> v = vector<MonoidType>()) :

        E0(E0_), upd_f(upd_f_), cmb_f(cmb_f_) {

        build(n_, v);

    }



    // update k-th element (applied value: x)

    void update(int k, UpdateType x) {

        k += n - 1;

        node[k] = upd_f(node[k], x);

        while(k > 0) {

            k = (k - 1) / 2;

            node[k] = cmb_f(node[2*k+1], node[2*k+2]);

        }

    }



    // range query for [a, b)

    MonoidType query(int a, int b, int l=0, int r=-1, int k=0) {

        if(r < 0) r = n;

        if(r <= a or  b <= l) return E0;

        if(a <= l and r <= b) return node[k];

        int mid = (l + r) / 2;

        MonoidType vl = query(a, b, l, mid, 2*k+1);

        MonoidType vr = query(a, b, mid, r, 2*k+2);

        return cmb_f(vl, vr);

    }

};





// Range Minimum Query

// query 1: update

// query 2: range minimum

void DSL_2_A() {

    int N, Q; cin >> N >> Q;

    SegmentTree<int, int> seg(N, INT_MAX,

                              [](int a, int b) { return b; },

                              [](int a, int b) { return min(a, b); });



    int indexed = 0;

    for(int i=0; i<Q; i++) {

        int query_type; cin >> query_type;

        int x, y; cin >> x >> y;

        if(query_type == 0) {

            x -= indexed;

            seg.update(x, y);

        }

        if(query_type == 1) {

            x -= indexed, y -= indexed;

            y++;

            cout << seg.query(x, y) << endl;

        }

    }

}



int main() {

    DSL_2_A();

    return 0;

}