Problem:
Score : 100 points

Problem Statement

You are given an array a_0, a_1, ..., a_{N-1} of length N. Process Q queries of the following types.

The type of i-th query is represented by T_i.

T_i=1: You are given two integers X_i,V_i. Replace the value of A_{X_i} with V_i.

T_i=2: You are given two integers L_i,R_i. Calculate the maximum value among A_{L_i},A_{L_i+1},\cdots,A_{R_i}.

T_i=3: You are given two integers X_i,V_i. Calculate the minimum j such that X_i \leq j \leq N, V_i \leq A_j. If there is no such j, answer j=N+1 instead.

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq A_i \leq 10^9

1 \leq Q \leq 2 \times 10^5

1 \leq T_i \leq 3

1 \leq X_i \leq N, 0 \leq V_i \leq 10^9 (T_i=1,3)

1 \leq L_i \leq R_i \leq N (T_i=2)

All values in Input are integer.

Input

Input is given from Standard Input in the following format:

N Q
A_1 A_2 \cdots A_N
First query
Second query
\vdots
Q-th query

Each query is given in the following format:

If T_i=1,3,

T_i X_i V_i

If T_i=2,

T_i L_i R_i

Output

For each query with T_i=2, 3, print the answer.

Sample Input 1

5 5
1 2 3 2 1
2 1 5
3 2 3
1 3 1
2 2 4
3 1 3

Sample Output 1

3
3
2
6

First query: Print 3, which is the maximum of (A_1,A_2,A_3,A_4,A_5)=(1,2,3,2,1).

Second query: Since 3>A_2, j=2 does not satisfy the condition．Since 3 \leq A_3, print j=3.

Third query: Replace the value of A_3 with 1. It becomes A=(1,2,1,2,1).

Fourth query: Print 2, which is the maximum of (A_2,A_3,A_4)=(2,1,2).

Fifth query: Since there is no j that satisfies the condition, print j=N+1=6.

Solution in Rust (1.42.0) (judge verdict: Wrong Answer)

use proconio::input;

fn main() {
    input! {
        n: usize,
        q: usize,
        a: [u64; n],
        tq: [(usize, u64, u64); q],
    }
    let mut segtree = SegmentTree::new(&a, std::u64::MIN, |a, b| a.max(b));
    for (t, p, q) in tq {
        match t {
            1 => segtree.update(p as usize - 1, q),
            2 => println!("{}", segtree.query(p as usize - 1, q as usize)),
            3 => println!(
                "{}",
                segtree.min_left(p as usize - 1, |v| v >= q).unwrap_or(n) + 1
            ),
            _ => unreachable!(),
        }
    }
}

struct SegmentTree<T: Copy> {
    n: usize,
    f: fn(T, T) -> T,
    e: T,
    binary_tree: Vec<T>,
}
impl<T: Copy> SegmentTree<T> {
    /// O(n) # create segment tree (e is identity element for a function f in type T)
    fn new(data: &[T], e: T, f: fn(T, T) -> T) -> Self {
        let (n, binary_tree) = (data.len(), vec![e; 2 * data.len().next_power_of_two() - 1]);
        let segment_tree = SegmentTree {
            n,
            f,
            e,
            binary_tree,
        };
        segment_tree.init(data)
    }

    /// O(n) # init segment tree by given data
    fn init(mut self, data: &[T]) -> Self {
        let leaf_offset = self.leaf_offset();
        for (i, &di) in data.iter().enumerate() {
            self.binary_tree[leaf_offset + i] = di;
        }
        for i in (0..leaf_offset).rev() {
            self.binary_tree[i] = (self.f)(
                self.binary_tree[Self::left_child(i)],
                self.binary_tree[Self::right_child(i)],
            );
        }
        self
    }

    /// O(1) # get beginning index of the segment tree leaf
    fn leaf_offset(&self) -> usize {
        self.n.next_power_of_two() - 1
    }

    /// O(1) # get size of leaves
    fn num_of_leaf(&self) -> usize {
        self.n.next_power_of_two()
    }

    /// O(1) # get left child index of node x
    fn left_child(x: usize) -> usize {
        x * 2 + 1
    }

    /// O(1) # get right child index of node x
    fn right_child(x: usize) -> usize {
        x * 2 + 2
    }

    /// O(1) # get parent index of node x
    fn parent(x: usize) -> usize {
        (x - 1) / 2
    }

    /// O(1) # get root index
    fn root() -> usize {
        0
    }

    /// O(1) # either node x is root or not
    fn is_root(x: usize) -> bool {
        x == Self::root()
    }

    /// O(log(n)) # update segment tree, leaf[k] = x
    fn update(&mut self, k: usize, x: T) {
        let i = self.leaf_offset() + k;
        self.binary_tree[i] = x;
        self.recursive_update(Self::parent(i));
    }

    /// O(log(i)) # update from leaf to root
    fn recursive_update(&mut self, i: usize) {
        if !Self::is_root(i) {
            self.binary_tree[i] = (self.f)(
                self.binary_tree[Self::left_child(i)],
                self.binary_tree[Self::right_child(i)],
            );
            self.recursive_update(Self::parent(i));
        }
    }

    /// O(log(n)) # calculate half-open interval summation from l to r (leaf index)
    fn query(&self, l: usize, r: usize) -> T {
        self.recursive_query(l, r, Self::root(), 0, self.num_of_leaf())
    }

    /// O(log(n)-log(node)) # calculate summation from root to leaf
    fn recursive_query(&self, l: usize, r: usize, node: usize, from: usize, to: usize) -> T {
        if r <= from || to <= l {
            self.e
        } else if l <= from && to <= r {
            self.binary_tree[node]
        } else {
            let mid = (from + to) / 2;
            (self.f)(
                self.recursive_query(l, r, Self::left_child(node), from, mid),
                self.recursive_query(l, r, Self::right_child(node), mid, to),
            )
        }
    }

    fn min_left<F>(&self, l: usize, f: F) -> Option<usize>
    where
        F: Fn(T) -> bool,
    {
        self.recursive_min_left(l, f, Self::root(), 0, self.num_of_leaf())
    }

    fn recursive_min_left<F>(
        &self,
        l: usize,
        f: F,
        node: usize,
        from: usize,
        to: usize,
    ) -> Option<usize>
    where
        F: Fn(T) -> bool,
    {
        if to <= l {
            None
        } else if to - from <= 1 {
            if f(self.binary_tree[node]) {
                Some(node - self.leaf_offset())
            } else {
                None
            }
        } else {
            let mid = (from + to) / 2;
            if f(self.binary_tree[Self::left_child(node)]) {
                self.recursive_min_left(l, f, Self::left_child(node), from, mid)
            } else if f(self.binary_tree[Self::right_child(node)]) {
                self.recursive_min_left(l, f, Self::right_child(node), mid, to)
            } else {
                None
            }
        }
    }
}