#include <bits/stdc++.h>
using namespace std;

#define rep(i,x,y) for(int i=(x);i<(y);++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define show(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define show(x)
#endif

typedef long long int ll;
typedef pair<int,int> pii;
template<typename T> using vec=std::vector<T>;

const int inf=1<<30;
const long long int infll=1LL<<62;
const double eps=1e-9;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
    os << "[";
    for (const auto &v : vec) {
    	os << v << ",";
    }
    os << "]";
    return os;
}

template<class data_type> class dynamic_memory_allocation_segtree{
private:
    class node{
    public:
        data_type data;
        int64_t left,right;
        node *left_child,*right_child;
        node(const data_type &data_,const int64_t left_,const int64_t right_){
            data=data_;
            left=left_;
            right=right_;
            left_child=right_child=NULL;
        }
    };
    data_type id,initial_value;
    std::function<data_type(data_type,data_type)> fun;
    node root;

    data_type update(node *node_,const int64_t index,const data_type &new_value){
        if(node_->right-node_->left==1) return node_->data=new_value;
        const int64_t mid=(node_->left+node_->right)/2;
        data_type left_value=id,right_value=id;
        if(index<mid){
            if(node_->left_child==NULL) node_->left_child=new node(id,node_->left,mid);
            if(node_->right_child!=NULL) right_value=node_->right_child->data;
            left_value=update(node_->left_child,index,new_value);
        }else{
            if(node_->left_child!=NULL) left_value=node_->left_child->data;
            if(node_->right_child==NULL) node_->right_child=new node(id,mid,node_->right);
            right_value=update(node_->right_child,index,new_value);
        }
        return node_->data=fun(left_value,right_value);
    }

    data_type query(node* node_,const int64_t left,const int64_t right){
        if(left<=node_->left and node_->right<=right) return node_->data;
        if(node_->right<=left or right<=node_->left) return id;
        data_type left_value=id,right_value=id;
        if(node_->left_child!=NULL) left_value=fun(left_value,query(node_->left_child,left,right));
        if(node_->right_child!=NULL) right_value=fun(right_value,query(node_->right_child,left,right));
        return fun(left_value,right_value);
    }

public:
    dynamic_memory_allocation_segtree()=default;
    dynamic_memory_allocation_segtree(const int64_t left,const int64_t right,const std::function<data_type(data_type,data_type)> &fun_,const data_type &id_,const data_type &initial_value_):
    root(id_,left,right){ init(left,right,fun_,id_,initial_value_); }

    void init(const int64_t left,const int64_t right,const std::function<data_type(data_type,data_type)> &fun_,const data_type &id_,const data_type &initial_value_){
        root=node(id_,left,right);
        id=id_;
        fun=fun_;
        initial_value=initial_value_;
    }

    void update(int64_t index,const data_type &new_value){ update(&root,index,new_value); }
    data_type query(const int64_t left,const int64_t right){ return query(&root,left,right); }
};

void solve(){
    int n,q;
    cin >> n >> q;
    dynamic_memory_allocation_segtree<int> seg(0,infll,[](int x,int y){ return min(x,y); },numeric_limits<int>::max(),numeric_limits<int>::max());
    rep(i,0,q){
        int com,x,y;
        cin >> com >> x >> y;
        if(com==0) seg.update(x,y);
        else cout << seg.query(x,y+1) << endl;
    }
}

int main(){
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    cout.setf(ios::fixed);
    cout.precision(10);
    solve();
    return 0;
}

Measured memory_bytes: 8672