#include <bits/stdc++.h>
using namespace std;
struct Fast {Fast(){std::cin.tie(0);ios::sync_with_stdio(false);cout.precision(20);}} fast;

/* define */
#define FOR(I,X,Y) for(long long (I)=(X);(I)<(Y);(I)++)
#define REP(I,X,Y) for(long long (I)=(Y)-1;(I)>=(X);(I)--)
#define ALL(X) (X).begin(),(X).end()
#define pb push_back
#define COUNT(V,X) (upper_bound((V).begin(),(V).end(),X)-lower_bound((V).begin(),(V).end(),X))
#define debug(x) cerr<<#x<<':'<<x<<endl;
#define DEBUG(v) cerr<<#v<<':';for(auto xXx:v)cerr<<xXx<<' ';cerr<<endl;
#define Yes(X) if(X){cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}
#define YES(X) if(X){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}
#define ctoi(C) (C-'0')
#define pow2(x) ((long long)((long long)1<<x))

/* alias */
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vii = vector<vector<int>>;
using vl = vector<long long>;
using vll = vector<vector<long long>>;
using pi = pair<int,int>;
using pl = pair<long long,long long>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using minPQ = priority_queue<T, vector<T>, greater<T>>;

/* const */
const long long dx[] = {1,0,-1,0};
const long long dy[] = {0,1,0,-1};
const long long dx8[] = {1,1,0,-1,-1,-1,0,1};
const long long dy8[] = {0,1,1,1,0,-1,-1,-1};
const long long dx9[] = {1,1,0,-1,-1,-1,0,1,0};
const long long dy9[] = {0,1,1,1,0,-1,-1,-1,0};
const int INF = 1000000007;
const long long LINF = 1000000000000000007;

/* func */
template <typename T> inline bool chmin(T& a, const T& b) {if (a > b) a = b; return a > b;}
template <typename T> inline bool chmax(T& a, const T& b) {if (a < b) a = b; return a < b;}
long long max(long long x,int y){return max(x,(long long)y);}
long long max(int x,long long y){return max((long long)x,y);}
long long min(long long x,int y){return min(x,(long long)y);}
long long min(int x,long long y){return min((long long)x,y);}

/* liblary */

template<typename T,T monoid = 1000000007>
struct SegmentTree{
	int length;
	vector<T> data;
	//data[i]の区間 = [l[i],r[i])
	vector<int> l;
	vector<int> r;

	inline T merge(const T& a,const T& b){
		return min(a,b);
	}

	void change(int i,T val){
		data[i+length-1] = val;
		for(int k = (i+length)/2-1;k >= 0;k = (k-1)/2){
			data[k] = merge(data[2*k+1],data[2*k+2]);
			if(!k)break;
		}
	}

	//[i,j)
	T query(int i,int j){
		T ans = monoid;
		queue<int> que;
		que.push(0);
		int k;
		while(que.size()){
			k = que.front();
			que.pop();
			if(r[k] <= i || j <= l[k]){
				continue;
			}
			if(i <= l[k] && r[k] <= j){
				ans = merge(ans,data[k]);
				continue;
			}
			que.push(2*k+1);
			que.push(2*k+2);
		}
		return ans;
	}

	SegmentTree(vector<T> v) : length(1) {
		while(!(length >= v.size()))length *= 2;
		data = vector<T>(length*2-1,monoid);
		for(int i = length-1;i < v.size();i++){
			data[i] = v[i-length+1];
		}
		for(int i = length-2;0 <= i;i--){
			data[i] = merge(data[i*2+1],data[i*2+2]);
		}
		l.resize(length*2-1);
		r.resize(length*2-1);
		for(int i = length-1;i < length*2-1;i++){
			l[i] = i-length+1;
			r[i] = min(i-length+2,v.size());
		}
		for(int i = length-2;0 <= i;i--){
			l[i] = l[i*2+1];
			r[i] = r[i*2+2];
		}
	};
};

/* main */

signed main(){
	ll n,q;
	cin >> n >> q;
	SegmentTree<int,pow2(31)-1> st(vector<int>(n,pow2(31)-1));
	ll com,x,y;
	FOR(i,0,q){
		cin >> com >> x >> y;
		if(com == 0){
			st.change(x,y);
		}
		if(com == 1){
			cout << st.query(x,y+1) << endl;
		}
	}
}


Measured memory_bytes: 6240