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

// Template Headers {{{
using pii = pair<int, int>; using vpii = vector<pii>;
using vi = vector<int>; using vvi = vector<vi>;
using ll = long long; using vll = vector<long long>;
template <class T> using min_queue = priority_queue<T, vector<T>, greater<T>>;
template <class T> istream &operator>>(istream &, vector<T> &);
template <class T> ostream &operator<<(ostream &, const vector<T> &);
template <class T, class U> istream &operator>>(istream &, pair<T, U> &);
template <class T, class U> ostream &operator<<(ostream &, const pair<T, U> &);
template <class T> struct Inf { static constexpr T inf() { return std::numeric_limits<T>::has_infinity() ? std::numeric_limits<T>::infinty() : std::numeric_limits<T>::max(); } };
template <> struct Inf<int> { static constexpr int inf() { return 0x3f3f3f3f; } };
template <> struct Inf<long long> { static constexpr long long inf() { return 0x3f3f3f3f3f3f3f3fLL; } };
constexpr int INF = Inf<int>::inf(); constexpr ll BINF = Inf<ll>::inf();
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// }}}

// Classic Segment Tree {{{
template <class T, class SegOp>
class SegmentTree {
private:
	SegOp op;
	int n;
	std::vector<T> tree;

public:
	SegmentTree(const std::vector<T> &init) : n(init.size()), tree(init.size()) {
		for (const T &x : init) tree.push_back(x);
		for (int i = n - 1; i > 0; i--) tree[i] = op(tree[i << 1], tree[i << 1 | 1]);
	}

	void modify(int p, const T &val) {
		for (op.upd(tree[p += n], val); p >>= 1; ) tree[p] = op(tree[p << 1], tree[p << 1 | 1]);
	}

	T query(int l, int r) {
		T resl = op.def(), resr = op.def();
		for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
			if (l & 1) resl = op(resl, tree[l++]);
			if (r & 1) resr = op(tree[--r], resr);
		}
		return op(resl, resr);
	}

};
// }}}

// Lazy Segment Tree {{{
template <class T, class LazyOp>
class LazySegmentTree {
private:
	LazyOp op;
	int n, h;
	std::vector<T> tree, lazy;
	std::vector<bool> tag;

	void calc(int p, int len) {
		tree[p] = op(tree[p << 1], tree[p << 1 | 1]);
		if (tag[p]) op.upd(tree[p], lazy[p], len);
	}

	void apply(int p, const T &val, int len) {
		op.upd(tree[p], val, len);
		if (p < n) op.upd(lazy[p], val), tag[p] = true;
	}

	void build(int p) {
		int len = 2;
		for (p += n; p >>= 1; len <<= 1) calc(p, len);
	}

	void push(int p) {
		int s = h, len = 1 << (h - 1);
		for (p += n; s > 0; s--, len >>= 1) {
			int i = p >> s;
			if (tag[i]) {
				apply(i << 1, lazy[i], len);
				apply(i << 1 | 1, lazy[i], len);
				lazy[i] = op.udef(), tag[i] = false;
			}
		}
	}

public:
	LazySegmentTree(const std::vector<T> &init) : n(init.size()), h(0), tree(n), lazy(n + n, op.udef()), tag(n + n) {
		for (const T &x : init) tree.push_back(x);
		while ((1 << h) <= n) h++;
		for (int i=n-1;i>0;i--) tree[i] = op(tree[i << 1], tree[i << 1 | 1]);
	}

	void modify(int l, int r, const T &val) {
		push(l); push(r);
		int l0 = l, r0 = r, len = 1;
		for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1, len <<= 1) {
			if (l & 1) apply(l++, val, len);
			if (r & 1) apply(--r, val, len);
		}
		build(l0); build(r0);
	}

	T query(int l, int r) {
		push(l); push(r);
		T res = op.def();
		for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
			if (l & 1) res = op(res, tree[l++]);
			if (r & 1) res = op(tree[--r], res);
		}
		return res;
	}

};
// }}}

// Segment Tree Operators {{{
template <class T> struct SegOpTemp {
	constexpr virtual T operator()(const T &lhs, const T &rhs) = 0; // query (e.g. range max/sum)
	constexpr virtual T &upd(T &lhs, const T &rhs, int len = 1) = 0; // update (e.g. range add/assign)
	constexpr virtual const T def() = 0; // default value for result (e.g. INF for min query)
	constexpr virtual const T udef() = 0; // default value for update (e.g. 0 for add updates)
};

template <class T> struct SumAdd : SegOpTemp<T> {
	constexpr T operator()(const T &lhs, const T &rhs) { return lhs + rhs; }
	constexpr T &upd(T &lhs, const T &rhs, int len = 1) { return lhs += rhs * len; }
	constexpr const T def() { return 0; }
	constexpr const T udef() { return 0; }
};

template <class T> struct SumAsg : SegOpTemp<T> {
	constexpr T operator()(const T &lhs, const T &rhs) { return lhs + rhs; }
	constexpr T &upd(T &lhs, const T &rhs, int len = 1) { return lhs = rhs * len; }
	constexpr const T def() { return 0; }
	constexpr const T udef() { return 0; }
};

template <class T> struct MinAdd : SegOpTemp<T> {
	constexpr T operator()(const T &lhs, const T &rhs) { return min(lhs, rhs); }
	constexpr T &upd(T &lhs, const T &rhs, int = 1) { return lhs += rhs; }
	constexpr const T def() { return Inf<T>::inf(); }
	constexpr const T udef() { return 0; }
};

template <class T> struct MinAsg : SegOpTemp<T> {
	constexpr T operator()(const T &lhs, const T &rhs) { return min(lhs, rhs); }
	constexpr T &upd(T &lhs, const T &rhs, int = 1) { return lhs = rhs; }
	constexpr const T def() { return Inf<T>::inf(); }
	constexpr const T udef() { return 0; }
};
// }}}

int solve() {
	int n, q; cin >> n >> q;
	vll init(n, (1LL << 31) - 1);
	SegmentTree<ll, MinAsg<ll>> lst(init);
	while (q--) {
		int op; cin >> op;
		if (op == 0) {
			int l, v; cin >> l >> v;
			// l--, r--;
			lst.modify(l, v);
		} else {
			int l, r; cin >> l >> r;
			// l--, r--;
			cout << lst.query(l, r) << endl;
		}
	}
	return 0;
}

// Template Main {{{
int main() {
	ios::sync_with_stdio(0);
	// precompute();
	// int t; cin >> t; for (int i=1;i<=t;i++)
	solve();
	// cout << "Case #" << i << ": ", solve();
	return 0;
}

template <class T> istream &operator>>(istream &is, vector<T> &v) {
	for (auto it=v.begin();it!=v.end();++it) is >> *it;
	return is;
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
	for (auto it=v.begin();it!=v.end();) os << *it, os << " \n"[++it==v.end()];
	return os;
}

template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
	return is >> p.first >> p.second;
}

template <class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) {
	return os << p.first << ' ' << p.second;
}
// }}}

// vim: fdm=marker


Measured memory_bytes: 5240