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 Rust (judge verdict: Accepted)

use std::io;
use std::cmp;

fn main() {
    let (n, q) = {
        let i = read::<usize>();
        (i[0], i[1])
    };
    let id = 2usize.pow(31) - 1;
    let mut st = SegmentTree::new(n, id, |&x, &y| cmp::min(x, y));
    for _ in 0..q {
        let (com, x, y) = {
            let i = read::<usize>();
            (i[0], i[1], i[2])
        };
        if com == 0 {
            st.update(x, y);
        } else {
            let m = st.apply(x, y + 1);
            println!("{}", m);
        }
    }
}

#[allow(dead_code)]
pub struct SegmentTree<T, F> {
    n: usize,
    v: Vec<T>,
    id: T,
    f: F,
}

impl<T, F> SegmentTree<T, F>
where
    T: Clone,
    F: Fn(&T, &T) -> T,
{
    pub fn new(n: usize, id: T, f: F) -> Self {
        SegmentTree {
            n: n,
            v: vec![id.clone(); 2 * n],
            id: id,
            f: f,
        }
    }

    pub fn update(&mut self, mut i: usize, x: T) {
        i += self.n;
        self.v[i] = x;
        while { i /= 2; i > 0 } {
            self.v[i] = (self.f)(&self.v[i * 2], &self.v[i * 2 + 1]);
        }
    }

    pub fn apply(&mut self, s: usize, t: usize) -> T {
        let (mut x, mut y) = (self.id.clone(), self.id.clone());
        let (mut s, mut t) = (s + self.n, t + self.n);
        while s < t {
            if s % 2 != 0 {
                x = (self.f)(&x, &self.v[s]);
                s += 1;
            }
            if t % 2 != 0 {
                t -= 1;
                y = (self.f)(&self.v[t], &y);
            }
            s /= 2;
            t /= 2;
        }
        (self.f)(&x, &y)
    }
}

#[allow(dead_code)]
fn read<T>() -> Vec<T>
where
    T: std::str::FromStr,
    T::Err: std::fmt::Debug,
{
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    buf.split_whitespace()
        .map(|s| s.trim().parse().unwrap())
        .collect()
}

#[allow(dead_code)]
fn read_one<T>() -> T
where
    T: std::str::FromStr,
    T::Err: std::fmt::Debug,
{
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    buf.trim().parse().unwrap()
}