#define NDEBUG
#include <cassert>

template <class Monoid, template <class> class Container> class segment_tree {
public:
	using value_structure = Monoid;
	using value_type = typename value_structure::value_type;
	using container_type = Container<value_type>;
	using const_reference = typename container_type::const_reference;
	using size_type = typename container_type::size_type;

private:
	size_type base_size;
	container_type c;
	static size_type getsize(const size_type size) {
		size_type ret = 1;
		while (ret < size)
			ret <<= 1;
		return ret;
	}
	void recalc(const size_type index) {
		c[index] = value_structure::operation(c[index << 1], c[index << 1 | 1]);
	}

public:
	segment_tree() : base_size(0), c() {}
	explicit segment_tree(const size_type size)
		: base_size(getsize(size)),
		c(base_size + size, value_structure::identity()) {}

	bool empty() const { return size() == 0; }
	size_type size() const { return c.size() - base_size; }

	const_reference operator[](const size_type index) const {
		assert(index < size());
		return c[index + base_size];
	}
	value_type fold(size_type first, size_type last) const {
		assert(first <= last);
		assert(first <= size());
		assert(last <= size());
		value_type ret_l = value_structure::identity(),
			ret_r = value_structure::identity();
		for (first += base_size, last += base_size; first < last;
			first >>= 1, last >>= 1) {
			if (first & 1)
				ret_l = value_structure::operation(ret_l, c[first++]);
			if (last & 1)
				ret_r = value_structure::operation(c[last - 1], ret_r);
		}
		return value_structure::operation(ret_l, ret_r);
	}
	template <class F> size_type search(const F &f) const {
		if (f(value_structure::identity()))
			return 0;
		if (!f(c[1]))
			return size() + 1;
		value_type acc = value_structure::identity();
		size_type i = 1;
		while (i < base_size)
			if (!f(value_structure::operation(acc, c[i <<= 1])))
				acc = value_structure::operation(acc, c[i++]);
		return i - base_size + 1;
	}

	void update(size_type index, const value_type &value) {
		assert(index < size());
		index += base_size;
		c[index] = value;
		while (index >>= 1)
			recalc(index);
	}
};

#include <algorithm>
#include <limits>
template <class T> class min_monoid {
public:
	using value_type = T;
	static value_type operation(const value_type &x, const value_type &y) {
		return ::std::min(x, y);
	}
	static value_type identity() {
		return 2147483647;
	}
	static value_type reverse(const value_type &x) { return x; }
};

#include <cstdio>
#include <vector>

template<class T> using vec_alias = ::std::vector<T>;
using uint = unsigned int;

void scan(uint &d) {
	d = 0;
	int c;
	while (c = fgetc(stdin), c == ' ' || c == '\n');
	do
		d = d * 10 + c - '0';
	while (c = fgetc(stdin), c != ' '&&c != '\n');
}

#include<array>

void println(uint d) {
	::std::array<int, 30> buf;
	int i = 0;
	while (d)
		buf[i++] = d % 10 + '0', d /= 10;
	if (!i)
		buf[i++] = '0';
	while (i--)
		fputc(buf[i], stdout);
	fputc('\n', stdout);
}

int main() {
	uint n, q;
	scan(n), scan(q);

	segment_tree<min_monoid<uint>, vec_alias> seg(n);

	uint c, x, y;
	while (q--) {
		scan(c), scan(x), scan(y);

		if (c)
			println(seg.fold(x, y + 1));
		else
			seg.update(x, y);
	}

	return 0;
}



Measured memory_bytes: 3072