Problem:
Range Minimum Query (RMQ)

Write a program which manipulates a sequence A = {a0, a1, . . . , an-1} with the following operations:

find(s, t): report the minimum element in as, as+1, . . . ,at.

update(i, x): change ai to x.

Note that the initial values of ai (i = 0, 1, . . . , n−1) are 231-1.

Input

n q
com0 x0 y0
com1 x1 y1
...
comq−1 xq−1 yq−1

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, q queries are given where com represents the type of queries. '0' denotes update(xi, yi) and '1' denotes find(xi, yi).

Output

For each find operation, print the minimum element.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

If comi is 0, then 0 ≤ xi < n, 0 ≤ yi < 231-1.

If comi is 1, then 0 ≤ xi < n, 0 ≤ yi < n.

Sample Input 1

3 5
0 0 1
0 1 2
0 2 3
1 0 2
1 1 2

Sample Output 1

1
2

Sample Input 2

1 3
1 0 0
0 0 5
1 0 0

Sample Output 2

2147483647
5

Solution in C++14 (judge verdict: Time Limit Exceeded)

//#define NDEBUG
#define _CRT_SECURE_NO_WARNINGS
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <type_traits>

template <class Integral> class Rirange;

template <class Integral = std::size_t> class irange {
public:
	using value_type = Integral;
	using reference = value_type &;
	using const_reference = const value_type &;
	class irangeitr {
		friend irange;
		value_type i;
		irangeitr(const value_type x) noexcept : i(x) {}

	public:
		void operator++() noexcept { ++i; }
		value_type &operator*() noexcept { return i; }
		const_reference operator*() const noexcept { return i; }
		bool operator!=(const irangeitr &x) const noexcept { return i < x.i; }
	};

private:
	const value_type f, l;

public:
	irange(const value_type first, const value_type last) noexcept
		: f(first), l(last) {}
	irangeitr begin() const noexcept { return irangeitr(f); }
	irangeitr end() const noexcept { return irangeitr(l); }
	Rirange<value_type> rev() const noexcept {
		return Rirange<value_type>(l - 1, f - 1);
	}
};
template <class Integral = std::size_t> class Rirange {
public:
	using value_type = Integral;
	using reference = value_type &;
	using const_reference = const value_type &;
	class Rirangeitr {
		friend Rirange;
		value_type i;
		Rirangeitr(const value_type x) noexcept : i(x) {}

	public:
		void operator++() noexcept { --i; }
		reference operator*() noexcept { return i; }
		const_reference operator*() const noexcept { return i; }
		bool operator!=(const Rirangeitr &x) const noexcept {
			return (!~x.i && ~i) || x.i < i;
		}
	};

private:
	const value_type f, l;

public:
	Rirange(const value_type x, const value_type y) noexcept : f(x), l(y) {}
	Rirangeitr begin() const noexcept { return Rirangeitr(f); }
	Rirangeitr end() const noexcept { return Rirangeitr(l); }
	irange<value_type> rev() const noexcept {
		return irange<value_type>(l + 1, f + 1);
	}
};

template <class T> bool maxi(T &a, const T &b) {
	if (b < a)
		return 0;
	a = b;
	return 1;
}
template <class T> bool mini(T &a, const T &b) {
	if (a < b)
		return 0;
	a = b;
	return 1;
}
template <class T> bool smaxi(T &a, const T &b) {
	if (a < b) {
		a = b;
		return 1;
	}
	return 0;
}
template <class T> bool smini(T &a, const T &b) {
	if (b < a) {
		a = b;
		return 1;
	}
	return 0;
}
struct customIO {
	int c;
	bool f;
	std::array<int, 30> buf;
	const std::array<int, 10> itoc;
	std::array<std::uint_least8_t, 256> ctoi_base;
	const std::uint_least8_t *const ctoi;
	void get_c() { c = fgetc(stdin); }
	void put_c(int x) { fputc(x, stdout); }
	bool vacant() { return c == ' ' || c == '\n'; }
	operator int() { return 0; }

	explicit customIO()
		: itoc({ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }),
		ctoi(std::addressof(ctoi_base[-static_cast<std::int_fast16_t>(
			std::numeric_limits<char>::min())])) {
		for (std::uint_least8_t i = 0; i < 10; ++i)
			ctoi_base[static_cast<int>("0123456789"[i]) -
			static_cast<std::int_fast16_t>(
				std::numeric_limits<char>::min())] = i;
	}
	// in

	void cueing() {
		while (get_c(), vacant())
			;
	}
	template <class T>
	auto operator>>(T &d) ->
		typename std::enable_if<std::is_signed<T>::value, customIO &>::type {
		d = 0;
		f = 0;
		cueing();
		if (c == '-')
			f = 1, get_c();
		do
			d = d * 10 + ctoi[c];
		while (get_c(), !vacant());
		if (f)
			d = -d;
		return *this;
	}
	template <class T>
	auto operator>>(T &d) ->
		typename std::enable_if<!std::is_signed<T>::value, customIO &>::type {
		d = 0;
		cueing();
		do
			d = d * 10 + ctoi[c];
		while (get_c(), !vacant());
		return *this;
	}
	customIO &operator>>(char &d) {
		cueing();
		d = c;
		return *this;
	}
	customIO &operator>>(double &d) {
		scanf("%lf", &d);
		return *this;
	}
	customIO &operator>>(std::string &d) {
		d.clear();
		cueing();
		do
			d.push_back(c);
		while (get_c(), !vacant());
		return *this;
	}
	template <class T> T input() {
		T d;
		*this >> d;
		return d;
	}

	// out

	template <class T>
	auto operator<<(T d) ->
		typename std::enable_if<std::is_signed<T>::value, customIO &>::type {
		c = 0;
		f = 0;
		if (d < static_cast<T>(0))
			f = 1, d = -d;
		while (d)
			buf[c++] = itoc[d % 10], d /= 10;
		if (!c)
			buf[c++] = itoc[0];
		if (f)
			put_c('-');
		while (c--)
			put_c(buf[c]);
		return *this;
	}
	template <class T>
	auto operator<<(T d) ->
		typename std::enable_if<!std::is_signed<T>::value, customIO &>::type {
		c = 0;
		while (d)
			buf[c++] = itoc[d % 10], d /= 10;
		if (!c)
			buf[c++] = itoc[0];
		while (c--)
			put_c(buf[c]);
		return *this;
	}
	customIO &operator<<(char d) {
		put_c(d);
		return *this;
	}
	customIO &operator<<(double d) {
		printf("%f", d);
		return *this;
	}
	customIO &operator<<(const std::string &d) {
		for (const auto e : d)
			put_c(e);
		return *this;
	}
	customIO &operator<<(const char *d) {
		while (*d != '\0')
			put_c(*(d++));
		return *this;
	}
	void endl() { put_c('\n'); }
	void space() { put_c(' '); }
} IO;
#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <memory>
#include <numeric>
#include <utility>
#include <vector>

template <class Integral, class T,
	std::size_t bitsize = std::numeric_limits<Integral>::digits()>
	class WaveletMatrixSum {
	public:
		using key_type = Integral;
		using linked_type = T;
		using value_type = std::pair<key_type, linked_type>;
		using size_type = std::size_t;

	private:
		using uint32 = std::uint_least32_t;
		static size_type popcount32(uint32 c) {
#ifdef __GNUC__
			return __builtin_popcount(c);
#elif _MSC_VER_
			return _mm_popcnt_u32(c);
#else
			c = (c & 0x55555555) + ((c >> 1) & 0x55555555);
			c = (c & 0x33333333) + ((c >> 2) & 0x33333333);
			c = (c + (c >> 4)) & 0x0F0F0F0F;
			c += c >> 8;
			c += c >> 16;
			return static_cast<size_type>(c) & 0x3F;
#endif
		}
		struct FID {
			std::vector<uint32> dic;
			size_type cnt;
			key_type bit;
			std::vector<linked_type> sum;

			FID() {}

			void set(const size_type index) {
				dic[index >> 4 | 1] |= static_cast<uint32>(1) << (index & 0x1f);
			}
			void build() {
				const size_type len = dic.size();
				for (size_type j = 2; j < len; j += 2)
					dic[j] = dic[j - 2] + popcount32(dic[j - 1]);
			}

			size_type rank(const size_type last) const {
				return static_cast<size_type>(
					dic[last >> 4 & ~static_cast<size_type>(1)]) +
					popcount32(dic[last >> 4 | 1] &
					(static_cast<size_type>(1) << (last & 0x1f)) - 1);
			}
			bool access(const size_type index) const {
				return dic[index >> 4 | 1] >> (index & 0x1f) & 1;
			}
			linked_type range(const size_type first, const size_type last) const {
				return sum[last] - sum[first];
			}
		};
		std::array<FID, bitsize> matrix;
		value_type NOT_FOUND;
		size_type size_;

	public:
		WaveletMatrixSum(const std::vector<value_type> &data,
			const value_type NOT_FOUND = value_type())
			: size_(data.size()), NOT_FOUND(NOT_FOUND) {
			const size_type len = data.size(), block = ((len >> 5) + 1) << 1;
			std::vector<size_type> C(len), L(len), R(len);
			std::iota(C.begin(), C.end(), static_cast<size_type>(0));
			size_type l, r;
			key_type temp = static_cast<key_type>(1) << (bitsize - 1);
			for (auto &x : matrix) {
				x.dic.resize(block, 0);
				x.bit = temp;
				temp = temp >> 1 & ~temp;
				l = 0;
				r = 0;
				for (size_type i = 0; i < len; ++i)
					if (data[C[i]].first & x.bit)
						R[r++] = C[i], x.set(i);
					else
						L[l++] = C[i];
				x.cnt = l;
				x.build();
				std::swap(C, L);
				std::copy(R.begin(), R.begin() + r, C.begin() + l);
				for (size_type i = 0; i < len; ++i)
					x.sum.reserve(len + 1);
				x.sum.emplace_back();
				for (const auto e : C)
					x.sum.emplace_back(x.sum.back() + data[e].second);
			}
		}

		size_type size() const noexcept { return size_; }
		bool empty() const noexcept { return size() == 0; }

		value_type access(size_type index) const {
			assert(index < size());
			key_type ret = 0;
			for (const auto &x : matrix)
				if (x.access(index))
					ret |= x.bit, index = x.rank(index) + x.cnt;
				else
					index -= x.rank(index);
			return value_type(ret, matrix.back().range(index, index + 1));
		}
		value_type operator[](const size_type index) const {
			assert(index < size());
			return access(index);
		}
		size_type rank(size_type first, size_type last, const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			for (const auto &x : matrix)
				if (data & x.bit)
					first = x.rank(first) + x.cnt, last = x.rank(last) + x.cnt;
				else
					first -= x.rank(first), last -= x.rank(last);
			return last - first;
		}
		linked_type rank_sum(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			for (const auto &x : matrix)
				if (data & x.bit)
					first = x.rank(first) + x.cnt, last = x.rank(last) + x.cnt;
				else
					first -= x.rank(first), last -= x.rank(last);
			return matrix.back().range(first, last);
		}
		value_type quantile(size_type first, size_type last, size_type k) const {
			assert(first < size());
			assert(last <= size());
			assert(first < last);
			assert(last - first > k);
			key_type ret = 0;
			for (const auto &x : matrix) {
				const size_type l = x.rank(first), r = x.rank(last);
				if (r - l > k)
					first = l + x.cnt, last = r + x.cnt, ret |= x.bit;
				else
					first -= l, last -= r, k -= r - l;
			}
			return value_type(ret, matrix.back().range(last - k - 1, last - k));
		}
		value_type rquantile(size_type first, size_type last, size_type k) const {
			assert(first < size());
			assert(last <= size());
			assert(first < last);
			assert(last - first > k);
			return quantile(first, last, last - first - k - 1);
		}
		size_type less_than(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			size_type ret = 0;
			for (const auto &x : matrix) {
				if (data & x.bit) {
					ret += last - first + x.rank(first) - x.rank(last);
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return ret;
		}
		linked_type less_than_sum(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			linked_type ret = linked_type();
			for (const auto &x : matrix) {
				if (data & x.bit) {
					ret = ret + x.range(first - x.rank(first), last - x.rank(last));
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return ret;
		}
		size_type at_least(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			size_type ret = 0;
			for (const auto &x : matrix) {
				if (data & x.bit) {
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					ret += x.rank(last) - x.rank(first);
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return last - first + ret;
		}
		linked_type at_least_sum(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			linked_type ret = linked_type();
			for (const auto &x : matrix) {
				if (data & x.bit) {
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					ret = ret + x.range(x.rank(first) + x.cnt, x.rank(last) + x.cnt);
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return ret + matrix.back().range(first, last);
		}
		size_type greater_than(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			size_type ret = 0;
			for (const auto &x : matrix) {
				if (data & x.bit) {
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					ret += x.rank(last) - x.rank(first);
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return ret;
		}
		linked_type greater_than_sum(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			linked_type ret = linked_type();
			for (const auto &x : matrix) {
				if (data & x.bit) {
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					ret = ret + x.range(x.rank(first) + x.cnt, x.rank(last) + x.cnt);
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return ret;
		}
		size_type at_most(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			size_type ret = 0;
			for (const auto &x : matrix) {
				if (data & x.bit) {
					ret += last - first + x.rank(first) - x.rank(last);
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return last - first + ret;
		}
		linked_type at_most_sum(size_type first, size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			linked_type ret = linked_type();
			for (const auto &x : matrix) {
				if (data & x.bit) {
					ret = ret + x.range(first - x.rank(first), last - x.rank(last));
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return ret + matrix.back().range(first, last);
		}
		size_type rangefreq(size_type first, size_type last, const key_type lower,
			const key_type upper) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			assert(lower <= upper);
			return less_than(first, last, upper) - less_than(first, last, lower);
		}
		linked_type rangefreq_sum(size_type first, size_type last,
			const key_type lower, const key_type upper) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			assert(lower <= upper);
			return less_than_sum(first, last, upper) -
				less_than_sum(first, last, lower);
		}
		linked_type maxk_sum(size_type first, size_type last, size_type k) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			assert(last - first >= k);
			linked_type ret = linked_type();
			for (const auto &x : matrix) {
				const size_type l = x.rank(first), r = x.rank(last);
				if (r - l > k) {
					first = l + x.cnt;
					last = r + x.cnt;
				}
				else {
					ret = ret + x.range(l + x.cnt, r + x.cnt);
					first -= l;
					last -= r;
					k -= r - l;
				}
			}
			return ret + matrix.back().range(last - k, last);
		}
		linked_type mink_sum(size_type first, size_type last, size_type k) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			assert(last - first >= k);
			linked_type ret = linked_type();
			for (const auto &x : matrix) {
				const size_type l = first - x.rank(first), r = last - x.rank(last);
				if (r - l > k) {
					first = l;
					last = r;
				}
				else {
					ret = ret + x.range(l, r);
					first += x.cnt - l;
					last += x.cnt - r;
					k -= r - l;
				}
			}
			return ret + matrix.back().range(first, first + k);
		}
		value_type successor(const size_type first, const size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			const size_type k = less_than(first, last, data);
			return last - first == k ? NOT_FOUND : rquantile(first, last, k);
		}
		value_type predecessor(const size_type first, const size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			const size_type k = greater_than(first, last, data);
			return last - first == k ? NOT_FOUND : quantile(first, last, k);
		}
		value_type strict_succ(const size_type first, const size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			const size_type k = greater_than(first, last, data);
			return k ? quantile(first, last, k - 1) : NOT_FOUND;
		}
		value_type strict_pred(const size_type first, const size_type last,
			const key_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			const size_type k = less_than(first, last, data);
			return k ? rquantile(first, last, k - 1) : NOT_FOUND;
		}
};
using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
using intl32 = std::int_least32_t;
using intl64 = std::int_least64_t;
using uintl32 = std::uint_least32_t;
using uintl64 = std::uint_least64_t;

#include<utility>
#include<vector>

int main() {
	/*
	const auto n = IO.input<uint32>();
	std::vector<std::pair<uint32,int64>> a(n * 3);
	for (auto &e : a) {
		IO >> e.first;
		e.second = e.first;
	}
	WaveletMatrixSum<uint32, int64, 30> W(a);
	int64 ans = INT64_MIN;
	for (const auto i : irange<>(n, n * 2 + 1))
		smaxi(ans, W.maxk_sum(0, i, n) - W.mink_sum(i, n * 3, n));
	IO << ans << '\n';
	*/
	uint32 n, q;
	IO >> n >> q;
	std::vector<std::pair<uintl32, uintl32>> a(n);
	for (auto &e : a)
		e.first = e.second = 2147483647;
	while (q--) {
		uint32 c, x, y;
		IO >> c >> x >> y;
		if (c) {
			WaveletMatrixSum<uintl32, uintl32, 31> W(a);
			IO << W.mink_sum(x, y + 1, 1) << '\n';
		}
		else {
			a[x].first = a[x].second = y;
		}
	}
	return 0;
}