use std::fs::File;
use std::io::{Write, BufRead, BufReader, BufWriter};
use std::cmp;
struct SegmentTree {
maxval: i32,
left: Option<Box<SegmentTree>>,
right: Option<Box<SegmentTree>>,
}
impl SegmentTree {
fn new(l: usize, r: usize, v: &[i32]) -> SegmentTree {
if l == r {
SegmentTree {
maxval: v[l],
left: None,
right: None,
}
} else {
let mid = (l + r) / 2;
let left = Box::new(SegmentTree::new(l, mid, v));
let right = Box::new(SegmentTree::new(mid + 1, r, v));
SegmentTree {
maxval: cmp::max(left.maxval, right.maxval),
left: Some(left),
right: Some(right),
}
}
}
fn update(&mut self, l: usize, r: usize, pos: usize, val: i32) {
if pos < l || r < pos {
return ;
}
if l == r {
self.maxval = val;
} else {
let mid = (l + r) / 2;
let (mut left, mut right) = (self.left.take().unwrap(), self.right.take().unwrap());
left.update(l, mid, pos, val);
right.update(mid + 1, r, pos, val);
self.maxval = cmp::max(left.maxval, right.maxval);
self.left = Some(left);
self.right = Some(right);
}
}
fn query(&mut self, l: usize, r: usize, i: usize, j: usize) -> i32 {
if j < l || r < i || j < i {
return -1;
}
if i <= l && r <= j {
self.maxval
} else {
let mid = (l + r) / 2;
let (mut left, mut right) = (self.left.take().unwrap(), self.right.take().unwrap());
let res = cmp::max(left.query(l, mid, i, j), right.query(mid + 1, r, i, j));
self.left = Some(left);
self.right = Some(right);
res
}
}
}
fn main() {
let mut fin = BufReader::new(File::open("arbint.in").unwrap());
let mut fout = BufWriter::new(File::create("arbint.out").unwrap());
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let arg : Vec<usize> = line.trim().split(' ').map(|x| -> usize {x.parse().unwrap()}).collect();
let (n, m) = (arg[0], arg[1]);
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let arg: Vec<i32> = line.trim().split(' ').map(|x| -> i32 {x.parse().unwrap()}).collect();
let mut segtree = SegmentTree::new(0, n - 1, &arg);
for _ in 0..m {
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let arg: Vec<i32> = line.trim().split(' ').map(|x| -> i32 {x.parse().unwrap()}).collect();
let (optype, a, b) = (arg[0], arg[1], arg[2]);
match optype {
0 => {
fout.write(format!("{}\n", segtree.query(0, n - 1, (a - 1) as usize, (b - 1) as usize)).as_bytes()).unwrap();
}
1 => {
segtree.update(0, n - 1, (a - 1) as usize, b);
}
_ => {}
}
}
}