Problem:
Score : 500 points

Problem Statement

You have a string S of length N.
Initially, all characters in S are 1s.

You will perform queries Q times.
In the i-th query, you are given two integers L_i, R_i and a character D_i (which is a digit).
Then, you must replace all characters from the L_i-th to the R_i-th (inclusive) with D_i.

After each query, read the string S as a decimal integer, and print its value modulo 998,244,353.

Constraints

1 \leq N, Q \leq 200,000

1 \leq L_i \leq R_i \leq N

1 \leq D_i \leq 9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N Q
L_1 R_1 D_1
:
L_Q R_Q D_Q

Output

Print Q lines.
In the i-th line print the value of S after the i-th query, modulo 998,244,353.

Sample Input 1

8 5
3 6 2
1 4 7
3 8 3
2 2 2
4 5 1

Sample Output 1

11222211
77772211
77333333
72333333
72311333

Sample Input 2

200000 1
123 456 7

Sample Output 2

641437905

Don't forget to take the modulo.

Solution in Rust (1.42.0) (judge verdict: Accepted)

#[allow(unused_imports)]
use ngtio::prelude::*;

use type_traits::One;

type Fp = fp::F998244353;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct X;
impl Monoid for X {
    type S = Option<(Fp, usize)>;
    fn identity() -> Option<(Fp, usize)> {
        None
    }
    fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
        match (a, b) {
            (Some((a, len_a)), Some((b, len_b))) => {
                Some((Fp::new(10).pow(*len_b as u64) * a + b, len_a + len_b))
            }
            (Some(a), None) => Some(*a),
            (None, Some(b)) => Some(*b),
            (None, None) => None,
        }
    }
}
pub struct A;
impl MapMonoid for A {
    type M = X;
    type F = Option<Fp>;
    fn identity_map() -> Self::F {
        None
    }
    fn mapping(f: &Self::F, x: &<Self::M as Monoid>::S) -> <Self::M as Monoid>::S {
        match (*f, *x) {
            (Some(f), Some((_, len))) => Some((
                f * (Fp::new(10).pow(len as u64) - Fp::one()) / Fp::new(9),
                len,
            )),
            (Some(_), None) => None,
            (None, x) => x,
        }
    }
    fn composition(f: &Self::F, g: &Self::F) -> Self::F {
        match (f, g) {
            (Some(f), _) => Some(*f),
            (None, x) => *x,
        }
    }
}

fn main() {
    let mut buf = ngtio::with_stdin();
    let n = buf.usize();
    let mut seg = LazySegtree::<A>::new(n);
    (0..n).for_each(|i| seg.set(i, Some((Fp::one(), 1))));
    for _ in 0..buf.usize() {
        let (l, r, x) = buf.tuple::<(Usize1, usize, i64)>();
        let x = Fp::new(x);
        seg.apply_range(l, r, Some(x));
        let ans = seg.prod(0, n).unwrap();
        println!("{}", ans.0);
    }
}

// fp {{{
#[allow(dead_code)]
mod fp {
    #![warn(missing_docs)]
    use crate::type_traits::*;
    pub use aliases::*;
    use std::{cmp, fmt, iter, mem, ops::*};

    mod arith {
        use super::{Fp, Modable, Value};
        use crate::type_traits::*;
        use std::ops::*;

        impl<Mod: Modable> Add for Fp<Mod>
        where
            Mod::Output: Value,
        {
            type Output = Self;

            #[inline]
            fn add(self, rhs: Self) -> Self {
                Self(Self::normalize_from_the_bottom(
                    self.into_inner() + rhs.into_inner(),
                ))
            }
        }

        impl<Mod: Modable> Sub for Fp<Mod>
        where
            Mod::Output: Value,
        {
            type Output = Self;

            #[inline]
            fn sub(self, rhs: Self) -> Self {
                Self(Self::normalize_from_the_top(
                    self.into_inner() - rhs.into_inner(),
                ))
            }
        }

        impl<Mod: Modable> Mul for Fp<Mod>
        where
            Mod::Output: Value,
        {
            type Output = Self;

            #[inline]
            fn mul(self, rhs: Self) -> Self {
                Self::new(self.into_inner() * rhs.into_inner())
            }
        }

        #[allow(clippy::suspicious_arithmetic_impl)]
        impl<Mod: Modable> Div for Fp<Mod>
        where
            Mod::Output: Value,
        {
            type Output = Self;

            #[inline]
            fn div(self, rhs: Self) -> Self {
                self * rhs.inv()
            }
        }

        impl<Mod: Modable> Neg for Fp<Mod>
        where
            Mod::Output: Value,
        {
            type Output = Self;

            #[inline]
            fn neg(self) -> Self {
                if self.into_inner().is_zero() {
                    Self::zero()
                } else {
                    Self(Mod::VALUE - self.into_inner())
                }
            }
        }

        impl<Mod: Modable> Neg for &Fp<Mod>
        where
            Mod::Output: Value,
        {
            type Output = Fp<Mod>;

            #[inline]
            fn neg(self) -> Fp<Mod> {
                if self.into_inner().is_zero() {
                    Fp::zero()
                } else {
                    Fp(Mod::VALUE - self.into_inner())
                }
            }
        }

        macro_rules! forward_assign_biop {
            ($(impl $trait:ident, $fn_assign:ident, $fn:ident)*) => {
                $(
                    impl<Mod: Modable> $trait for Fp<Mod>
                    where
                        Mod::Output: Value
                    {
                        #[inline]
                        fn $fn_assign(&mut self, rhs: Self) {
                            *self = self.$fn(rhs);
                        }
                    }
                )*
            };
        }
        forward_assign_biop! {
            impl AddAssign, add_assign, add
            impl SubAssign, sub_assign, sub
            impl MulAssign, mul_assign, mul
            impl DivAssign, div_assign, div
        }

        macro_rules! forward_ref_binop {
            ($(impl $imp:ident, $method:ident)*) => {
                $(
                    impl<'a, Mod: Modable> $imp<Fp<Mod>> for &'a Fp<Mod>
                    where
                        Mod::Output:Value
                    {
                        type Output = Fp<Mod>;

                        #[inline]
                        fn $method(self, other: Fp<Mod>) -> Self::Output {
                            $imp::$method(*self, other)
                        }
                    }

                    impl<'a, Mod: Modable> $imp<&'a Fp<Mod>> for Fp<Mod>
                    where
                        Mod::Output:Value
                    {
                        type Output = Fp<Mod>;

                        #[inline]
                        fn $method(self, other: &Fp<Mod>) -> Self::Output {
                            $imp::$method(self, *other)
                        }
                    }

                    impl<'a, Mod: Modable> $imp<&'a Fp<Mod>> for &'a Fp<Mod>
                    where
                        Mod::Output:Value
                    {
                        type Output = Fp<Mod>;

                        #[inline]
                        fn $method(self, other: &Fp<Mod>) -> Self::Output {
                            $imp::$method(*self, *other)
                        }
                    }
                )*
            };
        }
        forward_ref_binop! {
            impl Add, add
            impl Sub, sub
            impl Mul, mul
            impl Div, div
        }
    }

    #[macro_export]
    macro_rules! fp_vec {
        () => (
            Vec::<$crate::Fp<_>>::new()
        );
        ($elem:expr; $n:expr) => (
            vec![$crate::Fp::new($elem); $n]
        );
        ($($x:expr),+ $(,)?) => (
            vec![$($crate::Fp::new($x),)+];
        );
    }

    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    pub struct Fp<Mod: Modable>(Mod::Output);

    impl<Mod: Modable> Fp<Mod>
    where
        Mod::Output: Value,
    {
        #[inline]
        pub fn new(src: Mod::Output) -> Self {
            Self(Self::normalize(src))
        }

        #[inline]
        pub fn frac(num: Mod::Output, den: Mod::Output) -> Self {
            Self::new(num) / Self::new(den)
        }

        #[inline]
        pub fn into_inner(self) -> Mod::Output {
            self.0
        }

        #[allow(clippy::many_single_char_names)]
        pub fn inv(self) -> Self {
            assert_ne!(
                self.into_inner(),
                Mod::Output::zero(),
                "さては 0 の逆元を取ろうとしていますね？"
            );
            let mut x = self.into_inner();
            let mut y = Mod::VALUE;
            let mut u = Mod::Output::one();
            let mut v = Mod::Output::zero();
            while x != Mod::Output::zero() {
                let q = y / x;
                y -= q * x;
                v -= q * u;
                mem::swap(&mut x, &mut y);
                mem::swap(&mut u, &mut v);
            }
            assert!(
                x == Mod::Output::zero()
                    && y == Mod::Output::one()
                    && (u == Mod::VALUE || u == -Mod::VALUE)
                    && (-Mod::VALUE < v && v < Mod::VALUE)
            );
            Self(Self::normalize_from_the_top(v))
        }

        pub fn pow(mut self, mut p: u64) -> Self {
            let mut ans = Self::one();
            while p != 0 {
                if p % 2 == 1 {
                    ans *= self;
                }
                self *= self;
                p /= 2;
            }
            ans
        }

        #[inline]
        fn normalize(src: Mod::Output) -> Mod::Output {
            Self::normalize_from_the_top(src % Mod::VALUE)
        }

        #[inline]
        fn normalize_from_the_bottom(src: Mod::Output) -> Mod::Output {
            if Mod::VALUE <= src {
                src - Mod::VALUE
            } else {
                src
            }
        }

        #[inline]
        fn normalize_from_the_top(src: Mod::Output) -> Mod::Output {
            if src < Mod::Output::zero() {
                src + Mod::VALUE
            } else {
                src
            }
        }
    }

    impl<Mod: Modable> Zero for Fp<Mod>
    where
        Mod::Output: Value,
    {
        #[inline]
        fn zero() -> Fp<Mod> {
            Fp::new(Mod::Output::zero())
        }
    }

    impl<Mod: Modable> One for Fp<Mod>
    where
        Mod::Output: Value,
    {
        #[inline]
        fn one() -> Fp<Mod> {
            Fp::new(Mod::Output::one())
        }
    }

    impl<Mod: Modable> iter::Sum<Fp<Mod>> for Fp<Mod>
    where
        Mod::Output: Value,
    {
        fn sum<I>(iter: I) -> Self
        where
            I: iter::Iterator<Item = Fp<Mod>>,
        {
            iter.fold(Fp::zero(), Add::add)
        }
    }

    impl<'a, Mod: 'a + Modable> iter::Sum<&'a Fp<Mod>> for Fp<Mod>
    where
        Mod::Output: Value,
    {
        fn sum<I>(iter: I) -> Self
        where
            I: iter::Iterator<Item = &'a Fp<Mod>>,
        {
            iter.fold(Fp::zero(), Add::add)
        }
    }

    impl<Mod: Modable> iter::Product<Fp<Mod>> for Fp<Mod>
    where
        Mod::Output: Value,
    {
        fn product<I>(iter: I) -> Self
        where
            I: iter::Iterator<Item = Fp<Mod>>,
        {
            iter.fold(Self::one(), Mul::mul)
        }
    }

    impl<'a, Mod: 'a + Modable> iter::Product<&'a Fp<Mod>> for Fp<Mod>
    where
        Mod::Output: Value,
    {
        fn product<I>(iter: I) -> Self
        where
            I: iter::Iterator<Item = &'a Fp<Mod>>,
        {
            iter.fold(Self::one(), Mul::mul)
        }
    }

    impl<Mod: Modable> fmt::Display for Fp<Mod>
    where
        Mod::Output: Value,
    {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
            write!(f, "{}", self.0)
        }
    }

    pub trait Modable: Constant + Clone + fmt::Debug + cmp::PartialEq + cmp::Eq {}
    impl<Mod: Constant + Clone + fmt::Debug + cmp::PartialEq + cmp::Eq> Modable for Mod {}

    pub trait Value:
        Sized
        + Clone
        + Copy
        + Ring
        + fmt::Debug
        + fmt::Display
        + cmp::PartialOrd
        + cmp::Ord
        + cmp::Eq
        + Div<Output = Self>
        + Rem<Output = Self>
        + Neg<Output = Self>
        + DivAssign
        + RemAssign
    {
    }

    macro_rules! impl_value {
        ($($type:ty,)*) => { $(impl Value for $type {})* };
    }

    impl_value! { i8, i16, i32, i64, i128, isize, }

    mod aliases {
        use super::Fp;
        use crate::type_traits::Constant;

        #[derive(Debug, Clone, Copy, PartialEq, Eq)]
        pub struct Mod1000000007 {}
        pub type F1000000007 = Fp<Mod1000000007>;
        impl Constant for Mod1000000007 {
            type Output = i64;
            const VALUE: i64 = 1_000_000_007;
        }

        #[derive(Debug, Clone, Copy, PartialEq, Eq)]
        pub struct Mod998244353 {}
        pub type F998244353 = Fp<Mod998244353>;
        impl Constant for Mod998244353 {
            type Output = i64;
            const VALUE: i64 = 998_244_353;
        }
    }
}
// }}}
// dbg {{{
#[allow(dead_code)]
mod dbg {
    #[macro_export]
    macro_rules! lg {
        () => {
            $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
        };
        ($val:expr) => {
            match $val {
                tmp => {
                    eprintln!("[{}:{}] {} = {:?}",
                        file!(), line!(), stringify!($val), &tmp);
                    tmp
                }
            }
        };
        ($val:expr,) => { $crate::lg!($val) };
        ($($val:expr),+ $(,)?) => {
            ($($crate::lg!($val)),+,)
        };
    }

    #[macro_export]
    macro_rules! lg_nl {
        () => {
            eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
        };
        ($val:expr) => {
            match $val {
                tmp => {
                    eprintln!("[{}:{}] {}:\n{:?}", file!(), line!(), stringify!($val), tmp);
                    tmp
                }
            };
        };
    }

    #[macro_export]
    macro_rules! msg {
        () => {
            compile_error!();
        };
        ($msg:expr) => {
            $crate::eprintln!("[{}:{}][{}]", $crate::file!(), $crate::line!(), $msg);
        };
        ($msg:expr, $val:expr) => {
            match $val {
                tmp => {
                    eprintln!("[{}:{}][{}] {} = {:?}",
                        file!(), line!(), $msg, stringify!($val), &tmp);
                    tmp
                }
            }
        };
        ($msg:expr, $val:expr,) => { msg!($msg, $val) };
        ($msg:expr, $($val:expr),+ $(,)?) => {
            ($(msg!($msg, $val)),+,)
        };
    }

    #[macro_export]
    macro_rules! tabular {
        ($val:expr) => {
            $crate::lg_nl!(crate::dbg::Tabular($val))
        };
    }

    #[macro_export]
    macro_rules! boolean_table {
        ($val:expr) => {
            $crate::lg_nl!(crate::dbg::BooleanTable($val));
        };
    }

    #[macro_export]
    macro_rules! boolean_slice {
        ($val:expr) => {
            $crate::lg!(crate::dbg::BooleanSlice($val));
        };
    }

    use std::fmt::{Debug, Formatter};

    #[derive(Clone)]
    pub struct Tabular<'a, T: Debug>(pub &'a [T]);
    impl<'a, T: Debug> Debug for Tabular<'a, T> {
        fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
            for i in 0..self.0.len() {
                writeln!(f, "{:2} | {:?}", i, &self.0[i])?;
            }
            Ok(())
        }
    }

    #[derive(Clone)]
    pub struct BooleanTable<'a>(pub &'a [Vec<bool>]);
    impl<'a> Debug for BooleanTable<'a> {
        fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
            for i in 0..self.0.len() {
                writeln!(f, "{:2} | {:?}", i, BooleanSlice(&self.0[i]))?;
            }
            Ok(())
        }
    }

    #[derive(Clone)]
    pub struct BooleanSlice<'a>(pub &'a [bool]);
    impl<'a> Debug for BooleanSlice<'a> {
        fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
            write!(
                f,
                "{}",
                self.0
                    .iter()
                    .map(|&b| if b { "1 " } else { "0 " })
                    .collect::<String>()
            )?;
            Ok(())
        }
    }
}
// }}}
// type_traits {{{
#[allow(dead_code)]
mod type_traits {
    #![warn(missing_docs)]

    use std::{cmp, fmt, ops};

    mod primitive {
        use super::{
            binary::{Add, Mul},
            Commut, One, OpN, Zero,
        };

        macro_rules! zero {
            (int) => {
                0
            };
            (float) => {
                0.
            };
        }
        macro_rules! one {
            (int) => {
                1
            };
            (float) => {
                1.
            };
        }
        macro_rules! num {
            (@kind $kind:ident @type $T:ty) => {
                impl Zero for $T {
                    fn zero() -> $T {
                        zero!($kind)
                    }
                }
                impl One for $T {
                    fn one() -> $T {
                        one!($kind)
                    }
                }
                impl Commut for Add<$T> {}
                impl OpN for Add<$T> {
                    fn op_n(self, n: u64) -> Self {
                        Add(self.0 * n as $T)
                    }
                }
                impl Commut for Mul<$T> {}
            };
        }

        macro_rules! int {
            ($($T:ty,)*) => {
                $( num! { @kind int @type $T } )*
            };
        }

        macro_rules! float {
            ($($T:ty,)*) => {
                $( num! { @kind float @type $T } )*
            };
        }

        int! {
            u8, u16, u32, u64, u128, usize,
            i8, i16, i32, i64, i128, isize,
        }

        float! {
            f32, f64,
        }
    }

    pub mod binary {
        use super::{Assoc, Commut, Element, Identity, One, OpN, Peek, Zero};
        use std::ops;

        macro_rules! triv_wrapper {
            ($name:ident<$T:ident>) => {
                impl<$T> Peek for $name<$T>
                where
                    $T: Element,
                {
                    type Inner = $T;
                    fn peek(&self) -> $T {
                        self.0.clone()
                    }
                }
            };
        }

        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Len<T> {
            pub len: u64,
            pub base: T,
        }
        impl<T> Len<T> {
            pub fn single(base: T) -> Self {
                Len { len: 1, base }
            }
        }
        impl<T: Assoc> Assoc for Len<T> {
            fn op(self, rhs: Self) -> Self {
                Len {
                    len: self.len + rhs.len,
                    base: self.base.op(rhs.base),
                }
            }
        }

        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Pair<T, U>(pub T, pub U);
        impl<T: Assoc, U: Assoc> Assoc for Pair<T, U> {
            fn op(self, rhs: Self) -> Self {
                Pair(self.0.op(rhs.0), self.1.op(rhs.1))
            }
        }
        impl<T: Identity, U: Identity> Identity for Pair<T, U> {
            fn identity() -> Self {
                Pair(T::identity(), U::identity())
            }
        }
        impl<T: Commut, U: Commut> Commut for Pair<T, U> {}
        impl<T: OpN, U: OpN> OpN for Pair<T, U> {
            fn op_n(self, n: u64) -> Self {
                let Pair(t, u) = self;
                Self(t.op_n(n), u.op_n(n))
            }
        }

        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
        pub struct BitXor<T>(pub T);
        triv_wrapper! { BitXor<T> }
        impl<T> Assoc for BitXor<T>
        where
            T: ops::BitXor<Output = T> + Element,
        {
            fn op(self, rhs: Self) -> Self {
                BitXor(self.0 ^ rhs.0)
            }
        }
        impl<T> Identity for BitXor<T>
        where
            T: ops::BitXor<Output = T> + Zero,
        {
            fn identity() -> Self {
                BitXor(T::zero())
            }
        }
        impl<T: ops::BitXor<Output = T> + Element> Commut for BitXor<T> {}
        impl<T: ops::BitXor<Output = T> + Zero> OpN for BitXor<T> {
            fn op_n(self, n: u64) -> Self {
                if n % 2 == 0 {
                    Self::identity()
                } else {
                    self
                }
            }
        }

        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Add<T>(pub T);
        triv_wrapper! { Add<T> }
        impl<T> Assoc for Add<T>
        where
            T: ops::Add<Output = T> + Element,
        {
            fn op(self, rhs: Self) -> Self {
                Add(self.0 + rhs.0)
            }
        }
        impl<T> Identity for Add<T>
        where
            T: Zero,
        {
            fn identity() -> Self {
                Add(T::zero())
            }
        }

        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Mul<T>(pub T);
        triv_wrapper! { Mul<T> }
        impl<T> Assoc for Mul<T>
        where
            T: ops::Mul<Output = T> + Element,
        {
            fn op(self, rhs: Self) -> Self {
                Mul(self.0 * rhs.0)
            }
        }
        impl<T> Identity for Mul<T>
        where
            T: One,
        {
            fn identity() -> Self {
                Mul(T::one())
            }
        }

        #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
        pub struct InvertionNumber {
            pub zero: u64,
            pub one: u64,
            pub invertion: u64,
        }
        impl Peek for InvertionNumber {
            type Inner = bool;
            fn peek(&self) -> bool {
                self.try_get_bool()
                    .expect("ビットでないものを peek するのはいけません！")
            }
        }

        impl Assoc for InvertionNumber {
            fn op(self, rhs: Self) -> Self {
                InvertionNumber {
                    zero: self.zero + rhs.zero,
                    one: self.one + rhs.one,
                    invertion: self.invertion + self.one * rhs.zero + rhs.invertion,
                }
            }
        }
        impl Identity for InvertionNumber {
            fn identity() -> Self {
                InvertionNumber::new()
            }
        }
        impl InvertionNumber {
            pub fn new() -> Self {
                InvertionNumber {
                    zero: 0,
                    one: 0,
                    invertion: 0,
                }
            }
            pub fn try_get_u8(&self) -> Option<u8> {
                self.try_get_bool().map(|b| if b { 1 } else { 0 })
            }
            pub fn try_get_bool(&self) -> Option<bool> {
                if *self == Self::bit_zero() {
                    Some(false)
                } else if *self == Self::bit_one() {
                    Some(true)
                } else {
                    None
                }
            }
            pub fn count_zeros(&self) -> u64 {
                self.zero
            }
            pub fn count_ones(&self) -> u64 {
                self.one
            }
            pub fn inversion_number(&self) -> u64 {
                self.invertion
            }
            pub fn bit_zero() -> Self {
                InvertionNumber {
                    zero: 1,
                    one: 0,
                    invertion: 0,
                }
            }
            pub fn bit_one() -> Self {
                InvertionNumber {
                    zero: 0,
                    one: 1,
                    invertion: 0,
                }
            }
            pub fn from_bool(b: bool) -> Self {
                if b {
                    Self::bit_one()
                } else {
                    Self::bit_zero()
                }
            }
            pub fn from_u8(x: u8) -> Self {
                match x {
                    0 => Self::bit_zero(),
                    1 => Self::bit_one(),
                    _ => panic!("0 でも 1 でもないものを渡すとパニックです。"),
                }
            }
        }

        #[derive(Debug, Clone, Copy, PartialEq, Eq)]
        pub struct Affine<T> {
            pub a: T,
            pub b: T,
        }
        impl<T: Element> Peek for Affine<T> {
            type Inner = (T, T);
            fn peek(&self) -> (T, T) {
                (self.a.clone(), self.b.clone())
            }
        }
        impl<T> Assoc for Affine<T>
        where
            T: ops::Add<Output = T> + Element,
            T: ops::Mul<Output = T> + Element,
        {
            fn op(self, rhs: Self) -> Self {
                Self {
                    a: self.a.clone() * rhs.a,
                    b: self.b + self.a * rhs.b,
                }
            }
        }
        impl<T> Identity for Affine<T>
        where
            T: Zero + One,
        {
            fn identity() -> Self {
                Self {
                    a: T::one(),
                    b: T::zero(),
                }
            }
        }

        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
        pub struct Cat(pub String);
        impl Peek for Cat {
            type Inner = String;
            fn peek(&self) -> String {
                self.0.clone()
            }
        }
        impl Assoc for Cat {
            fn op(self, rhs: Self) -> Self {
                Cat(self.0.chars().chain(rhs.0.chars()).collect())
            }
        }
        impl Identity for Cat {
            fn identity() -> Self {
                Cat(String::new())
            }
        }
    }

    pub mod actions {
        use super::{binary::Len, Action, Commut, OpN};

        #[derive(Debug, Clone, PartialEq, Copy)]
        pub struct Update<T>(pub T);

        impl<T: OpN> Action for Update<T> {
            type Space = Len<T>;
            fn acted(self, x: Self::Space) -> Self::Space {
                Len {
                    len: x.len,
                    base: self.0.op_n(x.len),
                }
            }
        }

        #[derive(Debug, Clone, PartialEq, Copy)]
        pub struct Adjoint<T>(pub T);

        impl<T: OpN + Commut> Action for Adjoint<T> {
            type Space = Len<T>;
            fn acted(self, x: Self::Space) -> Self::Space {
                Len {
                    len: x.len,
                    base: self.0.op_n(x.len).op(x.base),
                }
            }
        }
    }

    pub trait Element: Sized + Clone + PartialEq + fmt::Debug {}
    impl<T: Sized + Clone + PartialEq + fmt::Debug> Element for T {}

    pub trait Assoc: Element {
        fn op(self, rhs: Self) -> Self;

        fn op_from_left(&mut self, left: &Self) {
            *self = Self::op(left.clone(), self.clone());
        }

        fn op_from_right(&mut self, right: &Self) {
            *self = Self::op(self.clone(), right.clone());
        }
    }

    pub trait Identity: Assoc {
        fn identity() -> Self;
    }

    pub trait Commut: Assoc {}

    pub trait OpN: Assoc {
        fn op_n(self, n: u64) -> Self;
    }

    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
    pub struct Grade<T> {
        pub base: T,
        pub deg: usize,
    }
    impl<T: Assoc> Assoc for Grade<T> {
        fn op(self, rhs: Self) -> Self {
            Grade {
                deg: self.deg + rhs.deg,
                base: self.base.op(rhs.base),
            }
        }
    }

    pub trait Action {
        type Space: Assoc;
        fn acted(self, x: Self::Space) -> Self::Space;
    }

    pub trait Zero: ops::Add<Output = Self> + ops::AddAssign + Element {
        fn zero() -> Self;

        fn is_zero(&self) -> bool
        where
            Self: cmp::PartialEq,
        {
            self == &Self::zero()
        }
    }

    pub trait One: ops::Mul<Output = Self> + ops::MulAssign + Element {
        fn one() -> Self;

        fn is_one(&self) -> bool
        where
            Self: cmp::PartialEq,
        {
            self == &Self::one()
        }
    }

    pub trait Ring: Zero + One + ops::Neg + ops::Sub<Output = Self> + ops::SubAssign {}
    impl<T: Zero + One + ops::Neg + ops::Sub<Output = Self> + ops::SubAssign> Ring for T {}

    #[macro_export]
    macro_rules! define_constant {
        ($(#[$attr:meta])? $vis:vis type $wrapper_type:ident: $value_type:ty = $value:expr;) => {
            $(#[$attr])?
            #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
            $vis struct $wrapper_type {}

            impl Constant for $wrapper_type {
                type Output = $value_type;
                const VALUE: Self::Output = $value;
            }
        };
    }

    pub trait Peek {
        type Inner: fmt::Debug;

        fn peek(&self) -> Self::Inner;
    }

    pub trait Constant: Copy {
        type Output: Copy;

        const VALUE: Self::Output;
    }
}
// }}}
// ngtio {{{
#[allow(dead_code)]
mod ngtio {
    #![warn(missing_docs)]

    mod i {
        use std::{
            io::{self, BufRead},
            iter,
        };

        pub use multi_token::{Leaf, Parser, ParserTuple, RawTuple, Tuple, VecLen};
        pub use token::{Token, Usize1};

        pub fn with_stdin() -> Tokenizer<io::BufReader<io::Stdin>> {
            io::BufReader::new(io::stdin()).tokenizer()
        }

        pub fn with_str(src: &str) -> Tokenizer<&[u8]> {
            src.as_bytes().tokenizer()
        }

        pub struct Tokenizer<S: BufRead> {
            queue: Vec<String>, // FIXME: String のみにすると速そうです。
            scanner: S,
        }
        macro_rules! prim_method {
            ($name:ident: $T:ty) => {
#[allow(missing_docs)]
                pub fn $name(&mut self) -> $T {
                    <$T>::leaf().parse(self)
                }
            };
            ($name:ident) => {
                prim_method!($name: $name);
            };
        }
        macro_rules! prim_methods {
            ($name:ident: $T:ty; $($rest:tt)*) => {
                prim_method!($name:$T);
                prim_methods!($($rest)*);
            };
            ($name:ident; $($rest:tt)*) => {
                prim_method!($name);
                prim_methods!($($rest)*);
            };
            () => ()
        }
        impl<S: BufRead> Tokenizer<S> {
            pub fn token(&mut self) -> String {
                self.load();
                self.queue.pop().expect("入力が終了したのですが。")
            }
            pub fn new(scanner: S) -> Self {
                Self {
                    queue: Vec::new(),
                    scanner,
                }
            }
            fn load(&mut self) {
                while self.queue.is_empty() {
                    let mut s = String::new();
                    let length = self.scanner.read_line(&mut s).unwrap(); // 入力が UTF-8 でないときにエラーだそうです。
                    if length == 0 {
                        break;
                    }
                    self.queue = s.split_whitespace().rev().map(str::to_owned).collect();
                }
            }

            pub fn skip_line(&mut self) {
                assert!(
                    self.queue.is_empty(),
                    "行の途中で呼ばないでいただきたいです。現在のトークンキュー: {:?}",
                    &self.queue
                );
                self.load();
            }

            pub fn end(&mut self) {
                self.load();
                assert!(self.queue.is_empty(), "入力はまだあります！");
            }

            pub fn parse<T: Token>(&mut self) -> T::Output {
                T::parse(&self.token())
            }

            pub fn parse_collect<T: Token, B>(&mut self, n: usize) -> B
            where
                B: iter::FromIterator<T::Output>,
            {
                iter::repeat_with(|| self.parse::<T>()).take(n).collect()
            }

            pub fn tuple<T: RawTuple>(&mut self) -> <T::LeafTuple as Parser>::Output {
                T::leaf_tuple().parse(self)
            }

            pub fn vec<T: Token>(&mut self, len: usize) -> Vec<T::Output> {
                T::leaf().vec(len).parse(self)
            }

            pub fn vec_tuple<T: RawTuple>(
                &mut self,
                len: usize,
            ) -> Vec<<T::LeafTuple as Parser>::Output> {
                T::leaf_tuple().vec(len).parse(self)
            }

            pub fn vec2<T: Token>(&mut self, height: usize, width: usize) -> Vec<Vec<T::Output>> {
                T::leaf().vec(width).vec(height).parse(self)
            }

            pub fn vec2_tuple<T>(
                &mut self,
                height: usize,
                width: usize,
            ) -> Vec<Vec<<T::LeafTuple as Parser>::Output>>
            where
                T: RawTuple,
            {
                T::leaf_tuple().vec(width).vec(height).parse(self)
            }
            prim_methods! {
                u8; u16; u32; u64; u128; usize;
                i8; i16; i32; i64; i128; isize;
                char; string: String;
            }
        }

        mod token {
            use super::multi_token::Leaf;
            use std::{any, fmt, marker, str};

            pub trait Token: Sized {
                type Output;
                fn parse(s: &str) -> Self::Output;
                fn leaf() -> Leaf<Self> {
                    Leaf(marker::PhantomData)
                }
            }

            impl<T> Token for T
            where
                T: str::FromStr,
                <T as str::FromStr>::Err: fmt::Debug,
            {
                type Output = T;
                fn parse(s: &str) -> Self::Output {
                    s.parse().unwrap_or_else(|_| {
                        panic!("Parse error!: ({}: {})", s, any::type_name::<T>(),)
                    })
                }
            }

            pub struct Usize1 {}
            impl Token for Usize1 {
                type Output = usize;
                fn parse(s: &str) -> Self::Output {
                    usize::parse(s)
                        .checked_sub(1)
                        .expect("Parse error! (Zero substruction error of Usize1)")
                }
            }
        }

        mod multi_token {
            use super::{Token, Tokenizer};
            use std::{io::BufRead, iter, marker};

            pub trait Parser: Sized {
                type Output;
                fn parse<S: BufRead>(&self, server: &mut Tokenizer<S>) -> Self::Output;
                fn vec(self, len: usize) -> VecLen<Self> {
                    VecLen { len, elem: self }
                }
            }
            pub struct Leaf<T>(pub(super) marker::PhantomData<T>);
            impl<T: Token> Parser for Leaf<T> {
                type Output = T::Output;
                fn parse<S: BufRead>(&self, server: &mut Tokenizer<S>) -> T::Output {
                    server.parse::<T>()
                }
            }

            pub struct VecLen<T> {
                pub len: usize,
                pub elem: T,
            }
            impl<T: Parser> Parser for VecLen<T> {
                type Output = Vec<T::Output>;
                fn parse<S: BufRead>(&self, server: &mut Tokenizer<S>) -> Self::Output {
                    iter::repeat_with(|| self.elem.parse(server))
                        .take(self.len)
                        .collect()
                }
            }

            pub trait RawTuple {
                type LeafTuple: Parser;
                fn leaf_tuple() -> Self::LeafTuple;
            }
            pub trait ParserTuple {
                type Tuple: Parser;
                fn tuple(self) -> Self::Tuple;
            }
            pub struct Tuple<T>(pub T);
            macro_rules! impl_tuple {
                ($($t:ident: $T:ident),*) => {
                    impl<$($T),*> Parser for Tuple<($($T,)*)>
                        where
                            $($T: Parser,)*
                            {
                                type Output = ($($T::Output,)*);
#[allow(unused_variables)]
                                fn parse<S: BufRead >(&self, server: &mut Tokenizer<S>) -> Self::Output {
                                    match self {
                                        Tuple(($($t,)*)) => {
                                            ($($t.parse(server),)*)
                                        }
                                    }
                                }
                            }
                    impl<$($T: Token),*> RawTuple for ($($T,)*) {
                        type LeafTuple = Tuple<($(Leaf<$T>,)*)>;
                        fn leaf_tuple() -> Self::LeafTuple {
                            Tuple(($($T::leaf(),)*))
                        }
                    }
                    impl<$($T: Parser),*> ParserTuple for ($($T,)*) {
                        type Tuple = Tuple<($($T,)*)>;
                        fn tuple(self) -> Self::Tuple {
                            Tuple(self)
                        }
                    }
                };
            }
            impl_tuple!();
            impl_tuple!(t1: T1);
            impl_tuple!(t1: T1, t2: T2);
            impl_tuple!(t1: T1, t2: T2, t3: T3);
            impl_tuple!(t1: T1, t2: T2, t3: T3, t4: T4);
            impl_tuple!(t1: T1, t2: T2, t3: T3, t4: T4, t5: T5);
            impl_tuple!(t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6);
            impl_tuple!(t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7);
            impl_tuple!(
                t1: T1,
                t2: T2,
                t3: T3,
                t4: T4,
                t5: T5,
                t6: T6,
                t7: T7,
                t8: T8
            );
        }

        trait Scanner: BufRead + Sized {
            fn tokenizer(self) -> Tokenizer<Self> {
                Tokenizer::new(self)
            }
        }
        impl<R: BufRead> Scanner for R {}
    }

    pub use i::{with_stdin, with_str};

    pub mod prelude {
        pub use super::i::{Parser, ParserTuple, RawTuple, Token, Usize1};
    }
}
// }}}
// {{{ lazysegtree
//https://github.com/rust-lang-ja/ac-library-rs

pub mod internal_bit {
    // Skipped:
    //
    // - `bsf` = `__builtin_ctz`: is equivalent to `{integer}::trailing_zeros`

    #[allow(dead_code)]
    pub(crate) fn ceil_pow2(n: u32) -> u32 {
        32 - n.saturating_sub(1).leading_zeros()
    }

    #[cfg(test)]
    mod tests {
        #[test]
        fn ceil_pow2() {
            // https://github.com/atcoder/ac-library/blob/2088c8e2431c3f4d29a2cfabc6529fe0a0586c48/test/unittest/bit_test.cpp
            assert_eq!(0, super::ceil_pow2(0));
            assert_eq!(0, super::ceil_pow2(1));
            assert_eq!(1, super::ceil_pow2(2));
            assert_eq!(2, super::ceil_pow2(3));
            assert_eq!(2, super::ceil_pow2(4));
            assert_eq!(3, super::ceil_pow2(5));
            assert_eq!(3, super::ceil_pow2(6));
            assert_eq!(3, super::ceil_pow2(7));
            assert_eq!(3, super::ceil_pow2(8));
            assert_eq!(4, super::ceil_pow2(9));
            assert_eq!(30, super::ceil_pow2(1 << 30));
            assert_eq!(31, super::ceil_pow2((1 << 30) + 1));

            assert_eq!(32, super::ceil_pow2(u32::max_value()));
        }
    }
}
pub mod internal_type_traits {
    use std::{
        fmt,
        iter::{Product, Sum},
        ops::{
            Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
            DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
            SubAssign,
        },
    };

    // Skipped:
    //
    // - `is_signed_int_t<T>`   (probably won't be used directly in `modint.rs`)
    // - `is_unsigned_int_t<T>` (probably won't be used directly in `modint.rs`)
    // - `to_unsigned_t<T>`     (not used in `fenwicktree.rs`)

    /// Corresponds to `std::is_integral` in C++.
    // We will remove unnecessary bounds later.
    //
    // Maybe we should rename this to `PrimitiveInteger` or something, as it probably won't be used in the
    // same way as the original ACL.
    pub trait Integral:
        'static
        + Send
        + Sync
        + Copy
        + Ord
        + Not<Output = Self>
        + Add<Output = Self>
        + Sub<Output = Self>
        + Mul<Output = Self>
        + Div<Output = Self>
        + Rem<Output = Self>
        + AddAssign
        + SubAssign
        + MulAssign
        + DivAssign
        + RemAssign
        + Sum
        + Product
        + BitOr<Output = Self>
        + BitAnd<Output = Self>
        + BitXor<Output = Self>
        + BitOrAssign
        + BitAndAssign
        + BitXorAssign
        + Shl<Output = Self>
        + Shr<Output = Self>
        + ShlAssign
        + ShrAssign
        + fmt::Display
        + fmt::Debug
        + fmt::Binary
        + fmt::Octal
        + Zero
        + One
        + BoundedBelow
        + BoundedAbove
    {
    }

    /// Class that has additive identity element
    pub trait Zero {
        /// The additive identity element
        fn zero() -> Self;
    }

    /// Class that has multiplicative identity element
    pub trait One {
        /// The multiplicative identity element
        fn one() -> Self;
    }

    pub trait BoundedBelow {
        fn min_value() -> Self;
    }

    pub trait BoundedAbove {
        fn max_value() -> Self;
    }

    macro_rules! impl_integral {
    ($($ty:ty),*) => {
        $(
            impl Zero for $ty {
                #[inline]
                fn zero() -> Self {
                    0
                }
            }

            impl One for $ty {
                #[inline]
                fn one() -> Self {
                    1
                }
            }

            impl BoundedBelow for $ty {
                #[inline]
                fn min_value() -> Self {
                    Self::min_value()
                }
            }

            impl BoundedAbove for $ty {
                #[inline]
                fn max_value() -> Self {
                    Self::max_value()
                }
            }

            impl Integral for $ty {}
        )*
    };
}

    impl_integral!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
}
pub mod lazysegtree {
    use crate::internal_bit::ceil_pow2;
    use crate::Monoid;

    pub trait MapMonoid {
        type M: Monoid;
        type F: Clone;
        // type S = <Self::M as Monoid>::S;
        fn identity_element() -> <Self::M as Monoid>::S {
            Self::M::identity()
        }
        fn binary_operation(
            a: &<Self::M as Monoid>::S,
            b: &<Self::M as Monoid>::S,
        ) -> <Self::M as Monoid>::S {
            Self::M::binary_operation(a, b)
        }
        fn identity_map() -> Self::F;
        fn mapping(f: &Self::F, x: &<Self::M as Monoid>::S) -> <Self::M as Monoid>::S;
        fn composition(f: &Self::F, g: &Self::F) -> Self::F;
    }

    impl<F: MapMonoid> Default for LazySegtree<F> {
        fn default() -> Self {
            Self::new(0)
        }
    }
    impl<F: MapMonoid> LazySegtree<F> {
        pub fn new(n: usize) -> Self {
            vec![F::identity_element(); n].into()
        }
    }
    impl<F: MapMonoid> From<Vec<<F::M as Monoid>::S>> for LazySegtree<F> {
        fn from(v: Vec<<F::M as Monoid>::S>) -> Self {
            let n = v.len();
            let log = ceil_pow2(n as u32) as usize;
            let size = 1 << log;
            let mut d = vec![F::identity_element(); 2 * size];
            let lz = vec![F::identity_map(); size];
            d[size..(size + n)].clone_from_slice(&v);
            let mut ret = LazySegtree {
                n,
                size,
                log,
                d,
                lz,
            };
            for i in (1..size).rev() {
                ret.update(i);
            }
            ret
        }
    }

    impl<F: MapMonoid> LazySegtree<F> {
        pub fn set(&mut self, mut p: usize, x: <F::M as Monoid>::S) {
            assert!(p < self.n);
            p += self.size;
            for i in (1..=self.log).rev() {
                self.push(p >> i);
            }
            self.d[p] = x;
            for i in 1..=self.log {
                self.update(p >> i);
            }
        }

        pub fn get(&mut self, mut p: usize) -> <F::M as Monoid>::S {
            assert!(p < self.n);
            p += self.size;
            for i in (1..=self.log).rev() {
                self.push(p >> i);
            }
            self.d[p].clone()
        }

        pub fn prod(&mut self, mut l: usize, mut r: usize) -> <F::M as Monoid>::S {
            assert!(l <= r && r <= self.n);
            if l == r {
                return F::identity_element();
            }

            l += self.size;
            r += self.size;

            for i in (1..=self.log).rev() {
                if ((l >> i) << i) != l {
                    self.push(l >> i);
                }
                if ((r >> i) << i) != r {
                    self.push(r >> i);
                }
            }

            let mut sml = F::identity_element();
            let mut smr = F::identity_element();
            while l < r {
                if l & 1 != 0 {
                    sml = F::binary_operation(&sml, &self.d[l]);
                    l += 1;
                }
                if r & 1 != 0 {
                    r -= 1;
                    smr = F::binary_operation(&self.d[r], &smr);
                }
                l >>= 1;
                r >>= 1;
            }

            F::binary_operation(&sml, &smr)
        }

        pub fn all_prod(&self) -> <F::M as Monoid>::S {
            self.d[1].clone()
        }

        pub fn apply(&mut self, mut p: usize, f: F::F) {
            assert!(p < self.n);
            p += self.size;
            for i in (1..=self.log).rev() {
                self.push(p >> i);
            }
            self.d[p] = F::mapping(&f, &self.d[p]);
            for i in 1..=self.log {
                self.update(p >> i);
            }
        }
        pub fn apply_range(&mut self, mut l: usize, mut r: usize, f: F::F) {
            assert!(l <= r && r <= self.n);
            if l == r {
                return;
            }

            l += self.size;
            r += self.size;

            for i in (1..=self.log).rev() {
                if ((l >> i) << i) != l {
                    self.push(l >> i);
                }
                if ((r >> i) << i) != r {
                    self.push((r - 1) >> i);
                }
            }

            {
                let l2 = l;
                let r2 = r;
                while l < r {
                    if l & 1 != 0 {
                        self.all_apply(l, f.clone());
                        l += 1;
                    }
                    if r & 1 != 0 {
                        r -= 1;
                        self.all_apply(r, f.clone());
                    }
                    l >>= 1;
                    r >>= 1;
                }
                l = l2;
                r = r2;
            }

            for i in 1..=self.log {
                if ((l >> i) << i) != l {
                    self.update(l >> i);
                }
                if ((r >> i) << i) != r {
                    self.update((r - 1) >> i);
                }
            }
        }

        pub fn max_right<G>(&mut self, mut l: usize, g: G) -> usize
        where
            G: Fn(<F::M as Monoid>::S) -> bool,
        {
            assert!(l <= self.n);
            assert!(g(F::identity_element()));
            if l == self.n {
                return self.n;
            }
            l += self.size;
            for i in (1..=self.log).rev() {
                self.push(l >> i);
            }
            let mut sm = F::identity_element();
            while {
                // do
                while l % 2 == 0 {
                    l >>= 1;
                }
                if !g(F::binary_operation(&sm, &self.d[l])) {
                    while l < self.size {
                        self.push(l);
                        l *= 2;
                        let res = F::binary_operation(&sm, &self.d[l]);
                        if g(res.clone()) {
                            sm = res;
                            l += 1;
                        }
                    }
                    return l - self.size;
                }
                sm = F::binary_operation(&sm, &self.d[l]);
                l += 1;
                //while
                {
                    let l = l as isize;
                    (l & -l) != l
                }
            } {}
            self.n
        }

        pub fn min_left<G>(&mut self, mut r: usize, g: G) -> usize
        where
            G: Fn(<F::M as Monoid>::S) -> bool,
        {
            assert!(r <= self.n);
            assert!(g(F::identity_element()));
            if r == 0 {
                return 0;
            }
            r += self.size;
            for i in (1..=self.log).rev() {
                self.push((r - 1) >> i);
            }
            let mut sm = F::identity_element();
            while {
                // do
                r -= 1;
                while r > 1 && r % 2 != 0 {
                    r >>= 1;
                }
                if !g(F::binary_operation(&self.d[r], &sm)) {
                    while r < self.size {
                        self.push(r);
                        r = 2 * r + 1;
                        let res = F::binary_operation(&self.d[r], &sm);
                        if g(res.clone()) {
                            sm = res;
                            r -= 1;
                        }
                    }
                    return r + 1 - self.size;
                }
                sm = F::binary_operation(&self.d[r], &sm);
                // while
                {
                    let r = r as isize;
                    (r & -r) != r
                }
            } {}
            0
        }
    }

    pub struct LazySegtree<F>
    where
        F: MapMonoid,
    {
        n: usize,
        size: usize,
        log: usize,
        d: Vec<<F::M as Monoid>::S>,
        lz: Vec<F::F>,
    }
    impl<F> LazySegtree<F>
    where
        F: MapMonoid,
    {
        fn update(&mut self, k: usize) {
            self.d[k] = F::binary_operation(&self.d[2 * k], &self.d[2 * k + 1]);
        }
        fn all_apply(&mut self, k: usize, f: F::F) {
            self.d[k] = F::mapping(&f, &self.d[k]);
            if k < self.size {
                self.lz[k] = F::composition(&f, &self.lz[k]);
            }
        }
        fn push(&mut self, k: usize) {
            self.all_apply(2 * k, self.lz[k].clone());
            self.all_apply(2 * k + 1, self.lz[k].clone());
            self.lz[k] = F::identity_map();
        }
    }

    // TODO is it useful?
    use std::fmt::{Debug, Error, Formatter, Write};
    impl<F> Debug for LazySegtree<F>
    where
        F: MapMonoid,
        F::F: Debug,
        <F::M as Monoid>::S: Debug,
    {
        fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
            for i in 0..self.log {
                for j in 0..1 << i {
                    f.write_fmt(format_args!(
                        "{:?}[{:?}]\t",
                        self.d[(1 << i) + j],
                        self.lz[(1 << i) + j]
                    ))?;
                }
                f.write_char('\n')?;
            }
            for i in 0..self.size {
                f.write_fmt(format_args!("{:?}\t", self.d[self.size + i]))?;
            }
            Ok(())
        }
    }

    #[cfg(test)]
    mod tests {
        use crate::{LazySegtree, MapMonoid, Max};

        struct MaxAdd;
        impl MapMonoid for MaxAdd {
            type M = Max<i32>;
            type F = i32;

            fn identity_map() -> Self::F {
                0
            }

            fn mapping(&f: &i32, &x: &i32) -> i32 {
                f + x
            }

            fn composition(&f: &i32, &g: &i32) -> i32 {
                f + g
            }
        }

        #[test]
        fn test_max_add_lazy_segtree() {
            let base = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
            let n = base.len();
            let mut segtree: LazySegtree<MaxAdd> = base.clone().into();
            check_segtree(&base, &mut segtree);

            let mut segtree = LazySegtree::<MaxAdd>::new(n);
            let mut internal = vec![i32::min_value(); n];
            for i in 0..n {
                segtree.set(i, base[i]);
                internal[i] = base[i];
                check_segtree(&internal, &mut segtree);
            }

            segtree.set(6, 5);
            internal[6] = 5;
            check_segtree(&internal, &mut segtree);

            segtree.apply(5, 1);
            internal[5] += 1;
            check_segtree(&internal, &mut segtree);

            segtree.set(6, 0);
            internal[6] = 0;
            check_segtree(&internal, &mut segtree);

            segtree.apply_range(3, 8, 2);
            internal[3..8].iter_mut().for_each(|e| *e += 2);
            check_segtree(&internal, &mut segtree);
        }

        //noinspection DuplicatedCode
        fn check_segtree(base: &[i32], segtree: &mut LazySegtree<MaxAdd>) {
            let n = base.len();
            #[allow(clippy::needless_range_loop)]
            for i in 0..n {
                assert_eq!(segtree.get(i), base[i]);
            }
            for i in 0..=n {
                for j in i..=n {
                    assert_eq!(
                        segtree.prod(i, j),
                        base[i..j].iter().max().copied().unwrap_or(i32::min_value())
                    );
                }
            }
            assert_eq!(
                segtree.all_prod(),
                base.iter().max().copied().unwrap_or(i32::min_value())
            );
            for k in 0..=10 {
                let f = |x| x < k;
                for i in 0..=n {
                    assert_eq!(
                        Some(segtree.max_right(i, f)),
                        (i..=n)
                            .filter(|&j| f(base[i..j]
                                .iter()
                                .max()
                                .copied()
                                .unwrap_or(i32::min_value())))
                            .max()
                    );
                }
                for j in 0..=n {
                    assert_eq!(
                        Some(segtree.min_left(j, f)),
                        (0..=j)
                            .filter(|&i| f(base[i..j]
                                .iter()
                                .max()
                                .copied()
                                .unwrap_or(i32::min_value())))
                            .min()
                    );
                }
            }
        }
    }
}
pub mod segtree {
    use crate::internal_bit::ceil_pow2;
    use crate::internal_type_traits::{BoundedAbove, BoundedBelow, One, Zero};
    use std::cmp::{max, min};
    use std::convert::Infallible;
    use std::marker::PhantomData;
    use std::ops::{Add, Mul};

    // TODO Should I split monoid-related traits to another module?
    pub trait Monoid {
        type S: Clone;
        fn identity() -> Self::S;
        fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S;
    }

    pub struct Max<S>(Infallible, PhantomData<fn() -> S>);
    impl<S> Monoid for Max<S>
    where
        S: Copy + Ord + BoundedBelow,
    {
        type S = S;
        fn identity() -> Self::S {
            S::min_value()
        }
        fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
            max(*a, *b)
        }
    }

    pub struct Min<S>(Infallible, PhantomData<fn() -> S>);
    impl<S> Monoid for Min<S>
    where
        S: Copy + Ord + BoundedAbove,
    {
        type S = S;
        fn identity() -> Self::S {
            S::max_value()
        }
        fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
            min(*a, *b)
        }
    }

    pub struct Additive<S>(Infallible, PhantomData<fn() -> S>);
    impl<S> Monoid for Additive<S>
    where
        S: Copy + Add<Output = S> + Zero,
    {
        type S = S;
        fn identity() -> Self::S {
            S::zero()
        }
        fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
            *a + *b
        }
    }

    pub struct Multiplicative<S>(Infallible, PhantomData<fn() -> S>);
    impl<S> Monoid for Multiplicative<S>
    where
        S: Copy + Mul<Output = S> + One,
    {
        type S = S;
        fn identity() -> Self::S {
            S::one()
        }
        fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
            *a * *b
        }
    }

    impl<M: Monoid> Default for Segtree<M> {
        fn default() -> Self {
            Segtree::new(0)
        }
    }
    impl<M: Monoid> Segtree<M> {
        pub fn new(n: usize) -> Segtree<M> {
            vec![M::identity(); n].into()
        }
    }
    impl<M: Monoid> From<Vec<M::S>> for Segtree<M> {
        fn from(v: Vec<M::S>) -> Self {
            let n = v.len();
            let log = ceil_pow2(n as u32) as usize;
            let size = 1 << log;
            let mut d = vec![M::identity(); 2 * size];
            d[size..(size + n)].clone_from_slice(&v);
            let mut ret = Segtree { n, size, log, d };
            for i in (1..size).rev() {
                ret.update(i);
            }
            ret
        }
    }
    impl<M: Monoid> Segtree<M> {
        pub fn set(&mut self, mut p: usize, x: M::S) {
            assert!(p < self.n);
            p += self.size;
            self.d[p] = x;
            for i in 1..=self.log {
                self.update(p >> i);
            }
        }

        pub fn get(&self, p: usize) -> M::S {
            assert!(p < self.n);
            self.d[p + self.size].clone()
        }

        pub fn prod(&self, mut l: usize, mut r: usize) -> M::S {
            assert!(l <= r && r <= self.n);
            let mut sml = M::identity();
            let mut smr = M::identity();
            l += self.size;
            r += self.size;

            while l < r {
                if l & 1 != 0 {
                    sml = M::binary_operation(&sml, &self.d[l]);
                    l += 1;
                }
                if r & 1 != 0 {
                    r -= 1;
                    smr = M::binary_operation(&self.d[r], &smr);
                }
                l >>= 1;
                r >>= 1;
            }

            M::binary_operation(&sml, &smr)
        }

        pub fn all_prod(&self) -> M::S {
            self.d[1].clone()
        }

        pub fn max_right<F>(&self, mut l: usize, f: F) -> usize
        where
            F: Fn(&M::S) -> bool,
        {
            assert!(l <= self.n);
            assert!(f(&M::identity()));
            if l == self.n {
                return self.n;
            }
            l += self.size;
            let mut sm = M::identity();
            while {
                // do
                while l % 2 == 0 {
                    l >>= 1;
                }
                if !f(&M::binary_operation(&sm, &self.d[l])) {
                    while l < self.size {
                        l *= 2;
                        let res = M::binary_operation(&sm, &self.d[l]);
                        if f(&res) {
                            sm = res;
                            l += 1;
                        }
                    }
                    return l - self.size;
                }
                sm = M::binary_operation(&sm, &self.d[l]);
                l += 1;
                // while
                {
                    let l = l as isize;
                    (l & -l) != l
                }
            } {}
            self.n
        }

        pub fn min_left<F>(&self, mut r: usize, f: F) -> usize
        where
            F: Fn(&M::S) -> bool,
        {
            assert!(r <= self.n);
            assert!(f(&M::identity()));
            if r == 0 {
                return 0;
            }
            r += self.size;
            let mut sm = M::identity();
            while {
                // do
                r -= 1;
                while r > 1 && r % 2 == 1 {
                    r >>= 1;
                }
                if !f(&M::binary_operation(&self.d[r], &sm)) {
                    while r < self.size {
                        r = 2 * r + 1;
                        let res = M::binary_operation(&self.d[r], &sm);
                        if f(&res) {
                            sm = res;
                            r -= 1;
                        }
                    }
                    return r + 1 - self.size;
                }
                sm = M::binary_operation(&self.d[r], &sm);
                // while
                {
                    let r = r as isize;
                    (r & -r) != r
                }
            } {}
            0
        }

        fn update(&mut self, k: usize) {
            self.d[k] = M::binary_operation(&self.d[2 * k], &self.d[2 * k + 1]);
        }
    }

    // Maybe we can use this someday
    // ```
    // for i in 0..=self.log {
    //     for j in 0..1 << i {
    //         print!("{}\t", self.d[(1 << i) + j]);
    //     }
    //     println!();
    // }
    // ```

    pub struct Segtree<M>
    where
        M: Monoid,
    {
        // variable name is _n in original library
        n: usize,
        size: usize,
        log: usize,
        d: Vec<M::S>,
    }

    #[cfg(test)]
    mod tests {
        use crate::segtree::Max;
        use crate::Segtree;

        #[test]
        fn test_max_segtree() {
            let base = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
            let n = base.len();
            let segtree: Segtree<Max<_>> = base.clone().into();
            check_segtree(&base, &segtree);

            let mut segtree = Segtree::<Max<_>>::new(n);
            let mut internal = vec![i32::min_value(); n];
            for i in 0..n {
                segtree.set(i, base[i]);
                internal[i] = base[i];
                check_segtree(&internal, &segtree);
            }

            segtree.set(6, 5);
            internal[6] = 5;
            check_segtree(&internal, &segtree);

            segtree.set(6, 0);
            internal[6] = 0;
            check_segtree(&internal, &segtree);
        }

        //noinspection DuplicatedCode
        fn check_segtree(base: &[i32], segtree: &Segtree<Max<i32>>) {
            let n = base.len();
            #[allow(clippy::needless_range_loop)]
            for i in 0..n {
                assert_eq!(segtree.get(i), base[i]);
            }
            for i in 0..=n {
                for j in i..=n {
                    assert_eq!(
                        segtree.prod(i, j),
                        base[i..j].iter().max().copied().unwrap_or(i32::min_value())
                    );
                }
            }
            assert_eq!(
                segtree.all_prod(),
                base.iter().max().copied().unwrap_or(i32::min_value())
            );
            for k in 0..=10 {
                let f = |&x: &i32| x < k;
                for i in 0..=n {
                    assert_eq!(
                        Some(segtree.max_right(i, f)),
                        (i..=n)
                            .filter(|&j| f(&base[i..j]
                                .iter()
                                .max()
                                .copied()
                                .unwrap_or(i32::min_value())))
                            .max()
                    );
                }
                for j in 0..=n {
                    assert_eq!(
                        Some(segtree.min_left(j, f)),
                        (0..=j)
                            .filter(|&i| f(&base[i..j]
                                .iter()
                                .max()
                                .copied()
                                .unwrap_or(i32::min_value())))
                            .min()
                    );
                }
            }
        }
    }
}
use lazysegtree::*;
use segtree::*;
// }}}