QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#659415#9486. Random Mexucup-team296#AC ✓1675ms526416kbRust49.0kb2024-10-19 20:05:342024-10-19 20:05:34

Judging History

你现在查看的是最新测评结果

  • [2024-10-19 20:05:34]
  • 评测
  • 测评结果:AC
  • 用时:1675ms
  • 内存:526416kb
  • [2024-10-19 20:05:34]
  • 提交

answer

// https://contest.ucup.ac/contest/1812/problem/9486
pub mod solution {
//{"name":"K. Random Mex","group":"Universal Cup - The 3rd Universal Cup. Stage 13: Sendai","url":"https://contest.ucup.ac/contest/1812/problem/9486","interactive":false,"timeLimit":1000,"tests":[{"input":"4\n3 2\n1 1\n20 23\n8000 8000\n","output":"374341634\n1\n111675632\n994279778\n"}],"testType":"single","input":{"type":"stdin","fileName":null,"pattern":null},"output":{"type":"stdout","fileName":null,"pattern":null},"languages":{"java":{"taskClass":"KRandomMex"}}}

use crate::algo_lib::collections::md_arr::arr2d::Arr2d;
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::output::Output;
// use algo_lib::misc::extensions::do_with::DoWith;
use crate::algo_lib::collections::slice_ext::indices::Indices;
use crate::algo_lib::misc::test_type::TaskType;
use crate::algo_lib::misc::test_type::TestType;
use crate::algo_lib::misc::value::Value;
use crate::algo_lib::numbers::mod_int::ModIntF;
use crate::algo_lib::numbers::mod_int::ValF;
use crate::algo_lib::numbers::mod_utils::Combinations;
use crate::algo_lib::numbers::num_traits::algebra::One;
use crate::algo_lib::numbers::num_traits::algebra::Zero;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use crate::algo_lib::numbers::number_ext::Power;
use std::collections::HashMap;
use std::mem::transmute;
// use algo_lib::numbers::prime_fft::PrimeFFT;

type PreCalc = ();

fn solve(input: &mut Input, out: &mut Output, _test_case: usize, _data: &mut PreCalc) {
    let t = input.read_size();
    let queries = input.read_size_pair_vec(t);

    type Mod = ModIntF;
    let cc = Combinations::<Mod>::new(8001);
    /*let at = vec![Vec::new(); 8001].do_with(|at| {
        for (i, (n, m)) in queries.into_iter().enumerate() {
            at[m].push((n, i));
        }
    });
    let mut ans = vec![Mod::zero(); t];
    let mut a = vec![Mod::zero(); 8001];
    let mut b = vec![Mod::zero(); 8001];
    let mut c = vec![Mod::zero(); 8001];
    let mut fft = PrimeFFT::new();
    let mut d = Arr2d::new(20, 20, 0);
    for m in 1..=20 {
        // if m % 500 == 0 {
        //     eprintln!("m = {}", m);
        // }
        let mut mult = Mod::one();
        let mut by = Mod::from_index(m - 1) / Mod::from_index(m);
        for i in 0..=8000 {
            a[i] = (c[i] + Mod::one()) * mult * cc.inv_fact(i);
            mult *= by;
        }
        mult = Mod::one();
        by = Mod::one() - by;
        for i in 1..=8000 {
            mult *= by;
            b[i] = mult * cc.inv_fact(i);
        }
        fft.multiply_res(&a, &b, &mut c);
        for i in 0..=8000 {
            c[i] = c[i] * cc.fact(i);
        }
        for i in 0..20 {
            d[(m - 1, i)] = (c[i] * Mod::from_index(m).power(i)).val();
        }
        for (n, i) in at[m].iter() {
            ans[*i] = c[*n];
        }
    }

    for i in 0..20 {
        for j in 0..20 {
            eprint!("{} ", d[(j, i)]);
        }
        eprintln!();
    }*/
    let mut a = Arr2d::new(8001, 8001, Mod::zero());
    for m in 1..=8000 {
        a[(m, 0)] = Mod::from_index(m);
        let im = Mod::from_index(m).inv().unwrap();
        for q in 1..m {
            a[(m, q)] = Mod::from_index(m - q) * im * (Mod::one() + a[(m - 1, q)]);
        }
    }
    for m in 1..=8000 {
        for q in 0..=m {
            a[(m, q)] *= cc.c(m, q);
        }
    }
    let mut b = Arr2d::new(8001, 8001, Mod::zero());
    b[(0, 0)] = Mod::one();
    for n in 1..=8000 {
        for p in 1..=n {
            b[(n, p)] = Mod::from_index(p) * (b[(n - 1, p - 1)] + b[(n - 1, p)]);
        }
    }
    for n in 0..=8000 {
        b[n].reverse();
    }
    // let mut c = Arr2d::new(8001, 8001, Mod::zero());
    // for i in 1..=8000 {
    //     c[(i, 0)] = Mod::one();
    //     let by = Mod::from_index(i).inv().unwrap();
    //     for j in 1..=800 {
    //         c[(i, j)] = c[(i, j - 1)] * by;
    //     }
    // }
    let mut cache = HashMap::<(usize, usize), Mod>::new();
    let a: Arr2d<i32> = unsafe { transmute(a) };
    let b: Arr2d<i32> = unsafe { transmute(b) };

    fn multiply(a: &[i32], b: &[i32]) -> i128 {
        let mut res = 0;
        for i in a.indices() {
            res += ((a[i] as i64) * (b[i] as i64)) as i128;
        }
        res
    }

    const THRESHOLD: u64 = 998_244_353u64 * 17_000_000_000;
    for (n, m) in queries {
        if let Some(val) = cache.get(&(n, m)) {
            out.print_line(*val);
            continue;
        }
        let mut res = 0;
        let mut add = 0;
        // let mut done = 0;
        let aa = &a[m];
        let bb = &b[n][8000 - m..];
        let res = multiply(&aa[m.max(n) - n..m], &bb[m.max(n) - n..m]);
        // for z in m.max(n) - n..m {
        // eprintln!(
        //     "{} {} {} {:?} {:?} {:?}",
        //     n,
        //     m,
        //     z,
        //     a[(m, z)],
        //     b[(n, m - z)],
        //     c[(m - z, n)]
        // );
        // res += ((a[(m, z)].val() as u64) * (b[(n, m - z)].val() as u64));
        // if res >= THRESHOLD {
        //     res -= THRESHOLD;
        // }
        // let xx;
        // (res, xx) =
        //     res.overflowing_add((a[(m, z)].val() as i64) * (b[(n, m - z)].val() as i64));
        // add += xx as i32;
        // res += ((aa[z] as i64) * (bb[z] as i64)) as i128;
        // done += 1;
        // if done == 18 {
        //     res %= ValF::val() as u64;
        //     done = 0;
        // }
        // }
        // let mut res = Mod::new((res % ValF::val() as u64) as i32);
        let mut res =
            Mod::new(((res as i128 + ((add as i128) << 64)) % ValF::val() as i128) as i32);
        res /= Mod::from_index(m).power(n);
        out.print_line(res);
        cache.insert((n, m), res);
        // return;
    }
}

#[cfg(test)]
mod test {
use crate::algo_lib::collections::md_arr::arr2d::Arr2d;
use crate::algo_lib::numbers::mod_int::ModIntF;
use crate::algo_lib::numbers::num_traits::algebra::Zero;

    #[test]
    fn test() {
        type Mod = ModIntF;

        let mut b = Arr2d::new(20, 20, Mod::zero());
    }
}

pub static TEST_TYPE: TestType = TestType::Single;
pub static TASK_TYPE: TaskType = TaskType::Classic;

pub(crate) fn run(mut input: Input, mut output: Output) -> bool {
    let mut pre_calc = ();

    match TEST_TYPE {
        TestType::Single => solve(&mut input, &mut output, 1, &mut pre_calc),
        TestType::MultiNumber => {
            let t = input.read();
            for i in 1..=t {
                solve(&mut input, &mut output, i, &mut pre_calc);
            }
        }
        TestType::MultiEof => {
            let mut i = 1;
            while input.peek().is_some() {
                solve(&mut input, &mut output, i, &mut pre_calc);
                i += 1;
            }
        }
    }
    output.flush();
    match TASK_TYPE {
        TaskType::Classic => input.is_empty(),
        TaskType::Interactive => true,
    }
}

}
pub mod algo_lib {
pub mod collections {
pub mod md_arr {
pub mod arr2d {
use crate::algo_lib::collections::slice_ext::legacy_fill::LegacyFill;
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::input::Readable;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::io::output::Writable;
use std::mem::MaybeUninit;
use std::ops::Index;
use std::ops::IndexMut;
use std::ops::Range;
use std::slice::Iter;
use std::vec::IntoIter;

#[derive(Clone, Eq, PartialEq, Default)]
pub struct Arr2d<T> {
    d1: usize,
    d2: usize,
    data: Vec<T>,
}

impl<T: Clone> Arr2d<T> {
    pub fn new(d1: usize, d2: usize, value: T) -> Self {
        Self {
            d1,
            d2,
            data: vec![value; d1 * d2],
        }
    }
}

impl<T> Arr2d<T> {
    pub fn generate<F>(d1: usize, d2: usize, mut gen: F) -> Self
    where
        F: FnMut(usize, usize) -> T,
    {
        let mut data = Vec::with_capacity(d1 * d2);
        for i in 0usize..d1 {
            for j in 0usize..d2 {
                data.push(gen(i, j));
            }
        }
        Self { d1, d2, data }
    }

    pub fn d1(&self) -> usize {
        self.d1
    }

    pub fn d2(&self) -> usize {
        self.d2
    }

    pub fn iter(&self) -> Iter<'_, T> {
        self.data.iter()
    }

    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
        self.data.iter_mut()
    }

    pub fn row(&self, row: usize) -> impl Iterator<Item = &T> {
        assert!(row < self.d1);
        self.data.iter().skip(row * self.d2).take(self.d2)
    }

    pub fn row_mut(&mut self, row: usize) -> impl Iterator<Item = &mut T> {
        assert!(row < self.d1);
        self.data.iter_mut().skip(row * self.d2).take(self.d2)
    }

    pub fn column(&self, col: usize) -> impl Iterator<Item = &T> {
        assert!(col < self.d2);
        self.data.iter().skip(col).step_by(self.d2)
    }

    pub fn column_mut(&mut self, col: usize) -> impl Iterator<Item = &mut T> {
        assert!(col < self.d2);
        self.data.iter_mut().skip(col).step_by(self.d2)
    }

    pub fn swap(&mut self, r1: usize, c1: usize, r2: usize, c2: usize) {
        assert!(r1 < self.d1);
        assert!(r2 < self.d1);
        assert!(c1 < self.d2);
        assert!(c2 < self.d2);
        self.data.swap(r1 * self.d2 + c1, r2 * self.d2 + c2);
    }

    pub fn rows(&self) -> Range<usize> {
        0..self.d1
    }

    pub fn cols(&self) -> Range<usize> {
        0..self.d2
    }

    pub fn swap_rows(&mut self, r1: usize, r2: usize) {
        assert!(r1 < self.d1);
        assert!(r2 < self.d1);
        if r1 == r2 {
            return;
        }
        let (r1, r2) = (r1.min(r2), r1.max(r2));
        let (head, tail) = self.data.split_at_mut(r2 * self.d2);
        head[r1 * self.d2..(r1 + 1) * self.d2].swap_with_slice(&mut tail[..self.d2]);
    }

    pub fn rotate_clockwise(self) -> Self {
        unsafe {
            let d1 = self.d1;
            let d2 = self.d2;
            let mut res = MaybeUninit::new(Vec::with_capacity(d1 * d2));
            (*res.as_mut_ptr()).set_len(d1 * d2);
            for (id, element) in self.into_iter().enumerate() {
                let (i, j) = (id / d2, id % d2);
                let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
                ptr.add(j * d1 + d1 - i - 1).write(element);
            }
            Self {
                d1: d2,
                d2: d1,
                data: res.assume_init(),
            }
        }
    }

    pub fn rotate_counterclockwise(self) -> Self {
        unsafe {
            let d1 = self.d1;
            let d2 = self.d2;
            let mut res = MaybeUninit::new(Vec::with_capacity(d1 * d2));
            (*res.as_mut_ptr()).set_len(d1 * d2);
            for (id, element) in self.into_iter().enumerate() {
                let (i, j) = (id / d2, id % d2);
                let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
                ptr.add((d2 - j - 1) * d1 + i).write(element);
            }
            Self {
                d1: d2,
                d2: d1,
                data: res.assume_init(),
            }
        }
    }
}

impl<T: Clone> Arr2d<T> {
    pub fn fill(&mut self, elem: T) {
        self.data.legacy_fill(elem);
    }

    pub fn transpose(&self) -> Self {
        Self::generate(self.d2, self.d1, |i, j| self[(j, i)].clone())
    }
}

impl<T> Index<(usize, usize)> for Arr2d<T> {
    type Output = T;

    fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
        assert!(row < self.d1);
        assert!(col < self.d2);
        &self.data[self.d2 * row + col]
    }
}

impl<T> Index<usize> for Arr2d<T> {
    type Output = [T];

    fn index(&self, index: usize) -> &Self::Output {
        &self.data[self.d2 * index..self.d2 * (index + 1)]
    }
}

impl<T> IndexMut<(usize, usize)> for Arr2d<T> {
    fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut T {
        assert!(row < self.d1);
        assert!(col < self.d2);
        &mut self.data[self.d2 * row + col]
    }
}

impl<T> IndexMut<usize> for Arr2d<T> {
    fn index_mut(&mut self, index: usize) -> &mut [T] {
        &mut self.data[self.d2 * index..self.d2 * (index + 1)]
    }
}

impl<T> AsRef<Vec<T>> for Arr2d<T> {
    fn as_ref(&self) -> &Vec<T> {
        &self.data
    }
}

impl<T> AsMut<Vec<T>> for Arr2d<T> {
    fn as_mut(&mut self) -> &mut Vec<T> {
        &mut self.data
    }
}

impl<T: Writable> Writable for Arr2d<T> {
    fn write(&self, output: &mut Output) {
        let mut at = 0usize;
        for i in 0usize..self.d1 {
            if i != 0 {
                output.put(b'\n');
            }
            for j in 0usize..self.d2 {
                if j != 0 {
                    output.put(b' ');
                }
                self.data[at].write(output);
                at += 1;
            }
        }
    }
}

impl<T> IntoIterator for Arr2d<T> {
    type Item = T;
    type IntoIter = IntoIter<T>;

    fn into_iter(self) -> Self::IntoIter {
        self.data.into_iter()
    }
}

impl<'a, T> IntoIterator for &'a Arr2d<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

pub trait Arr2dRead {
    fn read_table<T: Readable>(&mut self, d1: usize, d2: usize) -> Arr2d<T>;
    fn read_int_table(&mut self, d1: usize, d2: usize) -> Arr2d<i32>;
    fn read_long_table(&mut self, d1: usize, d2: usize) -> Arr2d<i64>;
    fn read_size_table(&mut self, d1: usize, d2: usize) -> Arr2d<usize>;
    fn read_char_table(&mut self, d1: usize, d2: usize) -> Arr2d<u8>;
}

impl Arr2dRead for Input<'_> {
    fn read_table<T: Readable>(&mut self, d1: usize, d2: usize) -> Arr2d<T> {
        Arr2d::generate(d1, d2, |_, _| self.read())
    }

    fn read_int_table(&mut self, d1: usize, d2: usize) -> Arr2d<i32> {
        self.read_table(d1, d2)
    }

    fn read_long_table(&mut self, d1: usize, d2: usize) -> Arr2d<i64> {
        self.read_table(d1, d2)
    }

    fn read_size_table(&mut self, d1: usize, d2: usize) -> Arr2d<usize> {
        self.read_table(d1, d2)
    }

    fn read_char_table(&mut self, d1: usize, d2: usize) -> Arr2d<u8> {
        self.read_table(d1, d2)
    }
}

pub trait Arr2dCharWrite {
    fn print_table(&mut self, table: &Arr2d<u8>);
}

impl Arr2dCharWrite for Output<'_> {
    fn print_table(&mut self, table: &Arr2d<u8>) {
        let mut at = 0usize;
        for _ in 0..table.d1 {
            for _ in 0..table.d2 {
                self.put(table.data[at]);
                at += 1;
            }
            self.put(b'\n');
        }
        self.maybe_flush();
    }
}

impl<T: Readable> Readable for Arr2d<T> {
    fn read(input: &mut Input) -> Self {
        let d1 = input.read();
        let d2 = input.read();
        input.read_table(d1, d2)
    }
}
}
}
pub mod slice_ext {
pub mod indices {
use std::ops::Range;

pub trait Indices {
    fn indices(&self) -> Range<usize>;
}

impl<T> Indices for [T] {
    fn indices(&self) -> Range<usize> {
        0..self.len()
    }
}
}
pub mod legacy_fill {
// 1.50
pub trait LegacyFill<T> {
    fn legacy_fill(&mut self, val: T);
}

impl<T: Clone> LegacyFill<T> for [T] {
    fn legacy_fill(&mut self, val: T) {
        for el in self.iter_mut() {
            *el = val.clone();
        }
    }
}
}
}
pub mod vec_ext {
pub mod default {
pub fn default_vec<T: Default>(len: usize) -> Vec<T> {
    let mut v = Vec::with_capacity(len);
    for _ in 0..len {
        v.push(T::default());
    }
    v
}
}
}
}
pub mod io {
pub mod input {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use std::io::Read;

pub struct Input<'s> {
    input: &'s mut (dyn Read + Send),
    buf: Vec<u8>,
    at: usize,
    buf_read: usize,
}

macro_rules! read_impl {
    ($t: ty, $read_name: ident, $read_vec_name: ident) => {
        pub fn $read_name(&mut self) -> $t {
            self.read()
        }

        pub fn $read_vec_name(&mut self, len: usize) -> Vec<$t> {
            self.read_vec(len)
        }
    };

    ($t: ty, $read_name: ident, $read_vec_name: ident, $read_pair_vec_name: ident) => {
        read_impl!($t, $read_name, $read_vec_name);

        pub fn $read_pair_vec_name(&mut self, len: usize) -> Vec<($t, $t)> {
            self.read_vec(len)
        }
    };
}

impl<'s> Input<'s> {
    const DEFAULT_BUF_SIZE: usize = 4096;

    pub fn new(input: &'s mut (dyn Read + Send)) -> Self {
        Self {
            input,
            buf: default_vec(Self::DEFAULT_BUF_SIZE),
            at: 0,
            buf_read: 0,
        }
    }

    pub fn new_with_size(input: &'s mut (dyn Read + Send), buf_size: usize) -> Self {
        Self {
            input,
            buf: default_vec(buf_size),
            at: 0,
            buf_read: 0,
        }
    }

    pub fn get(&mut self) -> Option<u8> {
        if self.refill_buffer() {
            let res = self.buf[self.at];
            self.at += 1;
            if res == b'\r' {
                if self.refill_buffer() && self.buf[self.at] == b'\n' {
                    self.at += 1;
                }
                return Some(b'\n');
            }
            Some(res)
        } else {
            None
        }
    }

    pub fn peek(&mut self) -> Option<u8> {
        if self.refill_buffer() {
            let res = self.buf[self.at];
            Some(if res == b'\r' { b'\n' } else { res })
        } else {
            None
        }
    }

    pub fn skip_whitespace(&mut self) {
        while let Some(b) = self.peek() {
            if !b.is_ascii_whitespace() {
                return;
            }
            self.get();
        }
    }

    pub fn next_token(&mut self) -> Option<Vec<u8>> {
        self.skip_whitespace();
        let mut res = Vec::new();
        while let Some(c) = self.get() {
            if c.is_ascii_whitespace() {
                break;
            }
            res.push(c);
        }
        if res.is_empty() {
            None
        } else {
            Some(res)
        }
    }

    //noinspection RsSelfConvention
    pub fn is_exhausted(&mut self) -> bool {
        self.peek().is_none()
    }

    //noinspection RsSelfConvention
    pub fn is_empty(&mut self) -> bool {
        self.skip_whitespace();
        self.is_exhausted()
    }

    pub fn read<T: Readable>(&mut self) -> T {
        T::read(self)
    }

    pub fn read_vec<T: Readable>(&mut self, size: usize) -> Vec<T> {
        let mut res = Vec::with_capacity(size);
        for _ in 0..size {
            res.push(self.read());
        }
        res
    }

    pub fn read_char(&mut self) -> u8 {
        self.skip_whitespace();
        self.get().unwrap()
    }

    read_impl!(u32, read_unsigned, read_unsigned_vec);
    read_impl!(u64, read_u64, read_u64_vec);
    read_impl!(usize, read_size, read_size_vec, read_size_pair_vec);
    read_impl!(i32, read_int, read_int_vec, read_int_pair_vec);
    read_impl!(i64, read_long, read_long_vec, read_long_pair_vec);
    read_impl!(i128, read_i128, read_i128_vec);

    fn refill_buffer(&mut self) -> bool {
        if self.at == self.buf_read {
            self.at = 0;
            self.buf_read = self.input.read(&mut self.buf).unwrap();
            self.buf_read != 0
        } else {
            true
        }
    }
}

pub trait Readable {
    fn read(input: &mut Input) -> Self;
}

impl Readable for u8 {
    fn read(input: &mut Input) -> Self {
        input.read_char()
    }
}

impl<T: Readable> Readable for Vec<T> {
    fn read(input: &mut Input) -> Self {
        let size = input.read();
        input.read_vec(size)
    }
}

macro_rules! read_integer {
    ($($t:ident)+) => {$(
        impl Readable for $t {
            fn read(input: &mut Input) -> Self {
                input.skip_whitespace();
                let mut c = input.get().unwrap();
                let sgn = match c {
                    b'-' => {
                        c = input.get().unwrap();
                        true
                    }
                    b'+' => {
                        c = input.get().unwrap();
                        false
                    }
                    _ => false,
                };
                let mut res = 0;
                loop {
                    assert!(c.is_ascii_digit());
                    res *= 10;
                    let d = (c - b'0') as $t;
                    if sgn {
                        res -= d;
                    } else {
                        res += d;
                    }
                    match input.get() {
                        None => break,
                        Some(ch) => {
                            if ch.is_ascii_whitespace() {
                                break;
                            } else {
                                c = ch;
                            }
                        }
                    }
                }
                res
            }
        }
    )+};
}

read_integer!(i8 i16 i32 i64 i128 isize u16 u32 u64 u128 usize);

macro_rules! tuple_readable {
    ($($name:ident)+) => {
        impl<$($name: Readable), +> Readable for ($($name,)+) {
            fn read(input: &mut Input) -> Self {
                ($($name::read(input),)+)
            }
        }
    }
}

tuple_readable! {T}
tuple_readable! {T U}
tuple_readable! {T U V}
tuple_readable! {T U V X}
tuple_readable! {T U V X Y}
tuple_readable! {T U V X Y Z}
tuple_readable! {T U V X Y Z A}
tuple_readable! {T U V X Y Z A B}
tuple_readable! {T U V X Y Z A B C}
tuple_readable! {T U V X Y Z A B C D}
tuple_readable! {T U V X Y Z A B C D E}
tuple_readable! {T U V X Y Z A B C D E F}

impl Read for Input<'_> {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        if self.at == self.buf_read {
            self.input.read(buf)
        } else {
            let mut i = 0;
            while i < buf.len() && self.at < self.buf_read {
                buf[i] = self.buf[self.at];
                i += 1;
                self.at += 1;
            }
            Ok(i)
        }
    }
}
}
pub mod output {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use std::cmp::Reverse;
use std::io::stderr;
use std::io::Stderr;
use std::io::Write;

#[derive(Copy, Clone)]
pub enum BoolOutput {
    YesNo,
    YesNoCaps,
    PossibleImpossible,
    Custom(&'static str, &'static str),
}

impl BoolOutput {
    pub fn output(&self, output: &mut Output, val: bool) {
        (if val { self.yes() } else { self.no() }).write(output);
    }

    fn yes(&self) -> &str {
        match self {
            BoolOutput::YesNo => "Yes",
            BoolOutput::YesNoCaps => "YES",
            BoolOutput::PossibleImpossible => "Possible",
            BoolOutput::Custom(yes, _) => yes,
        }
    }

    fn no(&self) -> &str {
        match self {
            BoolOutput::YesNo => "No",
            BoolOutput::YesNoCaps => "NO",
            BoolOutput::PossibleImpossible => "Impossible",
            BoolOutput::Custom(_, no) => no,
        }
    }
}

pub struct Output<'s> {
    output: &'s mut dyn Write,
    buf: Vec<u8>,
    at: usize,
    auto_flush: bool,
    bool_output: BoolOutput,
}

impl<'s> Output<'s> {
    const DEFAULT_BUF_SIZE: usize = 4096;

    pub fn new(output: &'s mut dyn Write) -> Self {
        Self {
            output,
            buf: default_vec(Self::DEFAULT_BUF_SIZE),
            at: 0,
            auto_flush: false,
            bool_output: BoolOutput::YesNoCaps,
        }
    }

    pub fn new_with_auto_flush(output: &'s mut dyn Write) -> Self {
        Self {
            output,
            buf: default_vec(Self::DEFAULT_BUF_SIZE),
            at: 0,
            auto_flush: true,
            bool_output: BoolOutput::YesNoCaps,
        }
    }

    pub fn flush(&mut self) {
        if self.at != 0 {
            self.output.write_all(&self.buf[..self.at]).unwrap();
            self.output.flush().unwrap();
            self.at = 0;
        }
    }

    pub fn print<T: Writable>(&mut self, s: T) {
        s.write(self);
        self.maybe_flush();
    }

    pub fn print_line<T: Writable>(&mut self, s: T) {
        self.print(s);
        self.put(b'\n');
        self.maybe_flush();
    }

    pub fn put(&mut self, b: u8) {
        self.buf[self.at] = b;
        self.at += 1;
        if self.at == self.buf.len() {
            self.flush();
        }
    }

    pub fn maybe_flush(&mut self) {
        if self.auto_flush {
            self.flush();
        }
    }

    pub fn print_per_line<T: Writable>(&mut self, arg: &[T]) {
        self.print_per_line_iter(arg.iter());
    }

    pub fn print_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
        let mut first = true;
        for e in iter {
            if first {
                first = false;
            } else {
                self.put(b' ');
            }
            e.write(self);
        }
    }

    pub fn print_line_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
        self.print_iter(iter);
        self.put(b'\n');
    }

    pub fn print_per_line_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
        for e in iter {
            e.write(self);
            self.put(b'\n');
        }
    }

    pub fn set_bool_output(&mut self, bool_output: BoolOutput) {
        self.bool_output = bool_output;
    }
}

impl Write for Output<'_> {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        let mut start = 0usize;
        let mut rem = buf.len();
        while rem > 0 {
            let len = (self.buf.len() - self.at).min(rem);
            self.buf[self.at..self.at + len].copy_from_slice(&buf[start..start + len]);
            self.at += len;
            if self.at == self.buf.len() {
                self.flush();
            }
            start += len;
            rem -= len;
        }
        self.maybe_flush();
        Ok(buf.len())
    }

    fn flush(&mut self) -> std::io::Result<()> {
        self.flush();
        Ok(())
    }
}

pub trait Writable {
    fn write(&self, output: &mut Output);
}

impl Writable for &str {
    fn write(&self, output: &mut Output) {
        output.write_all(self.as_bytes()).unwrap();
    }
}

impl Writable for String {
    fn write(&self, output: &mut Output) {
        output.write_all(self.as_bytes()).unwrap();
    }
}

impl Writable for char {
    fn write(&self, output: &mut Output) {
        output.put(*self as u8);
    }
}

impl Writable for u8 {
    fn write(&self, output: &mut Output) {
        output.put(*self);
    }
}

impl<T: Writable> Writable for [T] {
    fn write(&self, output: &mut Output) {
        output.print_iter(self.iter());
    }
}

impl<T: Writable, const N: usize> Writable for [T; N] {
    fn write(&self, output: &mut Output) {
        output.print_iter(self.iter());
    }
}

impl<T: Writable + ?Sized> Writable for &T {
    fn write(&self, output: &mut Output) {
        T::write(self, output)
    }
}

impl<T: Writable> Writable for Vec<T> {
    fn write(&self, output: &mut Output) {
        self.as_slice().write(output);
    }
}

impl Writable for () {
    fn write(&self, _output: &mut Output) {}
}

macro_rules! write_to_string {
    ($($t:ident)+) => {$(
        impl Writable for $t {
            fn write(&self, output: &mut Output) {
                self.to_string().write(output);
            }
        }
    )+};
}

write_to_string!(u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);

macro_rules! tuple_writable {
    ($name0:ident $($name:ident: $id:tt )*) => {
        impl<$name0: Writable, $($name: Writable,)*> Writable for ($name0, $($name,)*) {
            fn write(&self, out: &mut Output) {
                self.0.write(out);
                $(
                out.put(b' ');
                self.$id.write(out);
                )*
            }
        }
    }
}

tuple_writable! {T}
tuple_writable! {T U:1}
tuple_writable! {T U:1 V:2}
tuple_writable! {T U:1 V:2 X:3}
tuple_writable! {T U:1 V:2 X:3 Y:4}
tuple_writable! {T U:1 V:2 X:3 Y:4 Z:5}
tuple_writable! {T U:1 V:2 X:3 Y:4 Z:5 A:6}
tuple_writable! {T U:1 V:2 X:3 Y:4 Z:5 A:6 B:7}
tuple_writable! {T U:1 V:2 X:3 Y:4 Z:5 A:6 B:7 C:8}

impl<T: Writable> Writable for Option<T> {
    fn write(&self, output: &mut Output) {
        match self {
            None => (-1).write(output),
            Some(t) => t.write(output),
        }
    }
}

impl Writable for bool {
    fn write(&self, output: &mut Output) {
        let bool_output = output.bool_output;
        bool_output.output(output, *self)
    }
}

impl<T: Writable> Writable for Reverse<T> {
    fn write(&self, output: &mut Output) {
        self.0.write(output);
    }
}

static mut ERR: Option<Stderr> = None;

pub fn err() -> Output<'static> {
    unsafe {
        if ERR.is_none() {
            ERR = Some(stderr());
        }
        Output::new_with_auto_flush(ERR.as_mut().unwrap())
    }
}
}
}
pub mod misc {
pub mod test_type {
pub enum TestType {
    Single,
    MultiNumber,
    MultiEof,
}

pub enum TaskType {
    Classic,
    Interactive,
}
}
pub mod value {
use std::hash::Hash;

pub trait Value<T>: Copy + Eq + Hash {
    fn val() -> T;
}

pub trait ConstValue<T>: Value<T> {
    const VAL: T;
}

impl<T, V: ConstValue<T>> Value<T> for V {
    fn val() -> T {
        Self::VAL
    }
}

#[macro_export]
macro_rules! value {
    ($name: ident: $t: ty = $val: expr) => {
        #[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Default)]
        pub struct $name {}

        impl $crate::algo_lib::misc::value::ConstValue<$t> for $name {
            const VAL: $t = $val;
        }
    };
}

pub trait DynamicValue<T>: Value<T> {
    //noinspection RsSelfConvention
    fn set_val(t: T);
}

#[macro_export]
macro_rules! dynamic_value {
    ($name: ident: $t: ty, $val: ident) => {
        static mut $val: Option<$t> = None;

        #[derive(Copy, Clone, Eq, PartialEq, Hash, Default)]
        struct $name {}

        impl $crate::algo_lib::misc::value::DynamicValue<$t> for $name {
            fn set_val(t: $t) {
                unsafe {
                    $val = Some(t);
                }
            }
        }

        impl $crate::algo_lib::misc::value::Value<$t> for $name {
            fn val() -> $t {
                unsafe { $val.unwrap() }
            }
        }
    };
    ($name: ident: $t: ty) => {
        dynamic_value!($name: $t, VAL);
    };
    ($name: ident: $t: ty = $val: expr) => {
        dynamic_value!($name: $t);

        $name::set_val($val);
    };
    ($name: ident: $t: ty = $val: expr, $val_static: ident) => {
        dynamic_value!($name: $t, $val_static);

        $name::set_val($val);
    };
}
}
pub mod when {
#[macro_export]
macro_rules! when {
    {$($cond: expr => $then: expr,)*} => {
        match () {
            $(_ if $cond => $then,)*
            _ => unreachable!(),
        }
    };
    {$($cond: expr => $then: expr,)* else $(=>)? $else: expr$(,)?} => {
        match () {
            $(_ if $cond => $then,)*
            _ => $else,
        }
    };
}
}
}
pub mod numbers {
pub mod gcd {
use crate::algo_lib::numbers::num_traits::algebra::IntegerMultiplicationMonoid;
use crate::algo_lib::numbers::num_traits::algebra::IntegerSemiRingWithSub;
use crate::algo_lib::numbers::num_traits::algebra::One;
use crate::algo_lib::numbers::num_traits::algebra::SemiRingWithSub;
use crate::algo_lib::numbers::num_traits::algebra::Zero;
use crate::algo_lib::numbers::num_traits::wideable::Wideable;
use std::mem::swap;

pub fn extended_gcd<T: IntegerSemiRingWithSub + Wideable + Copy>(a: T, b: T) -> (T, T::W, T::W)
where
    T::W: Copy + SemiRingWithSub,
{
    if a == T::zero() {
        (b, T::W::zero(), T::W::one())
    } else {
        let (d, y, mut x) = extended_gcd(b % a, a);
        x -= T::W::from(b / a) * y;
        (d, x, y)
    }
}

pub fn gcd<T: Copy + Zero + IntegerMultiplicationMonoid>(mut a: T, mut b: T) -> T {
    while b != T::zero() {
        a %= b;
        swap(&mut a, &mut b);
    }
    a
}

pub fn lcm<T: Copy + Zero + IntegerMultiplicationMonoid>(a: T, b: T) -> T {
    (a / gcd(a, b)) * b
}
}
pub mod mod_int {
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::input::Readable;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::io::output::Writable;
use crate::algo_lib::misc::value::Value;
use crate::algo_lib::numbers::gcd::extended_gcd;
use crate::algo_lib::numbers::num_traits::algebra::Field;
use crate::algo_lib::numbers::num_traits::algebra::IntegerRing;
use crate::algo_lib::numbers::num_traits::algebra::One;
use crate::algo_lib::numbers::num_traits::algebra::Ring;
use crate::algo_lib::numbers::num_traits::algebra::Zero;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use crate::algo_lib::numbers::num_traits::wideable::Wideable;
use crate::value;
use crate::when;
use std::collections::HashMap;
use std::fmt::Display;
use std::fmt::Formatter;
use std::hash::Hash;
use std::marker::PhantomData;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::Div;
use std::ops::DivAssign;
use std::ops::Mul;
use std::ops::MulAssign;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::SubAssign;

pub trait BaseModInt: Field + Copy {
    type W: IntegerRing + Copy + From<Self::T>;
    type T: IntegerRing + Ord + Copy + Wideable<W = Self::W>;

    fn from(v: Self::T) -> Self;
    fn module() -> Self::T;
}

#[derive(Copy, Clone, Eq, PartialEq, Hash, Default)]
pub struct ModInt<T, V: Value<T>> {
    n: T,
    phantom: PhantomData<V>,
}

impl<T: Copy, V: Value<T>> ModInt<T, V> {
    pub fn val(&self) -> T {
        self.n
    }
}

impl<T: Ring + Ord + Copy, V: Value<T>> ModInt<T, V> {
    unsafe fn unchecked_new(n: T) -> Self {
        debug_assert!(n >= T::zero() && n < V::val());
        Self {
            n,
            phantom: Default::default(),
        }
    }

    unsafe fn maybe_subtract_mod(mut n: T) -> T {
        debug_assert!(n < V::val() + V::val() && n >= T::zero());
        if n >= V::val() {
            n -= V::val();
        }
        n
    }
}

impl<T: IntegerRing + Ord + Copy, V: Value<T>> ModInt<T, V> {
    pub fn new(n: T) -> Self {
        unsafe { Self::unchecked_new(Self::maybe_subtract_mod(n % (V::val()) + V::val())) }
    }
}

impl<T: Copy + IntegerRing + Ord + Wideable + Hash, V: Value<T>> ModInt<T, V>
where
    T::W: Copy + IntegerRing,
{
    pub fn log(&self, alpha: Self) -> T {
        let mut base = HashMap::new();
        let mut exp = T::zero();
        let mut pow = Self::one();
        let mut inv = *self;
        let alpha_inv = alpha.inv().unwrap();
        while exp * exp < Self::module() {
            if inv == Self::one() {
                return exp;
            }
            base.insert(inv, exp);
            exp += T::one();
            pow *= alpha;
            inv *= alpha_inv;
        }
        let step = pow;
        let mut i = T::one();
        loop {
            if let Some(b) = base.get(&pow) {
                break exp * i + *b;
            }
            pow *= step;
            i += T::one();
        }
    }
}

impl<T: Wideable + Ring + Ord + Copy, V: Value<T>> ModInt<T, V>
where
    T::W: IntegerRing,
{
    pub fn new_from_wide(n: T::W) -> Self {
        unsafe {
            Self::unchecked_new(Self::maybe_subtract_mod(
                T::downcast(n % V::val().into()) + V::val(),
            ))
        }
    }
}

impl<T: Copy + IntegerRing + Ord + Wideable, V: Value<T>> Invertible for ModInt<T, V>
where
    T::W: Copy + IntegerRing,
{
    type Output = Self;

    fn inv(&self) -> Option<Self> {
        let (g, x, _) = extended_gcd(self.n, V::val());
        if g != T::one() {
            None
        } else {
            Some(Self::new_from_wide(x))
        }
    }
}

impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> BaseModInt for ModInt<T, V>
where
    T::W: IntegerRing + Copy,
{
    type W = T::W;
    type T = T;

    fn from(v: Self::T) -> Self {
        Self::new(v)
    }

    fn module() -> T {
        V::val()
    }
}

impl<T: IntegerRing + Ord + Copy, V: Value<T>> From<T> for ModInt<T, V> {
    fn from(n: T) -> Self {
        Self::new(n)
    }
}

impl<T: Ring + Ord + Copy, V: Value<T>> AddAssign for ModInt<T, V> {
    fn add_assign(&mut self, rhs: Self) {
        self.n = unsafe { Self::maybe_subtract_mod(self.n + rhs.n) };
    }
}

impl<T: Ring + Ord + Copy, V: Value<T>> Add for ModInt<T, V> {
    type Output = Self;

    fn add(mut self, rhs: Self) -> Self::Output {
        self += rhs;
        self
    }
}

impl<T: Ring + Ord + Copy, V: Value<T>> SubAssign for ModInt<T, V> {
    fn sub_assign(&mut self, rhs: Self) {
        self.n = unsafe { Self::maybe_subtract_mod(self.n + V::val() - rhs.n) };
    }
}

impl<T: Ring + Ord + Copy, V: Value<T>> Sub for ModInt<T, V> {
    type Output = Self;

    fn sub(mut self, rhs: Self) -> Self::Output {
        self -= rhs;
        self
    }
}

impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> MulAssign for ModInt<T, V>
where
    T::W: IntegerRing + Copy,
{
    fn mul_assign(&mut self, rhs: Self) {
        self.n = T::downcast(T::W::from(self.n) * T::W::from(rhs.n) % T::W::from(V::val()));
    }
}

impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> Mul for ModInt<T, V>
where
    T::W: IntegerRing + Copy,
{
    type Output = Self;

    fn mul(mut self, rhs: Self) -> Self::Output {
        self *= rhs;
        self
    }
}

impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> DivAssign for ModInt<T, V>
where
    T::W: IntegerRing + Copy,
{
    #[allow(clippy::suspicious_op_assign_impl)]
    fn div_assign(&mut self, rhs: Self) {
        *self *= rhs.inv().unwrap();
    }
}

impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> Div for ModInt<T, V>
where
    T::W: IntegerRing + Copy,
{
    type Output = Self;

    fn div(mut self, rhs: Self) -> Self::Output {
        self /= rhs;
        self
    }
}

impl<T: Ring + Ord + Copy, V: Value<T>> Neg for ModInt<T, V> {
    type Output = Self;

    fn neg(mut self) -> Self::Output {
        self.n = unsafe { Self::maybe_subtract_mod(V::val() - self.n) };
        self
    }
}

impl<T: Display, V: Value<T>> Display for ModInt<T, V> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        <T as Display>::fmt(&self.n, f)
    }
}

impl<T: IntegerRing + Ord + Copy + Readable, V: Value<T>> Readable for ModInt<T, V> {
    fn read(input: &mut Input) -> Self {
        Self::new(T::read(input))
    }
}

impl<T: Writable, V: Value<T>> Writable for ModInt<T, V> {
    fn write(&self, output: &mut Output) {
        self.n.write(output);
    }
}

impl<T: Ring + Ord + Copy, V: Value<T>> Zero for ModInt<T, V> {
    fn zero() -> Self {
        unsafe { Self::unchecked_new(T::zero()) }
    }
}

impl<T: IntegerRing + Ord + Copy, V: Value<T>> One for ModInt<T, V> {
    fn one() -> Self {
        Self::new(T::one())
    }
}

impl<T, V: Value<T>> Wideable for ModInt<T, V> {
    type W = Self;

    fn downcast(w: Self::W) -> Self {
        w
    }
}

impl<T: IntegerRing + Ord + Copy + Wideable + Display + AsIndex, V: Value<T>> std::fmt::Debug
    for ModInt<T, V>
where
    T::W: IntegerRing + Copy,
{
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        let max = T::from_index(100);
        when! {
            self.n <= max => write!(f, "{}", self.n),
            self.n >= V::val() - max => write!(f, "{}", self.n - V::val()),
            else => {
                let mut denominator = T::one();
                while denominator < max {
                    let mut num = T::one();
                    while num < max {
                        if Self::new(num) / Self::new(denominator) == *self {
                            return write!(f, "{}/{}", num, denominator);
                        }
                        if -Self::new(num) / Self::new(denominator) == *self {
                            return write!(f, "-{}/{}", num, denominator);
                        }
                        num += T::one();
                    }
                    denominator += T::one();
                }
                write!(f, "(?? {} ??)", self.n)
            },
        }
    }
}

impl<T: IntegerRing + Ord + Copy + AsIndex, V: Value<T>> AsIndex for ModInt<T, V> {
    fn from_index(idx: usize) -> Self {
        Self::new(T::from_index(idx))
    }

    fn to_index(self) -> usize {
        self.n.to_index()
    }
}

value!(Val7: i32 = 1_000_000_007);
pub type ModInt7 = ModInt<i32, Val7>;

value!(Val9: i32 = 1_000_000_009);
pub type ModInt9 = ModInt<i32, Val9>;

value!(ValF: i32 = 998_244_353);
pub type ModIntF = ModInt<i32, ValF>;
}
pub mod mod_utils {
use crate::algo_lib::numbers::mod_int::BaseModInt;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use crate::algo_lib::numbers::num_utils::factorial;
use crate::algo_lib::numbers::num_utils::factorials;

pub fn inverses<M: BaseModInt>(len: usize) -> Vec<M>
where
    M::T: AsIndex,
{
    let mut res = Vec::new();
    if len > 0 {
        res.push(M::zero());
    }
    if len > 1 {
        res.push(M::one());
    }
    while res.len() < len {
        res.push(
            res[M::module().to_index() % res.len()]
                * (M::from(M::module() / (M::T::from_index(res.len()))).neg()),
        );
    }
    res
}

pub fn inverse_factorials<M: BaseModInt>(len: usize) -> Vec<M>
where
    M::T: AsIndex,
{
    let mut res = inverses(len);
    if len > 0 {
        res[0] = M::one();
    }
    for i in 1..len {
        let last = res[i - 1];
        res[i] *= last;
    }
    res
}

pub struct Combinations<M: BaseModInt>
where
    M::T: AsIndex,
{
    fact: Vec<M>,
    inv_fact: Vec<M>,
}

impl<M: BaseModInt + AsIndex> Combinations<M>
where
    M::T: AsIndex,
{
    pub fn new(len: usize) -> Self {
        Self {
            fact: factorials(len),
            inv_fact: inverse_factorials(len),
        }
    }

    pub fn c(&self, n: usize, k: usize) -> M {
        if n < k {
            M::zero()
        } else {
            self.fact[n] * self.inv_fact[k] * self.inv_fact[n - k]
        }
    }

    pub fn comb_with_rep(&self, n: usize, k: usize) -> M {
        self.c(n + k - 1, k)
    }

    pub fn c_inv(&self, n: usize, k: usize) -> M {
        self.inv_fact[n] * self.fact[k] * self.fact[n - k]
    }

    pub fn fact(&self, n: usize) -> M {
        self.fact[n]
    }

    pub fn inv_fact(&self, n: usize) -> M {
        self.inv_fact[n]
    }
}

pub fn combinations<M: BaseModInt + AsIndex>(n: usize, mut k: usize) -> M {
    if k > n {
        return M::zero();
    }
    if k > n - k {
        k = n - k;
    }
    let mut res = M::one();
    for i in n - k + 1..=n {
        res *= M::from_index(i);
    }
    res /= factorial(k);
    res
}
}
pub mod num_traits {
pub mod algebra {
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::Div;
use std::ops::DivAssign;
use std::ops::Mul;
use std::ops::MulAssign;
use std::ops::Neg;
use std::ops::Rem;
use std::ops::RemAssign;
use std::ops::Sub;
use std::ops::SubAssign;

pub trait Zero {
    fn zero() -> Self;
}

pub trait One {
    fn one() -> Self;
}

pub trait AdditionMonoid: Add<Output = Self> + AddAssign + Zero + Eq + Sized {}

impl<T: Add<Output = Self> + AddAssign + Zero + Eq> AdditionMonoid for T {}

pub trait AdditionMonoidWithSub: AdditionMonoid + Sub<Output = Self> + SubAssign {}

impl<T: AdditionMonoid + Sub<Output = Self> + SubAssign> AdditionMonoidWithSub for T {}

pub trait AdditionGroup: AdditionMonoidWithSub + Neg<Output = Self> {}

impl<T: AdditionMonoidWithSub + Neg<Output = Self>> AdditionGroup for T {}

pub trait MultiplicationMonoid: Mul<Output = Self> + MulAssign + One + Eq + Sized {}

impl<T: Mul<Output = Self> + MulAssign + One + Eq> MultiplicationMonoid for T {}

pub trait IntegerMultiplicationMonoid:
    MultiplicationMonoid + Div<Output = Self> + Rem<Output = Self> + DivAssign + RemAssign
{
}

impl<T: MultiplicationMonoid + Div<Output = Self> + Rem<Output = Self> + DivAssign + RemAssign>
    IntegerMultiplicationMonoid for T
{
}

pub trait MultiplicationGroup:
    MultiplicationMonoid + Div<Output = Self> + DivAssign + Invertible<Output = Self>
{
}

impl<T: MultiplicationMonoid + Div<Output = Self> + DivAssign + Invertible<Output = Self>>
    MultiplicationGroup for T
{
}

pub trait SemiRing: AdditionMonoid + MultiplicationMonoid {}

impl<T: AdditionMonoid + MultiplicationMonoid> SemiRing for T {}

pub trait SemiRingWithSub: AdditionMonoidWithSub + SemiRing {}

impl<T: AdditionMonoidWithSub + SemiRing> SemiRingWithSub for T {}

pub trait Ring: SemiRing + AdditionGroup {}

impl<T: SemiRing + AdditionGroup> Ring for T {}

pub trait IntegerSemiRing: SemiRing + IntegerMultiplicationMonoid {}

impl<T: SemiRing + IntegerMultiplicationMonoid> IntegerSemiRing for T {}

pub trait IntegerSemiRingWithSub: SemiRingWithSub + IntegerSemiRing {}

impl<T: SemiRingWithSub + IntegerSemiRing> IntegerSemiRingWithSub for T {}

pub trait IntegerRing: IntegerSemiRing + Ring {}

impl<T: IntegerSemiRing + Ring> IntegerRing for T {}

pub trait Field: Ring + MultiplicationGroup {}

impl<T: Ring + MultiplicationGroup> Field for T {}

macro_rules! zero_one_integer_impl {
    ($($t: ident)+) => {$(
        impl Zero for $t {
            fn zero() -> Self {
                0
            }
        }

        impl One for $t {
            fn one() -> Self {
                1
            }
        }
    )+};
}

zero_one_integer_impl!(i128 i64 i32 i16 i8 isize u128 u64 u32 u16 u8 usize);
}
pub mod as_index {
pub trait AsIndex {
    fn from_index(idx: usize) -> Self;
    fn to_index(self) -> usize;
}

macro_rules! from_index_impl {
    ($($t: ident)+) => {$(
        impl AsIndex for $t {
            fn from_index(idx: usize) -> Self {
                idx as $t
            }

            fn to_index(self) -> usize {
                self as usize
            }
        }
    )+};
}

from_index_impl!(i128 i64 i32 i16 i8 isize u128 u64 u32 u16 u8 usize);
}
pub mod invertible {
pub trait Invertible {
    type Output;

    fn inv(&self) -> Option<Self::Output>;
}
}
pub mod wideable {
use std::convert::From;

pub trait Wideable: Sized {
    type W: From<Self>;

    fn downcast(w: Self::W) -> Self;
}

macro_rules! wideable_impl {
    ($($t: ident $w: ident),+) => {$(
        impl Wideable for $t {
            type W = $w;

            fn downcast(w: Self::W) -> Self {
                w as $t
            }
        }
    )+};
}

wideable_impl!(i64 i128, i32 i64, i16 i32, i8 i16, u64 u128, u32 u64, u16 u32, u8 u16);
}
}
pub mod num_utils {
use crate::algo_lib::numbers::num_traits::algebra::AdditionMonoid;
use crate::algo_lib::numbers::num_traits::algebra::IntegerRing;
use crate::algo_lib::numbers::num_traits::algebra::MultiplicationMonoid;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;

pub fn factorials<T: MultiplicationMonoid + Copy + AsIndex>(len: usize) -> Vec<T> {
    let mut res = Vec::new();
    if len > 0 {
        res.push(T::one());
    }
    while res.len() < len {
        res.push((*res.last().unwrap()) * T::from_index(res.len()));
    }
    res
}

pub fn powers<T: MultiplicationMonoid + Copy>(base: T, len: usize) -> Vec<T> {
    let mut res = Vec::new();
    if len > 0 {
        res.push(T::one());
    }
    while res.len() < len {
        res.push((*res.last().unwrap()) * base);
    }
    res
}

pub struct Powers<T: MultiplicationMonoid + Copy> {
    small: Vec<T>,
    big: Vec<T>,
}

impl<T: MultiplicationMonoid + Copy> Powers<T> {
    pub fn new(base: T, len: usize) -> Self {
        let small = powers(base, len);
        let big = powers(small[len - 1] * base, len);
        Self { small, big }
    }

    pub fn power(&self, exp: usize) -> T {
        debug_assert!(exp < self.small.len() * self.small.len());
        self.big[exp / self.small.len()] * self.small[exp % self.small.len()]
    }
}

pub fn factorial<T: MultiplicationMonoid + AsIndex>(n: usize) -> T {
    let mut res = T::one();
    for i in 1..=n {
        res *= T::from_index(i);
    }
    res
}

pub trait PartialSums<T> {
    fn partial_sums(&self) -> Vec<T>;
}

impl<T: AdditionMonoid + Copy> PartialSums<T> for [T] {
    fn partial_sums(&self) -> Vec<T> {
        let mut res = Vec::with_capacity(self.len() + 1);
        res.push(T::zero());
        for i in self.iter() {
            res.push(*res.last().unwrap() + *i);
        }
        res
    }
}

pub trait UpperDiv {
    fn upper_div(self, other: Self) -> Self;
}

impl<T: IntegerRing + Copy> UpperDiv for T {
    fn upper_div(self, other: Self) -> Self {
        (self + other - Self::one()) / other
    }
}
}
pub mod number_ext {
use crate::algo_lib::numbers::num_traits::algebra::IntegerSemiRing;
use crate::algo_lib::numbers::num_traits::algebra::MultiplicationMonoid;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use std::ops::Mul;

pub trait Power {
    #[must_use]
    fn power<T: IntegerSemiRing + Copy>(&self, exp: T) -> Self;
}

impl<S: MultiplicationMonoid + Copy> Power for S {
    fn power<T: IntegerSemiRing + Copy>(&self, exp: T) -> Self {
        if exp == T::zero() {
            S::one()
        } else {
            let mut res = self.power(exp / (T::one() + T::one()));
            res *= res;
            if exp % (T::one() + T::one()) == T::one() {
                res *= *self;
            }
            res
        }
    }
}

pub trait NumDigs {
    fn num_digs(&self) -> usize;
}

impl<S: IntegerSemiRing + AsIndex + Copy> NumDigs for S {
    fn num_digs(&self) -> usize {
        let mut copy = *self;
        let ten = S::from_index(10);
        let mut res = 0;
        while copy != S::zero() {
            copy /= ten;
            res += 1;
        }
        res
    }
}

pub trait Square {
    fn square(self) -> Self;
}

impl<T: Mul<Output = T> + Copy> Square for T {
    fn square(self) -> Self {
        self * self
    }
}
}
}
}
fn main() {
    let mut sin = std::io::stdin();
    let input = algo_lib::io::input::Input::new(&mut sin);
    let mut stdout = std::io::stdout();
    let output = algo_lib::io::output::Output::new(&mut stdout);
    solution::run(input, output);
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 370ms
memory: 502028kb

input:

4
3 2
1 1
20 23
8000 8000

output:

374341634
1
111675632
994279778

result:

ok 4 tokens

Test #2:

score: 0
Accepted
time: 383ms
memory: 502164kb

input:

5
60 26
33 95
18 89
82 12
77 36

output:

945602338
254913692
403396795
820508695
360125985

result:

ok 5 tokens

Test #3:

score: 0
Accepted
time: 372ms
memory: 502136kb

input:

5
23 13
95 8
73 19
72 74
23 51

output:

788774542
935467825
483603650
274447212
738760583

result:

ok 5 tokens

Test #4:

score: 0
Accepted
time: 380ms
memory: 502164kb

input:

5
7 79
47 12
64 29
23 59
88 21

output:

238359778
424364643
993714623
760177301
865871793

result:

ok 5 tokens

Test #5:

score: 0
Accepted
time: 368ms
memory: 502108kb

input:

5
39 47
22 33
2 58
43 45
32 67

output:

68068469
21035974
735626561
965644028
137192045

result:

ok 5 tokens

Test #6:

score: 0
Accepted
time: 375ms
memory: 502224kb

input:

5
57 73
20 64
18 72
56 64
9 58

output:

218207240
814770590
121270366
636721674
420274847

result:

ok 5 tokens

Test #7:

score: 0
Accepted
time: 376ms
memory: 502116kb

input:

5
100 100
100 99
99 100
98 99
99 97

output:

585389012
131732771
619127511
549657738
490584077

result:

ok 5 tokens

Test #8:

score: 0
Accepted
time: 375ms
memory: 502464kb

input:

1922
4663 5021
7459 306
3249 6943
4902 4260
6118 5364
4997 7021
6772 3346
3916 7327
7156 4792
1228 5381
3240 7026
131 5713
1120 5334
2186 610
7638 2846
891 6274
5363 426
1335 7417
2127 396
323 7781
5435 1922
4989 5238
2886 3788
5413 1384
7624 4245
7191 6758
7755 5835
7660 1787
1043 7586
803 7889
79 ...

output:

672342508
406758717
456109836
583347519
254351863
547587964
177045319
935533988
555369350
136991350
790497273
429246740
670208582
782070778
169184793
771435402
251034885
528072506
303570823
257245963
629853925
267752975
350150586
786769060
44222606
607226242
320315817
861879910
752261031
341472947
2...

result:

ok 1922 tokens

Test #9:

score: 0
Accepted
time: 379ms
memory: 502504kb

input:

1569
1690 3118
4489 1453
6866 3161
6664 1290
2600 7962
6689 4642
522 772
2162 4794
3190 5987
3327 4938
6130 3823
6941 5425
3091 6213
3025 388
5330 3690
3161 6492
1740 5873
5530 1458
2496 6781
6287 5635
662 3877
3505 5138
2511 2028
3500 859
7572 813
2520 3943
7377 4768
6158 1882
7427 1702
4296 5159
5...

output:

786392950
680031668
677629004
801851613
786349751
79816839
959519914
318092993
339917671
724667845
890615671
100962701
589915015
941504560
820459949
486565344
823734064
220460851
576680186
554430485
361102164
218914963
840663949
777667686
736007308
919520675
863371619
66677855
637862969
67422276
384...

result:

ok 1569 tokens

Test #10:

score: 0
Accepted
time: 381ms
memory: 502376kb

input:

1181
4017 5052
5241 7494
7719 3875
7903 143
7280 2239
6098 2785
4900 5047
3542 4892
3011 430
4358 3184
1473 1501
2732 5656
6806 7106
6079 4418
4893 233
1746 3558
3801 650
4506 970
7836 5225
1970 1822
3342 7672
3519 1017
6258 3172
6871 3994
4143 3721
1752 2936
5806 2553
1727 3701
6464 2302
2048 3091
...

output:

648881231
526073149
469264135
392921762
374237236
765018788
699026377
457948355
693169225
754094043
700515631
122741833
428610910
661965148
268857241
313001621
686530925
177273994
339148514
571456944
973936686
176745436
23414882
360870357
623038194
895354617
386646311
288047747
236022755
955017813
1...

result:

ok 1181 tokens

Test #11:

score: 0
Accepted
time: 374ms
memory: 502372kb

input:

1080
7499 4465
5556 2341
808 1986
3404 6901
4609 4168
235 5744
5131 7261
6616 1993
4624 3943
5843 6392
4889 2743
386 6670
1188 23
4216 4225
1193 1295
6097 4160
710 2728
7146 4193
5425 4148
6206 7462
7147 1808
2381 1254
4193 1297
1359 233
991 6979
5009 6963
1824 2135
1078 6208
2893 5858
320 4173
4937...

output:

584491148
616649457
512306930
528213999
550156793
344729669
779502829
828764040
365090398
371482124
273983459
617971432
137019685
400487464
761520033
143391408
908639433
294086517
926654429
723576006
993426946
572674399
178336952
402120004
148856064
897242602
390050708
850225145
605879501
962941650
...

result:

ok 1080 tokens

Test #12:

score: 0
Accepted
time: 377ms
memory: 502316kb

input:

1534
2137 7885
2676 2513
53 3021
1623 5195
660 4999
2881 7697
6034 6429
4724 4014
5986 266
7826 726
4086 6628
7498 6114
4801 4415
5037 4206
700 6054
3497 476
1715 5892
6009 6340
1251 2345
2819 4107
7544 864
3138 4179
3909 912
180 4496
4727 2930
1057 7077
4123 2560
4963 4100
7118 463
2945 935
6573 41...

output:

676937061
816416208
899106800
778722088
621854770
637694747
789726622
647248717
143759992
290955099
204045987
17260543
508242895
836696138
605720517
462338702
426815143
443255417
341689094
660082176
461660684
531200268
467927798
816405934
307396775
786033585
765478425
774747686
67909522
155061063
47...

result:

ok 1534 tokens

Test #13:

score: 0
Accepted
time: 1057ms
memory: 525996kb

input:

300000
1983 855
7767 4477
6925 7526
7306 5358
3987 46
5716 3789
4487 4391
4358 7525
933 1015
953 546
5716 5487
968 6561
2932 6558
6796 1429
4864 4211
5955 4414
6657 5171
2784 3725
1139 7304
553 3163
7248 6772
1977 6216
4701 7267
6130 4055
5688 1364
1335 4326
2633 3945
7851 5521
6474 2532
6869 5201
2...

output:

917986185
514093688
240004856
10138263
106086887
486293160
462563200
380236329
178495199
768072852
293049871
679765965
19413063
914310451
303877752
97576016
551398628
294935753
497649688
625770227
916721949
945723005
793837895
598750153
811171822
281042931
224310375
229099648
232754408
173968951
334...

result:

ok 300000 tokens

Test #14:

score: 0
Accepted
time: 1079ms
memory: 526396kb

input:

300000
6276 3969
1337 287
69 4971
4553 4420
4304 107
836 5154
7039 7495
4074 5597
3321 6214
5997 5958
1357 67
5347 5263
5228 5204
6067 7567
3498 226
1830 3989
7897 3908
4547 714
1973 4138
3392 2046
6781 2623
7423 7027
3219 1631
688 6768
1270 5667
1911 1106
4914 755
4060 6194
5588 6416
5379 3593
4950...

output:

785609765
389521714
617648697
133397962
663080285
932116327
864145458
250419436
926868327
231968290
706343931
34357834
259117474
30429506
802394434
962282557
421143424
325071266
930611818
413209658
588520237
879895836
293550595
779472804
703506662
997419552
167326709
571013401
948481475
873418350
52...

result:

ok 300000 tokens

Test #15:

score: 0
Accepted
time: 1070ms
memory: 526172kb

input:

300000
172 7671
2377 1841
772 2572
897 2774
7862 7766
563 7835
50 5627
3975 332
3125 4092
6642 7913
377 4237
5378 2346
7235 484
7254 4026
5032 189
698 3244
5656 1277
42 5418
294 7339
6054 5619
5273 6487
3381 4739
1652 5241
5455 6606
5194 1556
2248 5307
6266 94
6669 4982
4033 4379
6666 4863
7785 583
...

output:

690315780
651031191
910258157
142140073
777756320
339555304
856925271
481764268
804784924
892959827
162363106
880216583
28750709
919204633
590976688
235862971
115143352
552437269
440186544
342438715
203287097
208201535
473851494
630433067
795957931
121121486
655185544
120192487
18559533
512410924
14...

result:

ok 300000 tokens

Test #16:

score: 0
Accepted
time: 1059ms
memory: 526108kb

input:

300000
7687 5348
7170 7128
1126 3094
1811 2132
4535 2558
6168 62
1913 315
454 6832
2620 979
6268 2470
7745 4962
5836 455
2548 2645
1190 4820
1664 7069
1853 3559
1684 324
2964 2375
6535 2140
5793 6520
2089 2949
6810 6376
3938 1105
3321 2276
1764 7871
7238 4463
6621 6709
4794 1247
1193 3711
7945 25
75...

output:

467980791
680962696
898655348
87851601
574364215
617075952
975724718
232344677
97747094
798035755
544312119
750213987
398352588
468271115
911224185
789740750
889993565
757589351
219602000
508186836
143616463
496959998
957512294
48894767
747840016
237688107
834496842
452902067
436640761
68924558
4766...

result:

ok 300000 tokens

Test #17:

score: 0
Accepted
time: 1063ms
memory: 526288kb

input:

300000
3651 4395
598 2124
7806 1885
6102 3232
1632 4425
2814 2949
2885 4010
719 5821
945 382
3259 3899
1193 2658
3681 176
6978 3339
5065 458
7910 7330
7480 2560
1144 4193
3047 5955
690 5384
6928 5609
238 904
6819 6617
2297 2464
1956 4427
3070 7665
57 5624
1382 7277
1510 931
5413 6319
4135 5153
1245 ...

output:

185080421
622515437
953285449
259657392
382766568
389748070
912098350
791812015
122470478
542646121
189378193
481103802
38378800
282397881
456885301
463133196
542482622
956189657
306447176
892824103
231973605
607936904
612962412
787715604
946988413
397452805
443819486
441909715
443478773
675662739
2...

result:

ok 300000 tokens

Test #18:

score: 0
Accepted
time: 932ms
memory: 526124kb

input:

300000
5511 1592
3091 222
3042 2846
4996 1848
2759 719
339 41
7833 6657
6578 4870
5836 3918
3287 2592
6888 254
323 257
3894 762
2781 147
6338 4197
2401 5526
309 111
499 475
68 1
1791 1498
1139 172
7367 5346
1326 1086
6056 3244
1539 870
2161 577
6899 4934
3222 2409
5094 4945
1252 389
7532 3877
4849 2...

output:

308162096
926831023
97466439
381502673
879141892
288558285
376988538
114780505
967786299
109837829
456357766
152648543
358087181
727740397
203822224
512742419
592251017
205442121
1
187347956
440265112
31975034
944117166
277099223
807372439
313788153
396485979
416038692
118014328
380422322
384451082
...

result:

ok 300000 tokens

Test #19:

score: 0
Accepted
time: 931ms
memory: 526072kb

input:

300000
5511 2811
3091 225
3042 1281
4996 821
2759 267
339 292
7833 515
6578 5344
5836 1128
3287 398
6888 5910
323 266
3894 3721
2781 2271
6338 5322
6838 6497
309 243
499 486
68 11
1791 100
1139 514
7367 5113
1326 747
6056 1604
1539 782
2161 762
6899 4749
3222 2011
5094 3978
1252 623
7532 5477
4849 4...

output:

665054891
300867667
348283279
466053547
45744379
708735980
593404766
831832507
489279444
573407999
597639718
5766230
375599902
486548670
501927978
980593373
969955705
448325802
388400601
262385137
375376816
110122988
737706874
150359153
575621812
804184716
68665586
818047613
692689346
78602127
45512...

result:

ok 300000 tokens

Test #20:

score: 0
Accepted
time: 922ms
memory: 526376kb

input:

300000
5511 413
3091 2856
3042 1024
4996 3213
2759 105
339 327
7833 5988
6578 1636
5836 315
3287 1972
6888 1326
323 60
3894 816
2781 1712
6338 4382
2852 7641
309 57
499 167
68 23
1791 1375
1139 348
7367 6505
1326 435
6056 4617
1539 1133
2161 910
6899 1763
3222 1481
5094 2477
1252 1156
7532 6557
4849...

output:

485659367
677896371
51153808
69443182
412971885
818481416
849977792
331829138
55724792
462907888
637926
406804012
381350405
51624478
359208029
272155650
163436382
342656855
200714626
498916202
182274510
677459983
991151110
396383019
392439555
63570810
520284517
966012692
88444228
86200285
555967449
...

result:

ok 300000 tokens

Test #21:

score: 0
Accepted
time: 925ms
memory: 526416kb

input:

300000
5511 2520
3091 2007
3042 2527
4996 267
2759 1311
339 7
7833 5969
6578 5180
5836 4504
3287 824
6888 1800
323 188
3894 2703
2781 113
6338 5373
210 667
309 5
499 463
68 45
1791 1776
1139 217
7367 6534
1326 193
6056 4824
1539 64
2161 626
6899 2131
3222 2304
5094 908
1252 622
7532 571
4849 1266
15...

output:

476330360
341129155
87686760
780287663
27737410
601067754
621911465
112461167
976022023
494331271
75971592
561865913
585445560
580978232
272409206
301199669
509769247
189882720
370830663
729977839
290413155
663712832
115843838
947770059
572260971
688396109
806982866
335384041
666428123
733355123
403...

result:

ok 300000 tokens

Test #22:

score: 0
Accepted
time: 926ms
memory: 526276kb

input:

300000
5511 2723
3091 2210
3042 1678
4996 3350
2759 1717
339 59
7833 6785
6578 1468
5836 5509
3287 2451
6888 4895
323 38
3894 2668
2781 2757
6338 5735
139 3773
309 296
499 359
68 51
1791 681
1139 990
7367 745
1326 327
6056 4864
1539 1125
2161 808
6899 890
3222 1023
5094 818
1252 185
7532 1083
4849 1...

output:

122256708
329468041
972582618
696900189
185355879
798415905
911105222
943525716
635145786
793642508
954014637
300072137
198622306
632297009
788106407
790602929
474908621
312319885
494386936
195749245
997359493
881353961
668060322
157183412
32778140
733123188
104542588
116382314
860154073
47295
78564...

result:

ok 300000 tokens

Test #23:

score: 0
Accepted
time: 1675ms
memory: 526096kb

input:

300000
7522 7956
7746 7848
7995 7694
7479 7992
7878 7976
7532 7658
7679 7755
7462 7709
7610 7495
7877 7995
7915 7608
7883 7677
7467 7658
7615 7815
7521 7676
7455 7891
7868 7896
7634 7704
7869 7590
7471 7573
7472 7678
7885 7539
7983 7974
7478 7479
7705 7827
7675 7615
7915 7597
7644 7511
7903 7966
750...

output:

350858640
985201186
270505812
117456150
344107653
461416294
951152728
812878714
422195931
502806704
124570242
713987345
272798186
110562310
722669359
200627964
808703774
749707180
560860878
63011161
961348423
407734207
629246603
741475119
234863886
992855605
920110738
57955523
124147954
685852042
92...

result:

ok 300000 tokens

Extra Test:

score: 0
Extra Test Passed