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::cmp;
use std::collections::HashMap;
use std::io::*;
use std::str::FromStr;
use std::string::String;

const MAX: i64 = 2147483647;

struct Segtree {
    node: Vec<i64>,
    size: usize,
}

impl Segtree {
    fn new(n: i32) -> Segtree {
        Segtree {
            size: {
                let mut tmp_size: usize = 1;
                while tmp_size < n as usize {
                    tmp_size *= 2;
                }
                tmp_size
            },
            node: {
                let mut tmp_size: usize = 1;
                while tmp_size < n as usize {
                    tmp_size *= 2;
                }
                vec![MAX; 2*tmp_size-1]
            }
        }
    }

    fn update(&mut self, mut k: usize, val: i64) {
        k += self.size - 1;
        self.node[k] = val;
        while k > 0 {
            k = (k - 1) / 2;
            self.node[k] = std::cmp::min(self.node[2*k+1], self.node[2*k+2]);
        }
    }

    fn get(&self, queryL: usize, queryR: usize) -> i64 {
        self._get(queryL, queryR, 0, self.size, 0)
    }

    fn _get(&self, queryL: usize, queryR: usize, nodeL: usize, nodeR: usize, k: usize) -> i64 {
        if nodeR <= queryL || queryR <= nodeL {return MAX;}
        if queryL <= nodeL && nodeR <= queryR {return self.node[k];}
        let nodeM: usize = (nodeL + nodeR) / 2;
        let vl: i64 = self._get(queryL, queryR, nodeL, nodeM, 2*k+1);
        let vr: i64 = self._get(queryL, queryR, nodeM, nodeR, 2*k+2);
        std::cmp::min(vl, vr)
    }
}

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();

    token.parse().ok().expect("failed to parse token")
}

fn main() {
    /*
    let mut buf = String::new();
    std::io::stdin().read_line(& mut buf).ok();
    let buf = buf.trim();
    let n: i32 = buf.trim().parse().ok().unwrap();
    //println!{"{}", n};

    let mut buf = String::new();
    std::io::stdin().read_line(& mut buf).ok();
    let buf = buf.trim();
    let v: Vec<i32> = buf.split_whitespace().map(|x| x.parse().ok().unwrap()).collect();
    */
    let (n, q): (i32, i32) = (read(), read());
    let mut seg = Segtree::new(n);

    for _ in 0..q {
        let (com, x, y): (i32, usize, usize) = (read(), read(), read());
        if com == 0 {
            seg.update(x, y as i64);
        }
        else {
            println!{"{}", seg.get(x, y+1)};
        }
    }
    /*
    let mut seg = Segtree::new(4);
    println!{"{}", seg.node.len()};
    seg.update(0, 10);
    seg.update(1, 2);
    println!{"{}", seg.node[3]};
    println!{"{}", seg.node[4]};
    println!{"{}", seg.get(0, 1)};
    */
}