#include <stdio.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=((1<<30)-1)*2+1;
template <class T> struct BIT_sum_single_add{
    vector<T>arr;
public:
    void init(const vector<T> &a){
        arr.resize(a.size()+1);
        for(int i=1;i<arr.size();i++)arr[i]=a[i-1];
        for(int i=1;i<arr.size();i++)if(i+(i&-i)<arr.size())arr[i+(i&-i)]+=arr[i];
        return ;
    }
    void set(int n,int size){
        arr.resize(size+1);
        for(int i=1;i<arr.size();i++)arr[i]=n;
        for(int i=1;i<arr.size();i++)if(i+(i&-i)<arr.size())arr[i+(i&-i)]+=arr[i];
        return ;
    }
    T sum(int pos){
        T temp=0;
        pos++;
        while(pos>0){
            temp+=arr[pos];
            pos-=pos&-pos;
        }
        return temp;
    }
    /*void push(T a){
        arr.push_back(a);
        arr[(int)arr.size()-1]+=(sum((int)arr.size()-3)-sum((int)arr.size()));
        return ;
    }*/
    void add(T a,int pos){
        pos++;
        while(pos<arr.size()){
            arr[pos]+=a;
            pos+=pos&-pos;
        }
        return;
    }
private:
};
template <class T> struct BIT_2D_max_single_add{
public:
    void init(){
        
    }
    void add(int n,int x,int y){
        
    }
    /*T sum(){
     
     }*/
private:
};
template <class T>struct BIT_2D_sum_single_add{
public:
    void init(){
        
    }
    void add(int n,int x,int y){
        
    }
    /*T sum(){
        
    }*/
private:
};
template <class T>struct BIT_sum_multi_add{
    vector<T>arr;
public:
    void init(const vector<T> a){
        arr.resize(a.size()+1);
        for(int i=1;i<arr.size();i++)arr[i]=a[i-1];
        for(int i=1;i<arr.size();i++)if(i+(i&-i)<arr.size())arr[i+(i&-i)]+=arr[i];
        return ;
    }
private:
};
template <class T> struct BIT_max_single{
    vector<T>arr;
public:
    void set(int n,int size){
        arr.resize(size+1);
        for(int i=1;i<arr.size();i++)arr[i]=n;
        return ;
    }
    void init(const vector<T> &a){
        arr.resize(a.size()+1);
        for(int i=1;i<arr.size();i++)arr[i]=a[i-1];
        for(int i=1;i<arr.size();i++)if(i+(i&-i)<arr.size())arr[i+(i&-i)]=max(arr[i],arr[i+(i&-i)]);
        return ;
    }
    void update(T a,int pos){
        pos++;
        while(pos<arr.size()){
            arr[pos]=max(arr[pos],a);
            pos+=pos&-pos;
        }
        return ;
    }
    /*void add(T a,int pos){
        pos++;
        while(pos<arr.size()){
            arr[pos]+=a;
            pos+=pos&-pos;
        }
        return;
    }*/
    T sum(int pos){
        pos++;
        T temp=arr[pos];
        pos-=pos&-pos;
        while(pos>0){
            temp=max(temp,arr[pos]);
            pos-=pos&-pos;
        }
        return temp;
    }
private:
};
template <class T> struct BIT_min_single{
    vector<T>arr;
public:
    void init(const vector<T> &a){
        arr.resize(a.size()+1);
        for(int i=1;i<arr.size();i++)arr[i]=a[i-1];
        for(int i=1;i<arr.size();i++)if(i+(i&-i)<arr.size())arr[i+(i&-i)]=min(arr[i],arr[i+(i&-i)]);
        return ;
    }
    void set(int n,int size){
        arr.resize(size+1);
        for(int i=1;i<arr.size();i++)arr[i]=n;
        return ;
    }
    void update(T a,int pos){
        pos++;
        while(pos<arr.size()){
            arr[pos]=min(arr[pos],a);
            pos+=pos&-pos;
        }
        return ;
    }
    /*void add(T a,int pos){
     pos++;
     while(pos<arr.size()){
     arr[pos]+=a;
     pos+=pos&-pos;
     }
     return;
     }*/
    T sum(int pos){
        pos++;
        T temp=arr[pos];
        pos-=pos&-pos;
        while(pos>0){
            temp=min(temp,arr[pos]);
            pos-=pos&-pos;
        }
        return temp;
    }
private:
};
template <class T> struct segment_tree_max_single_add{
    vector<T>arr;
public:
    void init(const vector<T> &a){
        initialize(a,0,0,a.size()-1);
        return ;
    }
    void set(T n,int size){
        arr.resize(2*size-1);
        fill(arr.begin(),arr.end(),n);
        return ;
    }
    void add(T n,int L,int R){
        add_val(n,0,0,arr.size()-1,L,R);
        return ;
    }
    T find(int L,int R){
        return find_val(0,0,arr.size()-1,L,R);
    }
private:
    void initialize(const vector<T> &a,int now,int l,int r){
        
    }
    void add_val(T n,int now,int l,int r,int L,int R){
        if(L>r||l>R)return ;
        
        return ;
    }
    T find_val(int now,int l,int r,int L,int R){
        T temp;
        return temp;
    }
};
template <class T> struct segment_tree_max_single_update{
    vector<T>arr;
public:
    void init(const vector<T> &a){
        initialize(a,0,0,a.size()-1);
        return ;
    }
    void set(T n,int size){
        arr.resize(2*size-1);
        fill(arr.begin(),arr.end(),n);
        return ;
    }
    void add(T n,int L,int R){
        add_val(n,0,0,arr.size()-1,L,R);
        return ;
    }
    T find(int L,int R){
        return find_val(0,0,arr.size()-1,L,R);
    }
private:
    void initialize(const vector<T> &a,int now,int l,int r){
        
    }
    void add_val(T n,int now,int l,int r,int L,int R){
        if(L>r||l>R)return ;
        
        return ;
    }
    T find_val(int now,int l,int r,int L,int R){
        T temp;
        return temp;
    }
};
template <class T> struct segment_tree_min_single_update{
    vector<T>arr;
    int size;
public:
    void init(const vector<T> &a){
        size=a.size();
        arr.resize(size*4);
        initialize(a,0,0,size-1);
        return ;
    }
    void set(T n,int SIZE){
        arr.resize(4*SIZE);
        size=SIZE;
        for(int i=0;i<arr.size();i++)arr[i]=n;
        return ;
    }
    void update(T n,int pos){
        update_val(n,0,0,size-1,pos);
        return ;
    }
    T find(int L,int R){
        return find_val(0,0,size-1,L,R);
    }
private:
    void initialize(const vector<T> &a,int now,int l,int r){
        if(l==r)arr[now]=a[l];
        else{
            int mid=(l+r)/2;
            initialize(a,now*2+1,l,mid);
            initialize(a,now*2+2,mid+1,r);
            arr[now]=min(arr[now*2+1],arr[now*2+2]);
        }
        return ;
    }
    void update_val(T n,int now,int l,int r,int pos){
        if(l>pos||r<pos)return ;
        if(l==r){
            arr[now]=n;
            return ;
        }
        int mid=(l+r)/2;
        update_val(n,now*2+1,l,mid,pos);
        update_val(n,now*2+2,mid+1,r,pos);
        arr[now]=min(arr[now*2+1],arr[now*2+2]);
        return ;
    }
    T find_val(int now,int l,int r,int L,int R){
        if(L>r||l>R)return INF;
        if(l>=L&&R>=r)return arr[now];
        int mid=(l+r)/2;
        return min(find_val(now*2+1,l,mid,L,R),find_val(now*2+2,mid+1,r,L,R));
    }
};
template <class T> struct segment_tree_min_multi_update{
    struct node{
        T val;
        T lazytag;
    };
    vector<node> arr;
    int size;
public:
    void init(const vector<T> &a){
        size=a.size();
        arr.resize(2*size-1);
        initialize(a,0,0,size-1);
        return ;
    }
    void set(T n,int SIZE){
        arr.resize(2*SIZE-1);
        size=SIZE;
        arr[0].val=n;
        arr[0].lazytag=n;
        for(int i=1;i<arr.size();i++)arr[i].lazytag=0;
        return ;
    }
    void update(T n,int L,int R){
        update_val(n,0,0,size-1,L,R);
        return ;
    }
    T find(int L,int R){
        return find_val(0,0,size-1,L,R);
    }
private:
    void initialize(const vector<T> &a,int now,int l,int r){
        if(l==r)arr[now]=a[l];
        else {
            int mid=(l+r)/2;
            initialize(a,now*2+1,l,mid);
            initialize(a,now*2+2,mid+1,r);
            arr[now]=min(arr[now*2+1],arr[now*2+2]);
        }
        return ;
    }
    void update_val(T n,int now,int l,int r,int L,int R){
        if(L>r||l>R)return ;
        if(R>=r&&l>=L){
            arr[now].val=n;
            arr[now].lazytag=n;
            return ;
        }
        int mid=(l+r)/2;
        if(arr[now].lazytag!=0){
            arr[now*2+1].val=arr[now].lazytag;
            arr[now*2+1].lazytag=arr[now].lazytag;
            arr[now*2+2].val=arr[now].lazytag;
            arr[now*2+2].lazytag=arr[now].lazytag;
            arr[now].lazytag=0;
        }
        update_val(n,now*2+1,l,mid,L,R);
        update_val(n,now*2+2,mid+1,r,L,R);
        arr[now].val=min(arr[now*2+1].val,arr[now*2+2].val);
        return ;
    }
    T find_val(int now,int l,int r,int L,int R){
        if(L>r||l>R)return INF;
        if(R>=r&&l>=L)return arr[now].val;
        int mid=(l+r)/2;
        if(arr[now].lazytag!=0){
            arr[now*2+1].val=arr[now].lazytag;
            arr[now*2+1].lazytag=arr[now].lazytag;
            arr[now*2+2].val=arr[now].lazytag;
            arr[now*2+2].lazytag=arr[now].lazytag;
            arr[now].lazytag=0;
        }
        return min(find_val(now*2+1,l,mid,L,R),find_val(now*2+2,mid+1,r,L,R));
    }
};
template <class T> struct segment_tree_max_multi_add{
    struct node{
        T val;
        T lazytag;
    };
    vector<node> arr;
public:
    void init(const vector<T> &a){
        arr.resize(2*a.size()-1);
        initialize(a,0,0,a.size()-1);
        return ;
    }
    void set(T n,int size){
        arr.resize(2*size-1);
        for(int i=0;i<arr.size();i++){
            arr[i].val=n;
            arr[i].lazytag=0;
        }
        return ;
    }
    void add(T n,int L,int R){
        add_val(n,0,0,arr.size()-1,L,R);
        return ;
    }
    T find(int L,int R){
        return find_val(0,0,arr.size()-1,L,R);
    }
private:
    void initialize(const vector<T> &a,int now,int l,int r){
        if(l==r)arr[now]=a[l];
        else {
            int mid=(l+r)/2;
            initialize(a,now*2+1,l,mid);
            initialize(a,now*2+2,mid+1,r);
            arr[now]=max(arr[now*2+1],arr[now*2+2]);
        }
        return ;
    }
    void add_val(T n,int now,int l,int r,int L,int R){
        if(L>r||l>R)return ;
        if(R>=r&&l>=L){
            arr[now].val+=n;
            arr[now].lazytag+=n;
            return ;
        }
        int mid=(l+r)/2;
        arr[now*2+1].val+=arr[now].lazytag;
        arr[now*2+1].lazytag+=arr[now].lazytag;
        arr[now*2+2].val+=arr[now].lazytag;
        arr[now*2+2].lazytag+=arr[now].lazytag;
        arr[now].lazytag=0;
        add_val(n,now*2+1,l,mid,L,R);
        add_val(n,now*2+2,mid+1,r,L,R);
        arr[now].val=max(arr[now*2+1].val,arr[now*2+2].val);
        return ;
    }
    T find_val(int now,int l,int r,int L,int R){
        if(L>r||l>R)return -INF;
        if(R>=r&&l>=L)return arr[now].val;
        int mid=(l+r)/2;
        arr[now*2+1].val+=arr[now].lazytag;
        arr[now*2+1].lazytag+=arr[now].lazytag;
        arr[now*2+2].val+=arr[now].lazytag;
        arr[now*2+2].lazytag+=arr[now].lazytag;
        arr[now].lazytag=0;
        return max(find_val(now*2+1,l,mid,L,R),find_val(now*2+2,mid+1,r,L,R));
    }
};
template <class T> struct segment_tree_max_multi_update{
    struct node{
        T val;
        T lazytag;
    };
    vector<node> arr;
public:
    void init(const vector<T> &a){
        arr.resize(2*a.size()-1);
        initialize(a,0,0,a.size()-1);
        return ;
    }
    void set(T n,int size){
        arr.resize(2*size-1);
        arr[0].val=n;
        arr[0].lazytag=n;
        for(int i=1;i<arr.size();i++)arr[i].lazytag=0;
        return ;
    }
    void update(T n,int L,int R){
        update_val(n,0,0,(int)arr.size()-1,L,R);
        return ;
    }
    T find(int L,int R){
        return find_val(0,0,(int)arr.size()-1,L,R);
    }
private:
    void initialize(const vector<T> &a,int now,int l,int r){
        if(l==r)arr[now]=a[l];
        else {
            int mid=(l+r)/2;
            initialize(a,now*2+1,l,mid);
            initialize(a,now*2+2,mid+1,r);
            arr[now]=max(arr[now*2+1],arr[now*2+2]);
        }
        return ;
    }
    void update_val(T n,int now,int l,int r,int L,int R){
        if(L>r||l>R)return ;
        if(R>=r&&l>=L){
            arr[now].val=n;
            arr[now].lazytag=n;
            return ;
        }
        int mid=(l+r)/2;
        if(arr[now].lazytag!=0){
            arr[now*2+1].val=arr[now].lazytag;
            arr[now*2+1].lazytag=arr[now].lazytag;
            arr[now*2+2].val=arr[now].lazytag;
            arr[now*2+2].lazytag=arr[now].lazytag;
            arr[now].lazytag=0;
        }
        update_val(n,now*2+1,l,mid,L,R);
        update_val(n,now*2+2,mid+1,r,L,R);
        arr[now].val=max(arr[now*2+1].val,arr[now*2+2].val);
        return ;
    }
    T find_val(int now,int l,int r,int L,int R){
        if(L>r||l>R)return -INF;
        if(R>=r&&l>=L)return arr[now].val;
        int mid=(l+r)/2;
        arr[now*2+1].val+=arr[now].lazytag;
        arr[now*2+1].lazytag+=arr[now].lazytag;
        arr[now*2+2].val+=arr[now].lazytag;
        arr[now*2+2].lazytag+=arr[now].lazytag;
        arr[now].lazytag=0;
        return max(find_val(now*2+1,l,mid,L,R),find_val(now*2+2,mid+1,r,L,R));
    }
};
template <class T> struct AVL_tree{
    struct node{
        T val;
        int left;
        int parent;
        int right;
        int height;
        void init(){
            left=parent=right=-1;
            height=0;
            return ;
        }
    };
    vector<node>map;
    int root;
public:
    void init(){
        
    }
    void insert(T n){
        
    }
    void erase(T n){
        
    }
    void in_print(){
        inorder(root);
        printf("\n");
        return ;
    }
    void pre_print(){
        preorder(root);
        printf("\n");
        return ;
    }
    void post_print(){
        postorder(root);
        printf("\n");
        return ;
    }
private:
    void Lrotate(int pos){
        
    }
    void Rrotate(int pos){
        
    }
    void inorder(int now){
        if(map[now].left!=-1){
            inorder(map[now].left);
            printf(" ");
        }
        cout<<map[now].val;
        if(map[now].right!=-1){
            printf(" ");
            inorder(map[now].right);
        }
        return ;
    }
    void preorder(int now){
        cout<<map[now].val;
        if(map[now].left!=-1){
            printf(" ");
            preorder(map[now].left);
        }
        if(map[now].right!=-1){
            printf(" ");
            preorder(map[now].right);
        }
        return ;
    }
    void postorder(int now){
        if(map[now].left!=-1){
            postorder(map[now].left);
            printf(" ");
        }
        if(map[now].right!=-1){
            postorder(map[now].right);
            printf(" ");
        }
        cout<<map[now].val;
        return ;
    }
};
/*template <class T>struct merge_split_tree{
    
public:
    void init(){
    
    }
    void push(){
        
    }
    void in_print(){
        inorder(root);
        printf("\n");
        return ;
    }
    void pre_print(){
        preorder(root);
        printf("\n");
        return ;
    }
    void post_print(){
        postorder(root);
        printf("\n");
        return ;
    }
private:
    void merge(){
    
    }
    void split(){
    
    }
    void inorder(int now){
        if(map[now].left!=-1){
            inorder(map[now].left);
            printf(" ");
        }
        cout<<map[now].val;
        if(map[now].right!=-1){
            printf(" ");
            inorder(map[now].right);
        }
        return ;
    }
    void preorder(int now){
        cout<<map[now].val;
        if(map[now].left!=-1){
            printf(" ");
            preorder(map[now].left);
        }
        if(map[now].right!=-1){
            printf(" ");
            preorder(map[now].right);
        }
        return ;
    }
    void postorder(int now){
        if(map[now].left!=-1){
            postorder(map[now].left);
            printf(" ");
        }
        if(map[now].right!=-1){
            postorder(map[now].right);
            printf(" ");
        }
        cout<<map[now].val;
        return ;
    }
};*/
template <class T> struct carstain_tree{
    struct node{
        T val;
        int left;
        int right;
        int parent;
        void init(){
            right=left=parent=-1;
            return ;
        }
    };
    vector<node>map;
    int root;
    int size;
public:
    void init(){
        root=-1;
        size=0;
        map.clear();
        return ;
    }
    void push(T n){
        node temp;
        temp.init();
        temp.val=n;
        map.push_back(temp);
        if(size==0)root=0;
        else insert(size-1,size);
        size++;
        return ;
    }
    void in_print(){
        inorder(root);
        printf("\n");
        return ;
    }
    void pre_print(){
        preorder(root);
        printf("\n");
        return ;
    }
    void post_print(){
        postorder(root);
        printf("\n");
        return ;
    }
private:
    void insert(int now,int n){
        if(map[n].val>map[now].val){
            map[now].right=n;
            map[n].parent=now;
        }
        else if(now==root){
            root=n;
            map[n].left=now;
            map[now].parent=n;
        }
        else{
            insert(map[now].parent,n);
            if(map[map[now].parent].right!=now){
                map[now].parent=n;
                map[n].left=now;
            }
        }
        return ;
    }
    void inorder(int now){
        if(map[now].left!=-1){
            inorder(map[now].left);
            printf(" ");
        }
        cout<<map[now].val;
        if(map[now].right!=-1){
            printf(" ");
            inorder(map[now].right);
        }
        return ;
    }
    void preorder(int now){
        cout<<map[now].val;
        if(map[now].left!=-1){
            printf(" ");
            preorder(map[now].left);
        }
        if(map[now].right!=-1){
            printf(" ");
            preorder(map[now].right);
        }
        return ;
    }
    void postorder(int now){
        if(map[now].left!=-1){
            postorder(map[now].left);
            printf(" ");
        }
        if(map[now].right!=-1){
            postorder(map[now].right);
            printf(" ");
        }
        cout<<map[now].val;
        return ;
    }
};
struct tree{
    
};
struct W_tree{
    
};
struct trie{
    
};
struct list{
    
};
struct double_list{
    
};
struct disjoint_set{
public:
    vector<int> arr;
    void init(int size){
        arr.resize(size);
        for(int i=0;i<size;i++)arr[i]=i;
        return ;
    }
    int find(int n){
        if(arr[n]==n)return n;
        return arr[n]=find(arr[n]);
    }
    void add(int l,int r){
        l=find(l);
        r=find(r);
        if(l>r)arr[l]=r;
        else arr[r]=l;
        return ;
    }
    bool check(int l,int r){
        return find(l)==find(r);
    }
};
int main(){
    int n,q,l,r;
    segment_tree_min_single_update<int>a;
    scanf("%d%d",&n,&q);
    a.set(INF,n);
    while(q--){
        scanf("%d%d%d",&n,&l,&r);
        if(n==0)a.update(r,l);
        else printf("%d\n",a.find(l,r));
    }
}

Measured memory_bytes: 4368