/ SeriousOJ /

Record Detail

Memory Exceeded


  
# Status Time Cost Memory Cost
#1 Accepted 1ms 284.0 KiB
#2 Wrong Answer 474ms 604.0 KiB
#3 Memory Exceeded ≥2177ms ≥512.016 MiB

Code

// https://judge.eluminatis-of-lu.com/contest/676ffd92569fb90008aac7da/1156
use crate::algo_lib::collections::iter_ext::iter_copied::ItersCopied;
use crate::algo_lib::collections::md_arr::arr2d::Arr2dRead;
use crate::algo_lib::collections::min_max::MinimMaxim;
use crate::algo_lib::graph::distances::Distances;
use crate::algo_lib::graph::edges::weighted_edge::WeightedEdge;
use crate::algo_lib::graph::Graph;
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::misc::test_type::TaskType;
use crate::algo_lib::misc::test_type::TestType;
type PreCalc = ();
fn solve(input: &mut Input, out: &mut Output, _test_case: usize, _data: &mut PreCalc) {
    let n = input.read_size();
    let m = input.read_size();
    let x = input.read_long();
    let y = input.read_long();
    let maze = input.read_char_table(n, m);
    let mut graph = Graph::new(n * (m - 1) + m * (n - 1));
    for i in 0..n - 1 {
        for j in 0..m {
            if maze[(i + 1, j)] == b'#' {
                continue;
            }
            let id = i * m + j;
            if i + 1 < n - 1 {
                graph.add_edge(WeightedEdge::new(id, id + m, x));
            }
            if j > 0 {
                graph
                    .add_edge(
                        WeightedEdge::new(
                            id,
                            m * (n - 1) + (i + 1) * (m - 1) + (j - 1),
                            y,
                        ),
                    );
            }
            if j + 1 < m {
                graph
                    .add_edge(
                        WeightedEdge::new(id, m * (n - 1) + (i + 1) * (m - 1) + j, y),
                    );
            }
        }
    }
    for i in 0..n {
        for j in 0..m - 1 {
            let id = m * (n - 1) + i * (m - 1) + j;
            if j + 1 < m - 1 && maze[(i, j + 1)] != b'#' {
                graph.add_edge(WeightedEdge::new(id, id + 1, x));
            }
            if j > 0 && maze[(i, j)] != b'#' {
                graph.add_edge(WeightedEdge::new(id, id - 1, x));
            }
            if i + 1 < n {
                if maze[(i, j)] != b'#' {
                    graph.add_edge(WeightedEdge::new(id, i * m + j, y));
                }
                if maze[(i, j + 1)] != b'#' {
                    graph.add_edge(WeightedEdge::new(id, i * m + j + 1, y));
                }
            }
        }
    }
    let sources = vec![0, m * (n - 1)];
    let sinks = vec![m * (n - 1) - 1, m * (n - 1) + n * (m - 1) - 1];
    let mut ans = None;
    for s in sources.copy_iter() {
        let d = graph.distances_from(s);
        for t in sinks.copy_iter() {
            if let Some((dist, ..)) = d[t] {
                ans.minim(dist);
            }
        }
    }
    out.print_line(ans);
}
pub static TEST_TYPE: TestType = TestType::MultiNumber;
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,
    }
}


fn main() {
    let mut sin = std::io::stdin();
    let input = crate::algo_lib::io::input::Input::new(&mut sin);
    let mut stdout = std::io::stdout();
    let output = crate::algo_lib::io::output::Output::new(&mut stdout);
    run(input, output);
}
pub mod algo_lib {
pub mod collections {
pub mod dsu {
use crate::algo_lib::collections::slice_ext::bounds::Bounds;
use crate::algo_lib::collections::slice_ext::indices::Indices;
use std::cell::Cell;
#[derive(Clone)]
pub struct DSU {
    id: Vec<Cell<i32>>,
    count: usize,
}
impl DSU {
    pub fn new(n: usize) -> Self {
        Self {
            id: vec![Cell::new(- 1); n],
            count: n,
        }
    }
    pub fn size(&self, i: usize) -> usize {
        (-self.id[self.find(i)].get()) as usize
    }
    #[allow(clippy::len_without_is_empty)]
    pub fn len(&self) -> usize {
        self.id.len()
    }
    pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
        self.id
            .iter()
            .enumerate()
            .filter_map(|(i, id)| if id.get() < 0 { Some(i) } else { None })
    }
    pub fn set_count(&self) -> usize {
        self.count
    }
    pub fn union(&mut self, mut a: usize, mut b: usize) -> bool {
        a = self.find(a);
        b = self.find(b);
        if a == b {
            false
        } else {
            self.id[a].replace(self.id[a].get() + self.id[b].get());
            self.id[b].replace(a as i32);
            self.count -= 1;
            true
        }
    }
    pub fn find(&self, i: usize) -> usize {
        if self.id[i].get() >= 0 {
            let res = self.find(self.id[i].get() as usize);
            self.id[i].replace(res as i32);
            res
        } else {
            i
        }
    }
    pub fn clear(&mut self) {
        self.count = self.id.len();
        self.id.fill(Cell::new(-1));
    }
    pub fn parts(&self) -> Vec<Vec<usize>> {
        let roots: Vec<_> = self.iter().collect();
        let mut res = vec![Vec::new(); roots.len()];
        for i in self.id.indices() {
            res[roots.as_slice().bin_search(&self.find(i)).unwrap()].push(i);
        }
        res
    }
}
}
pub mod indexed_heap {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use crate::algo_lib::misc::maybe::Maybe;
struct Opt<T> {
    index: u32,
    value: Maybe<T>,
}
#[allow(clippy::derivable_impls)]
impl<T> Default for Opt<T> {
    fn default() -> Self {
        Self {
            index: u32::MAX,
            value: Maybe::none(),
        }
    }
}
impl<T> Opt<T> {
    fn index(&self) -> usize {
        assert!(self.index != u32::MAX);
        self.index as usize
    }
    fn val(&self) -> &T {
        assert!(self.index != u32::MAX);
        unsafe { self.value.as_ref() }
    }
    fn set_index(&mut self, index: usize) {
        assert!(self.index != u32::MAX);
        self.index = index as u32;
    }
    fn set_val(&mut self, t: T) {
        assert!(self.index != u32::MAX);
        unsafe { *self.value.as_mut() = t };
    }
    fn take(&mut self) -> (usize, T) {
        assert!(self.index != u32::MAX);
        let value = unsafe { self.value.take() };
        let index = self.index as usize;
        self.index = u32::MAX;
        (index, value)
    }
    fn is_none(&self) -> bool {
        self.index == u32::MAX
    }
}
impl<T> Drop for Opt<T> {
    fn drop(&mut self) {
        if self.index != u32::MAX {
            unsafe { self.value.drop() }
        }
    }
}
pub struct IndexedHeap<T> {
    heap: Vec<u32>,
    pos: Vec<Opt<T>>,
}
impl<T: PartialOrd> IndexedHeap<T> {
    pub fn new(capacity: usize) -> Self {
        Self {
            heap: Vec::with_capacity(capacity),
            pos: default_vec(capacity),
        }
    }
    pub fn len(&self) -> usize {
        self.heap.len()
    }
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
    pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
        self.heap.iter().map(|x| *x as usize)
    }
    pub fn add_or_adjust(&mut self, el: usize, val: T) {
        if self.pos[el].is_none() {
            self.pos[el].index = self.heap.len() as u32;
            self.pos[el].value = Maybe::new(val);
            self.heap.push(el as u32);
            self.sift_up(self.pos[el].index());
        } else {
            let v = self.pos[el].val();
            let less = *v < val;
            self.pos[el].set_val(val);
            if less {
                self.sift_down(self.pos[el].index());
            } else {
                self.sift_up(self.pos[el].index());
            }
        }
    }
    pub fn add_or_relax(&mut self, el: usize, val: T) {
        if self.pos[el].is_none() {
            self.add_or_adjust(el, val);
        } else {
            let value = self.pos[el].val();
            if &val < value {
                self.add_or_adjust(el, val);
            }
        }
    }
    pub fn peek(&self) -> Option<(usize, &T)> {
        if self.is_empty() {
            None
        } else {
            let at = self.heap[0] as usize;
            Some((self.pos[at].index(), self.pos[at].val()))
        }
    }
    pub fn pop(&mut self) -> Option<(usize, T)> {
        if self.is_empty() {
            None
        } else {
            let el = self.heap[0] as usize;
            Some((el, self.remove(el).unwrap()))
        }
    }
    pub fn clear(&mut self) {
        self.heap.clear();
        for el in &mut self.pos {
            *el = Opt::default();
        }
    }
    pub fn remove(&mut self, el: usize) -> Option<T> {
        if self.pos[el].is_none() {
            None
        } else {
            let pos = self.pos[el].index();
            let last = self.heap.pop().unwrap();
            let val = self.pos[last as usize].take().1;
            if self.is_empty() {
                Some(val)
            } else {
                let top_val = self.pos[el].take().1;
                self.pos[last as usize].index = pos as u32;
                self.pos[last as usize].value = Maybe::new(val);
                self.heap[pos] = last;
                self.sift_down(pos);
                self.sift_up(pos);
                Some(top_val)
            }
        }
    }
    pub fn value(&self, el: usize) -> Option<&T> {
        if self.pos[el].is_none() { None } else { Some(self.pos[el].val()) }
    }
    fn sift_up(&mut self, mut index: usize) {
        let v = self.heap[index] as usize;
        while index > 0 {
            let parent = (index - 1) >> 1;
            let par_val = self.heap[parent] as usize;
            if self.pos[par_val].val() <= self.pos[v].val() {
                self.heap[index] = v as u32;
                self.pos[v].set_index(index);
                return;
            }
            self.heap[index] = par_val as u32;
            self.pos[par_val].set_index(index);
            index = parent;
        }
        self.heap[0] = v as u32;
        self.pos[v].set_index(0);
    }
    fn sift_down(&mut self, mut index: usize) {
        let v = self.heap[index] as usize;
        loop {
            let mut child = (index << 1) + 1;
            if child >= self.len() {
                break;
            }
            if child + 1 < self.len()
                && self.pos[self.heap[child] as usize].val()
                    > self.pos[self.heap[child + 1] as usize].val()
            {
                child += 1;
            }
            if self.pos[self.heap[child] as usize].val() >= self.pos[v].val() {
                break;
            }
            self.heap[index] = self.heap[child];
            self.pos[self.heap[index] as usize].set_index(index);
            index = child;
        }
        self.heap[index] = v as u32;
        self.pos[v].set_index(index);
    }
}
}
pub mod iter_ext {
pub mod iter_copied {
use std::iter::{
    Chain, Copied, Enumerate, Filter, Map, Rev, Skip, StepBy, Sum, Take, Zip,
};
pub trait ItersCopied<'a, T: 'a + Copy>: Sized + 'a
where
    &'a Self: IntoIterator<Item = &'a T>,
{
    fn copy_iter(&'a self) -> Copied<<&'a Self as IntoIterator>::IntoIter> {
        self.into_iter().copied()
    }
    fn copy_enumerate(
        &'a self,
    ) -> Enumerate<Copied<<&'a Self as IntoIterator>::IntoIter>> {
        self.copy_iter().enumerate()
    }
    fn copy_rev(&'a self) -> Rev<Copied<<&'a Self as IntoIterator>::IntoIter>>
    where
        Copied<<&'a Self as IntoIterator>::IntoIter>: DoubleEndedIterator,
    {
        self.copy_iter().rev()
    }
    fn copy_skip(
        &'a self,
        n: usize,
    ) -> Skip<Copied<<&'a Self as IntoIterator>::IntoIter>> {
        self.copy_iter().skip(n)
    }
    fn copy_take(
        &'a self,
        n: usize,
    ) -> Take<Copied<<&'a Self as IntoIterator>::IntoIter>> {
        self.copy_iter().take(n)
    }
    fn copy_chain<V>(
        &'a self,
        chained: &'a V,
    ) -> Chain<
        Copied<<&'a Self as IntoIterator>::IntoIter>,
        Copied<<&'a V as IntoIterator>::IntoIter>,
    >
    where
        &'a V: IntoIterator<Item = &'a T>,
    {
        self.copy_iter().chain(chained.into_iter().copied())
    }
    fn copy_zip<V>(
        &'a self,
        other: &'a V,
    ) -> Zip<
        Copied<<&'a Self as IntoIterator>::IntoIter>,
        Copied<<&'a V as IntoIterator>::IntoIter>,
    >
    where
        &'a V: IntoIterator<Item = &'a T>,
    {
        self.copy_iter().zip(other.into_iter().copied())
    }
    fn copy_max(&'a self) -> T
    where
        T: Ord,
    {
        self.copy_iter().max().unwrap()
    }
    fn copy_max_by_key<B, F>(&'a self, f: F) -> T
    where
        F: FnMut(&T) -> B,
        B: Ord,
    {
        self.copy_iter().max_by_key(f).unwrap()
    }
    fn copy_min(&'a self) -> T
    where
        T: Ord,
    {
        self.copy_iter().min().unwrap()
    }
    fn copy_min_by_key<B, F>(&'a self, f: F) -> T
    where
        F: FnMut(&T) -> B,
        B: Ord,
    {
        self.copy_iter().min_by_key(f).unwrap()
    }
    fn copy_sum(&'a self) -> T
    where
        T: Sum<T>,
    {
        self.copy_iter().sum()
    }
    fn copy_map<F, U>(
        &'a self,
        f: F,
    ) -> Map<Copied<<&'a Self as IntoIterator>::IntoIter>, F>
    where
        F: FnMut(T) -> U,
    {
        self.copy_iter().map(f)
    }
    fn copy_all(&'a self, f: impl FnMut(T) -> bool) -> bool {
        self.copy_iter().all(f)
    }
    fn copy_any(&'a self, f: impl FnMut(T) -> bool) -> bool {
        self.copy_iter().any(f)
    }
    fn copy_step_by(
        &'a self,
        step: usize,
    ) -> StepBy<Copied<<&'a Self as IntoIterator>::IntoIter>> {
        self.copy_iter().step_by(step)
    }
    fn copy_filter<F: FnMut(&T) -> bool>(
        &'a self,
        f: F,
    ) -> Filter<Copied<<&'a Self as IntoIterator>::IntoIter>, F> {
        self.copy_iter().filter(f)
    }
    fn copy_fold<Acc, F>(&'a self, init: Acc, f: F) -> Acc
    where
        F: FnMut(Acc, T) -> Acc,
    {
        self.copy_iter().fold(init, f)
    }
    fn copy_reduce<F>(&'a self, f: F) -> Option<T>
    where
        F: FnMut(T, T) -> T,
    {
        self.copy_iter().reduce(f)
    }
    fn copy_position<P>(&'a self, predicate: P) -> Option<usize>
    where
        P: FnMut(T) -> bool,
    {
        self.copy_iter().position(predicate)
    }
    fn copy_find(&'a self, val: T) -> Option<usize>
    where
        T: PartialEq,
    {
        self.copy_iter().position(|x| x == val)
    }
    fn copy_count(&'a self, val: T) -> usize
    where
        T: PartialEq,
    {
        self.copy_iter().filter(|&x| x == val).count()
    }
}
impl<'a, U: 'a, T: 'a + Copy> ItersCopied<'a, T> for U
where
    &'a U: IntoIterator<Item = &'a T>,
{}
}
}
pub mod md_arr {
pub mod arr2d {
use crate::algo_lib::io::input::{Input, Readable};
use crate::algo_lib::io::output::{Output, Writable};
use std::iter::{Skip, StepBy, Take};
use std::mem::MaybeUninit;
use std::ops::{Index, IndexMut, Range};
use std::slice::{Iter, IterMut};
use std::vec::IntoIter;
#[derive(Clone, Eq, PartialEq, Default, Debug, Hash)]
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 gen<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) -> IterMut<'_, T> {
        self.data.iter_mut()
    }
    pub fn row(&self, row: usize) -> Take<Skip<Iter<'_, T>>> {
        assert!(row < self.d1);
        self.data.iter().skip(row * self.d2).take(self.d2)
    }
    pub fn row_mut(&mut self, row: usize) -> Take<Skip<IterMut<'_, T>>> {
        assert!(row < self.d1);
        self.data.iter_mut().skip(row * self.d2).take(self.d2)
    }
    pub fn col(&self, col: usize) -> StepBy<Skip<Iter<'_, T>>> {
        assert!(col < self.d2);
        self.data.iter().skip(col).step_by(self.d2)
    }
    pub fn col_mut(&mut self, col: usize) -> StepBy<Skip<IterMut<'_, 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!(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) {
        if r1 == r2 {
            assert!(r1 < self.d1);
            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(),
            }
        }
    }
    pub fn transpose(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 + 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.fill(elem);
    }
}
impl<T> Index<(usize, usize)> for Arr2d<T> {
    type Output = T;
    fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
        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!(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(output.separator());
                }
                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::gen(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 min_max {
pub trait MinimMaxim<Rhs = Self>: PartialOrd + Sized {
    fn minim(&mut self, other: Rhs) -> bool;
    fn maxim(&mut self, other: Rhs) -> bool;
}
impl<T: PartialOrd> MinimMaxim for T {
    fn minim(&mut self, other: Self) -> bool {
        if other < *self {
            *self = other;
            true
        } else {
            false
        }
    }
    fn maxim(&mut self, other: Self) -> bool {
        if other > *self {
            *self = other;
            true
        } else {
            false
        }
    }
}
impl<T: PartialOrd> MinimMaxim<T> for Option<T> {
    fn minim(&mut self, other: T) -> bool {
        match self {
            None => {
                *self = Some(other);
                true
            }
            Some(v) => v.minim(other),
        }
    }
    fn maxim(&mut self, other: T) -> bool {
        match self {
            None => {
                *self = Some(other);
                true
            }
            Some(v) => v.maxim(other),
        }
    }
}
}
pub mod slice_ext {
pub mod bounds {
pub trait Bounds<T: PartialOrd> {
    fn lower_bound(&self, el: &T) -> usize;
    fn upper_bound(&self, el: &T) -> usize;
    fn bin_search(&self, el: &T) -> Option<usize>;
    fn more(&self, el: &T) -> usize;
    fn more_or_eq(&self, el: &T) -> usize;
    fn less(&self, el: &T) -> usize {
        self.lower_bound(el)
    }
    fn less_or_eq(&self, el: &T) -> usize {
        self.upper_bound(el)
    }
}
impl<T: PartialOrd> Bounds<T> for [T] {
    fn lower_bound(&self, el: &T) -> usize {
        let mut left = 0;
        let mut right = self.len();
        while left < right {
            let mid = left + ((right - left) >> 1);
            if &self[mid] < el {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        left
    }
    fn upper_bound(&self, el: &T) -> usize {
        let mut left = 0;
        let mut right = self.len();
        while left < right {
            let mid = left + ((right - left) >> 1);
            if &self[mid] <= el {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        left
    }
    fn bin_search(&self, el: &T) -> Option<usize> {
        let at = self.lower_bound(el);
        if at == self.len() || &self[at] != el { None } else { Some(at) }
    }
    fn more(&self, el: &T) -> usize {
        self.len() - self.upper_bound(el)
    }
    fn more_or_eq(&self, el: &T) -> usize {
        self.len() - self.lower_bound(el)
    }
}
}
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 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 graph {
use crate::algo_lib::collections::dsu::DSU;
use crate::algo_lib::graph::edges::bi_edge::BiEdge;
use crate::algo_lib::graph::edges::edge::Edge;
use crate::algo_lib::graph::edges::edge_trait::{BidirectionalEdgeTrait, EdgeTrait};
use std::ops::{Index, IndexMut};



















#[derive(Clone)]
pub struct Graph<E: EdgeTrait> {
    edges: Vec<Vec<E>>,
    edge_count: usize,
}
impl<E: EdgeTrait> Graph<E> {
    pub fn new(vertex_count: usize) -> Self {
        Self {
            edges: vec![Vec::new(); vertex_count],
            edge_count: 0,
        }
    }
    pub fn add_edge(&mut self, (from, mut edge): (usize, E)) -> usize {
        let to = edge.to();
        assert!(to < self.vertex_count());
        let direct_id = self.edges[from].len();
        edge.set_id(self.edge_count);
        self.edges[from].push(edge);
        if E::REVERSABLE {
            let rev_id = self.edges[to].len();
            self.edges[from][direct_id].set_reverse_id(rev_id);
            let mut rev_edge = self.edges[from][direct_id].reverse_edge(from);
            rev_edge.set_id(self.edge_count);
            rev_edge.set_reverse_id(direct_id);
            self.edges[to].push(rev_edge);
        }
        self.edge_count += 1;
        direct_id
    }
    pub fn add_vertices(&mut self, cnt: usize) {
        self.edges.resize(self.edges.len() + cnt, Vec::new());
    }
    pub fn clear(&mut self) {
        self.edge_count = 0;
        for ve in self.edges.iter_mut() {
            ve.clear();
        }
    }
    pub fn vertex_count(&self) -> usize {
        self.edges.len()
    }
    pub fn edge_count(&self) -> usize {
        self.edge_count
    }
    pub fn degrees(&self) -> Vec<usize> {
        self.edges.iter().map(|v| v.len()).collect()
    }
}
impl<E: BidirectionalEdgeTrait> Graph<E> {
    pub fn is_tree(&self) -> bool {
        if self.edge_count + 1 != self.vertex_count() {
            false
        } else {
            self.is_connected()
        }
    }
    pub fn is_forest(&self) -> bool {
        let mut dsu = DSU::new(self.vertex_count());
        for i in 0..self.vertex_count() {
            for e in self[i].iter() {
                if i <= e.to() && !dsu.union(i, e.to()) {
                    return false;
                }
            }
        }
        true
    }
    pub fn is_connected(&self) -> bool {
        let mut dsu = DSU::new(self.vertex_count());
        for i in 0..self.vertex_count() {
            for e in self[i].iter() {
                dsu.union(i, e.to());
            }
        }
        dsu.set_count() == 1
    }
}
impl<E: EdgeTrait> Index<usize> for Graph<E> {
    type Output = [E];
    fn index(&self, index: usize) -> &Self::Output {
        &self.edges[index]
    }
}
impl<E: EdgeTrait> IndexMut<usize> for Graph<E> {
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        &mut self.edges[index]
    }
}
impl Graph<Edge<()>> {
    pub fn from_edges(n: usize, edges: &[(usize, usize)]) -> Self {
        let mut graph = Self::new(n);
        for &(from, to) in edges {
            graph.add_edge(Edge::new(from, to));
        }
        graph
    }
}
impl<P: Clone> Graph<Edge<P>> {
    pub fn from_edges_with_payload(n: usize, edges: &[(usize, usize, P)]) -> Self {
        let mut graph = Self::new(n);
        for (from, to, p) in edges.iter() {
            graph.add_edge(Edge::with_payload(*from, *to, p.clone()));
        }
        graph
    }
}
impl Graph<BiEdge<()>> {
    pub fn from_biedges(n: usize, edges: &[(usize, usize)]) -> Self {
        let mut graph = Self::new(n);
        for &(from, to) in edges {
            graph.add_edge(BiEdge::new(from, to));
        }
        graph
    }
}
impl<P: Clone> Graph<BiEdge<P>> {
    pub fn from_biedges_with_payload(n: usize, edges: &[(usize, usize, P)]) -> Self {
        let mut graph = Self::new(n);
        for (from, to, p) in edges.iter() {
            graph.add_edge(BiEdge::with_payload(*from, *to, p.clone()));
        }
        graph
    }
}
pub mod distances {
use crate::algo_lib::collections::indexed_heap::IndexedHeap;
use crate::algo_lib::graph::edges::weighted_edge_trait::WeightedEdgeTrait;
use crate::algo_lib::graph::Graph;
use crate::algo_lib::numbers::num_traits::algebra::AdditionMonoid;
pub trait Distances<W: AdditionMonoid + Ord + Copy> {
    fn distances_from(&self, source: usize) -> Vec<Option<(W, usize, usize)>>;
    fn distance(
        &self,
        source: usize,
        mut destination: usize,
    ) -> Option<(W, Vec<(usize, usize)>)> {
        let dist = self.distances_from(source);
        dist[destination]
            .map(|(w, ..)| {
                let mut path = Vec::new();
                while destination != source {
                    let (_, from, edge) = dist[destination].unwrap();
                    path.push((from, edge));
                    destination = from;
                }
                path.reverse();
                (w, path)
            })
    }
}
impl<W: AdditionMonoid + Ord + Copy, E: WeightedEdgeTrait<W>> Distances<W> for Graph<E> {
    fn distances_from(&self, source: usize) -> Vec<Option<(W, usize, usize)>> {
        let n = self.vertex_count();
        let mut res = vec![None; n];
        let mut heap = IndexedHeap::new(n);
        heap.add_or_adjust(source, (W::zero(), source, self[source].len()));
        while let Some((cur, dist)) = heap.pop() {
            res[cur] = Some(dist);
            let dist = dist.0;
            for (i, e) in self[cur].iter().enumerate() {
                let next = e.to();
                if res[next].is_some() {
                    continue;
                }
                let total = dist + e.weight();
                let next_dist = (total, cur, i);
                heap.add_or_relax(next, next_dist);
            }
        }
        res
    }
}
}
pub mod edges {
pub mod bi_edge {
use crate::algo_lib::graph::edges::bi_edge_trait::BiEdgeTrait;
use crate::algo_lib::graph::edges::edge_id::{EdgeId, NoId, WithId};
use crate::algo_lib::graph::edges::edge_trait::{BidirectionalEdgeTrait, EdgeTrait};
#[derive(Clone)]
pub struct BiEdgeRaw<Id: EdgeId, P> {
    to: u32,
    id: Id,
    payload: P,
}
impl<Id: EdgeId> BiEdgeRaw<Id, ()> {
    pub fn new(from: usize, to: usize) -> (usize, Self) {
        (
            from,
            Self {
                to: to as u32,
                id: Id::new(),
                payload: (),
            },
        )
    }
}
impl<Id: EdgeId, P> BiEdgeRaw<Id, P> {
    pub fn with_payload(from: usize, to: usize, payload: P) -> (usize, Self) {
        (from, Self::with_payload_impl(to, payload))
    }
    fn with_payload_impl(to: usize, payload: P) -> BiEdgeRaw<Id, P> {
        Self {
            to: to as u32,
            id: Id::new(),
            payload,
        }
    }
}
impl<Id: EdgeId, P: Clone> BidirectionalEdgeTrait for BiEdgeRaw<Id, P> {}
impl<Id: EdgeId, P: Clone> EdgeTrait for BiEdgeRaw<Id, P> {
    type Payload = P;
    const REVERSABLE: bool = true;
    fn to(&self) -> usize {
        self.to as usize
    }
    fn id(&self) -> usize {
        self.id.id()
    }
    fn set_id(&mut self, id: usize) {
        self.id.set_id(id);
    }
    fn reverse_id(&self) -> usize {
        panic!("no reverse id")
    }
    fn set_reverse_id(&mut self, _: usize) {}
    fn reverse_edge(&self, from: usize) -> Self {
        Self::with_payload_impl(from, self.payload.clone())
    }
    fn payload(&self) -> &P {
        &self.payload
    }
}
impl<Id: EdgeId, P: Clone> BiEdgeTrait for BiEdgeRaw<Id, P> {}
pub type BiEdge<P> = BiEdgeRaw<NoId, P>;
pub type BiEdgeWithId<P> = BiEdgeRaw<WithId, P>;
}
pub mod bi_edge_trait {
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
pub trait BiEdgeTrait: EdgeTrait {}
}
pub mod edge {
use crate::algo_lib::graph::edges::edge_id::{EdgeId, NoId, WithId};
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
#[derive(Clone)]
pub struct EdgeRaw<Id: EdgeId, P> {
    to: u32,
    id: Id,
    payload: P,
}
impl<Id: EdgeId> EdgeRaw<Id, ()> {
    pub fn new(from: usize, to: usize) -> (usize, Self) {
        (
            from,
            Self {
                to: to as u32,
                id: Id::new(),
                payload: (),
            },
        )
    }
}
impl<Id: EdgeId, P> EdgeRaw<Id, P> {
    pub fn with_payload(from: usize, to: usize, payload: P) -> (usize, Self) {
        (from, Self::with_payload_impl(to, payload))
    }
    fn with_payload_impl(to: usize, payload: P) -> Self {
        Self {
            to: to as u32,
            id: Id::new(),
            payload,
        }
    }
}
impl<Id: EdgeId, P: Clone> EdgeTrait for EdgeRaw<Id, P> {
    type Payload = P;
    const REVERSABLE: bool = false;
    fn to(&self) -> usize {
        self.to as usize
    }
    fn id(&self) -> usize {
        self.id.id()
    }
    fn set_id(&mut self, id: usize) {
        self.id.set_id(id);
    }
    fn reverse_id(&self) -> usize {
        panic!("no reverse")
    }
    fn set_reverse_id(&mut self, _: usize) {
        panic!("no reverse")
    }
    fn reverse_edge(&self, _: usize) -> Self {
        panic!("no reverse")
    }
    fn payload(&self) -> &P {
        &self.payload
    }
}
pub type Edge<P> = EdgeRaw<NoId, P>;
pub type EdgeWithId<P> = EdgeRaw<WithId, P>;
}
pub mod edge_id {
pub trait EdgeId: Clone {
    fn new() -> Self;
    fn id(&self) -> usize;
    fn set_id(&mut self, id: usize);
}
#[derive(Clone)]
pub struct WithId {
    id: u32,
}
impl EdgeId for WithId {
    fn new() -> Self {
        Self { id: 0 }
    }
    fn id(&self) -> usize {
        self.id as usize
    }
    fn set_id(&mut self, id: usize) {
        self.id = id as u32;
    }
}
#[derive(Clone)]
pub struct NoId {}
impl EdgeId for NoId {
    fn new() -> Self {
        Self {}
    }
    fn id(&self) -> usize {
        panic!("Id called on no id")
    }
    fn set_id(&mut self, _: usize) {}
}
}
pub mod edge_trait {
pub trait EdgeTrait: Clone {
    type Payload;
    const REVERSABLE: bool;
    fn to(&self) -> usize;
    fn id(&self) -> usize;
    fn set_id(&mut self, id: usize);
    fn reverse_id(&self) -> usize;
    fn set_reverse_id(&mut self, reverse_id: usize);
    #[must_use]
    fn reverse_edge(&self, from: usize) -> Self;
    fn payload(&self) -> &Self::Payload;
}
pub trait BidirectionalEdgeTrait: EdgeTrait {}
}
pub mod weighted_edge {
use crate::algo_lib::graph::edges::edge_id::{EdgeId, NoId, WithId};
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
use crate::algo_lib::graph::edges::weighted_edge_trait::WeightedEdgeTrait;
use crate::algo_lib::numbers::num_traits::algebra::AdditionMonoidWithSub;
#[derive(Clone)]
pub struct WeightedEdgeRaw<W: AdditionMonoidWithSub + Copy, Id: EdgeId, P> {
    to: u32,
    weight: W,
    id: Id,
    payload: P,
}
impl<W: AdditionMonoidWithSub + Copy, Id: EdgeId> WeightedEdgeRaw<W, Id, ()> {
    pub fn new(from: usize, to: usize, w: W) -> (usize, Self) {
        (
            from,
            Self {
                to: to as u32,
                weight: w,
                id: Id::new(),
                payload: (),
            },
        )
    }
}
impl<W: AdditionMonoidWithSub + Copy, Id: EdgeId, P> WeightedEdgeRaw<W, Id, P> {
    pub fn with_payload(from: usize, to: usize, w: W, payload: P) -> (usize, Self) {
        (from, Self::with_payload_impl(to, w, payload))
    }
    fn with_payload_impl(to: usize, w: W, payload: P) -> Self {
        Self {
            to: to as u32,
            weight: w,
            id: Id::new(),
            payload,
        }
    }
}
impl<W: AdditionMonoidWithSub + Copy, Id: EdgeId, P: Clone> EdgeTrait
for WeightedEdgeRaw<W, Id, P> {
    type Payload = P;
    const REVERSABLE: bool = false;
    fn to(&self) -> usize {
        self.to as usize
    }
    fn id(&self) -> usize {
        self.id.id()
    }
    fn set_id(&mut self, id: usize) {
        self.id.set_id(id);
    }
    fn reverse_id(&self) -> usize {
        panic!("no reverse")
    }
    fn set_reverse_id(&mut self, _: usize) {
        panic!("no reverse")
    }
    fn reverse_edge(&self, _: usize) -> Self {
        panic!("no reverse")
    }
    fn payload(&self) -> &P {
        &self.payload
    }
}
impl<W: AdditionMonoidWithSub + Copy, Id: EdgeId, P: Clone> WeightedEdgeTrait<W>
for WeightedEdgeRaw<W, Id, P> {
    fn weight(&self) -> W {
        self.weight
    }
    fn weight_mut(&mut self) -> &mut W {
        &mut self.weight
    }
}
pub type WeightedEdge<W, P> = WeightedEdgeRaw<W, NoId, P>;
pub type WeightedEdgeWithId<W, P> = WeightedEdgeRaw<W, WithId, P>;
}
pub mod weighted_edge_trait {
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
pub trait WeightedEdgeTrait<W: Copy>: EdgeTrait {
    fn weight(&self) -> W;
    fn weight_mut(&mut self) -> &mut W;
}
}
}
}
pub mod io {
pub mod input {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use std::io::Read;
use std::mem::MaybeUninit;
pub struct Input<'s> {
    input: &'s mut (dyn Read + Send),
    buf: Vec<u8>,
    at: usize,
    buf_read: usize,
    eol: bool,
}
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,
            eol: true,
        }
    }
    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,
            eol: true,
        }
    }
    pub fn get(&mut self) -> Option<u8> {
        if self.refill_buffer() {
            let res = self.buf[self.at];
            self.at += 1;
            if res == b'\r' {
                self.eol = true;
                if self.refill_buffer() && self.buf[self.at] == b'\n' {
                    self.at += 1;
                }
                return Some(b'\n');
            }
            self.eol = res == 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) }
    }
    pub fn is_exhausted(&mut self) -> bool {
        self.peek().is_none()
    }
    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 fn is_eol(&self) -> bool {
        self.eol
    }
}
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)
    }
}
impl<T: Readable, const SIZE: usize> Readable for [T; SIZE] {
    fn read(input: &mut Input) -> Self {
        unsafe {
            let mut res = MaybeUninit::<[T; SIZE]>::uninit();
            for i in 0..SIZE {
                let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
                ptr.add(i).write(input.read::<T>());
            }
            res.assume_init()
        }
    }
}
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, Stderr, 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,
    precision: Option<usize>,
    separator: u8,
}
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,
            precision: None,
            separator: b' ',
        }
    }
    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,
            precision: None,
            separator: b' ',
        }
    }
    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(self.separator);
            }
            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;
    }
    pub fn set_precision(&mut self, precision: usize) {
        self.precision = Some(precision);
    }
    pub fn reset_precision(&mut self) {
        self.precision = None;
    }
    pub fn get_precision(&self) -> Option<usize> {
        self.precision
    }
    pub fn separator(&self) -> u8 {
        self.separator
    }
    pub fn set_separator(&mut self, separator: u8) {
        self.separator = separator;
    }
}
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(out
        .separator); 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 maybe {
use std::mem;
use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};
pub union Maybe<T> {
    pub value: ManuallyDrop<T>,
    pub none: (),
}
impl<T> Maybe<T> {
    pub fn new(value: T) -> Self {
        Self {
            value: ManuallyDrop::new(value),
        }
    }
    pub fn none() -> Self {
        Self { none: () }
    }
    pub unsafe fn take(&mut self) -> T {
        unsafe { ManuallyDrop::into_inner(mem::replace(self, Maybe::none()).value) }
    }
    pub unsafe fn as_ref(&self) -> &T {
        self.value.deref()
    }
    pub unsafe fn as_mut(&mut self) -> &mut T {
        self.value.deref_mut()
    }
    pub unsafe fn drop(&mut self) {
        unsafe { ManuallyDrop::drop(&mut self.value) }
    }
}
}
pub mod test_type {
pub enum TestType {
    Single,
    MultiNumber,
    MultiEof,
}
pub enum TaskType {
    Classic,
    Interactive,
}
}
}
pub mod numbers {
pub mod num_traits {
pub mod algebra {
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use std::ops::{
    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, 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 invertible {
pub trait Invertible {
    type Output;
    fn inv(&self) -> Option<Self::Output>;
}
}
}
}
}

Information

Submit By
Type
Submission
Problem
P1156 Low cost water management
Contest
Happy New Year 2025
Language
Rust 2021 (Rust 1.75.0)
Submit At
2025-01-02 15:17:41
Judged At
2025-01-02 15:17:41
Judged By
Score
1
Total Time
≥2177ms
Peak Memory
≥512.016 MiB