QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#756496#9558. The Devilucup-team296#TL 0ms2376kbRust104.0kb2024-11-16 20:41:412024-11-16 20:41:46

Judging History

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

  • [2024-11-16 20:41:46]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:2376kb
  • [2024-11-16 20:41:41]
  • 提交

answer

// https://contest.ucup.ac/contest/1843/problem/9558
pub mod solution {
//{"name":"K. The Devil","group":"Universal Cup - The 3rd Universal Cup. Stage 17: Jinan","url":"https://contest.ucup.ac/contest/1843/problem/9558","interactive":false,"timeLimit":1000,"tests":[{"input":"5\nautomated teller machine\nactive teller machine\nactive trouble maker\nalways telling misinformation\nAmerican Teller Machinery\n","output":"atm\natma\nactm\natem\nATM\n"},{"input":"5\nForest Conservation Committee Forum\nFuming Corruption Collusion Federation\nFulsome Cash Concealment Foundation\nFunky Crony Capitalism Facilitator\nFunny Cocky Cocky Funny\n","output":"FCCF\nFCCoF\nFCCFo\nFuCCF\nFCoCF\n"},{"input":"3\nA AA\nAA A\nA A A\n","output":"no solution\n"}],"testType":"single","input":{"type":"stdin","fileName":null,"pattern":null},"output":{"type":"stdout","fileName":null,"pattern":null},"languages":{"java":{"taskClass":"KTheDevil"}}}

use crate::algo_lib::collections::default_map::default_hash_map::DefaultHashMap;
use crate::algo_lib::collections::fx_hash_map::FxHashMap;
use crate::algo_lib::collections::iter_ext::collect::IterCollect;
// use algo_lib::collections::slice_ext::indices::Indices;
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
use crate::algo_lib::graph::edges::flow_edge_trait::FlowEdgeTrait;
use crate::algo_lib::graph::edges::weighted_flow_edge::WeightedFlowEdge;
use crate::algo_lib::graph::min_cost_flow::CostAndFlow;
use crate::algo_lib::graph::min_cost_flow::MinCostFlow;
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;
use crate::algo_lib::string::hash::CompositeHash;
use crate::algo_lib::string::hash::HashBase;
use crate::algo_lib::string::hash::SimpleHash;
use crate::algo_lib::string::hash::StringHash;
use crate::algo_lib::string::str::Str;
use crate::algo_lib::string::str::StrReader;

type PreCalc = ();

fn solve(input: &mut Input, out: &mut Output, _test_case: usize, _data: &mut PreCalc) {
    let n = input.read_size();
    let s = (0..n)
        .map(|_| {
            input
                .read_line()
                .split(' ')
                .into_iter()
                .map(|x| x.into_owned())
                .collect_vec()
        })
        .collect_vec();

    HashBase::init();
    let mut map = DefaultHashMap::<_, Vec<_>>::new();
    for i in 0..n {
        let total = s[i].iter().map(|x| x.len()).sum::<usize>();
        let hh = s[i].iter().map(|x| SimpleHash::new(x)).collect_vec();
        let mut done = 0;
        let mut cur = vec![vec![FxHashMap::default(); s[i].len() + 1]];
        cur[0][0].insert(0, (Str::new(), SimpleHash::new(&[] as &[u8])));
        for j in s[i].len()..=total {
            let leeway = j - s[i].len();
            cur.push(vec![FxHashMap::default(); s[i].len() + 1]);
            for (x, word) in s[i].iter().enumerate() {
                let start = if cur[leeway][x].len() + done == n {
                    leeway
                } else {
                    0
                };
                for k in start..=leeway {
                    if word.len() < leeway - k + 1 {
                        continue;
                    }
                    let l = leeway - k + 1;
                    let (check, add) = if k == leeway {
                        let (head, tail) = cur[leeway].split_at_mut(x + 1);
                        (&mut head[x], &mut tail[0])
                    } else {
                        let (head, tail) = cur.split_at_mut(leeway);
                        (&mut head[k][x], &mut tail[0][x + 1])
                    };
                    for ww in check.values() {
                        let ch = CompositeHash::new(&ww.1, &hh[x]);
                        let key = ch.hash(..ww.0.len() + l);
                        if !add.contains_key(&key) {
                            let s = ww.0.clone() + &word[..l];
                            let h = SimpleHash::new(&s);
                            add.insert(key, (s, h));
                            if add.len() + done == n {
                                break;
                            }
                        }
                    }
                    if cur[leeway][x + 1].len() + done == n {
                        break;
                    }
                }
            }
            for (word, _) in cur[leeway][s[i].len()].values() {
                // eprintln!("{} {}", word, i);
                map[word.clone()].push(i);
                done += 1;
            }
            if done == n {
                break;
            }
            assert!(done < n);
        }
    }
    let mut graph = Graph::new(map.len() + n + 2);
    let source = graph.vertex_count() - 2;
    let sink = graph.vertex_count() - 1;
    for (i, (w, val)) in map.iter().enumerate() {
        graph.add_edge(WeightedFlowEdge::new(source, i, w.len() as i64, 1));
        for &j in val {
            graph.add_edge(WeightedFlowEdge::new(i, map.len() + j, 0, 1));
        }
    }
    for i in 0..n {
        graph.add_edge(WeightedFlowEdge::new(map.len() + i, sink, 0, 1));
    }
    let CostAndFlow { flow, .. } = graph.min_cost_max_flow(source, sink);
    if flow != n as i64 {
        out.print_line("no solution");
        return;
    }
    let mut ans = vec![Str::new(); n];
    for (i, (w, _)) in map.iter().enumerate() {
        for edge in &graph[i] {
            let to = edge.to();
            if to >= map.len() && to < map.len() + n && edge.flow(&graph) == 1 {
                ans[to - map.len()] = w.clone();
            }
        }
    }
    out.print_per_line(&ans);
}

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 {
#![allow(clippy::too_many_arguments)]
#![allow(clippy::type_complexity)]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::legacy_numeric_constants)]

pub mod collections {
pub mod default_map {
pub mod default_hash_map {
use crate::algo_lib::collections::fx_hash_map::FxHashMap;
use std::hash::Hash;
use std::iter::FromIterator;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ops::Index;
use std::ops::IndexMut;

#[derive(Default, Clone, Eq, PartialEq, Debug)]
pub struct DefaultHashMap<K: Hash + Eq, V>(FxHashMap<K, V>, V);

impl<K: Hash + Eq, V> Deref for DefaultHashMap<K, V> {
    type Target = FxHashMap<K, V>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<K: Hash + Eq, V> DerefMut for DefaultHashMap<K, V> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl<K: Hash + Eq, V: Default> DefaultHashMap<K, V> {
    pub fn new() -> Self {
        Self(FxHashMap::default(), V::default())
    }

    pub fn get(&self, key: &K) -> &V {
        self.0.get(key).unwrap_or(&self.1)
    }

    pub fn get_mut(&mut self, key: K) -> &mut V {
        self.0.entry(key).or_insert_with(|| V::default())
    }

    pub fn into_values(self) -> std::collections::hash_map::IntoValues<K, V> {
        self.0.into_values()
    }
}

impl<K: Hash + Eq, V: Default> Index<K> for DefaultHashMap<K, V> {
    type Output = V;

    fn index(&self, index: K) -> &Self::Output {
        self.get(&index)
    }
}

impl<K: Hash + Eq, V: Default> IndexMut<K> for DefaultHashMap<K, V> {
    fn index_mut(&mut self, index: K) -> &mut Self::Output {
        self.get_mut(index)
    }
}

impl<K: Hash + Eq, V> IntoIterator for DefaultHashMap<K, V> {
    type Item = (K, V);
    type IntoIter = std::collections::hash_map::IntoIter<K, V>;

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

impl<K: Hash + Eq, V: Default> FromIterator<(K, V)> for DefaultHashMap<K, V> {
    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
        Self(iter.into_iter().collect(), V::default())
    }
}
}
}
pub mod dsu {
use crate::algo_lib::collections::iter_ext::collect::IterCollect;
use crate::algo_lib::collections::slice_ext::bounds::Bounds;
use crate::algo_lib::collections::slice_ext::legacy_fill::LegacyFill;
use std::cell::Cell;

#[derive(Clone)]
pub struct DSU {
    id: Vec<Cell<u32>>,
    size: Vec<u32>,
    count: usize,
}

impl DSU {
    pub fn new(n: usize) -> Self {
        Self {
            id: (0..n).map(|i| Cell::new(i as u32)).collect_vec(),
            size: vec![1; n],
            count: n,
        }
    }

    pub fn size(&self, i: usize) -> usize {
        self.size[self.get(i)] 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 (i as u32) == id.get() {
                Some(i)
            } else {
                None
            }
        })
    }

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

    pub fn join(&mut self, mut a: usize, mut b: usize) -> bool {
        a = self.get(a);
        b = self.get(b);
        if a == b {
            false
        } else {
            self.size[a] += self.size[b];
            self.id[b].replace(a as u32);
            self.count -= 1;
            true
        }
    }

    pub fn get(&self, i: usize) -> usize {
        if self.id[i].get() != i as u32 {
            let res = self.get(self.id[i].get() as usize);
            self.id[i].replace(res as u32);
        }
        self.id[i].get() as usize
    }

    pub fn clear(&mut self) {
        self.count = self.id.len();
        self.size.legacy_fill(1);
        self.id.iter().enumerate().for_each(|(i, id)| {
            id.replace(i as u32);
        });
    }

    pub fn parts(&self) -> Vec<Vec<usize>> {
        let roots = self.iter().collect_vec();
        let mut res = vec![Vec::new(); roots.len()];
        for i in 0..self.id.len() {
            res[roots.as_slice().bin_search(&self.get(i)).unwrap()].push(i);
        }
        res
    }
}
}
pub mod fx_hash_map {
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cell::Cell;
use std::convert::TryInto;
use std::time::SystemTime;
use std::collections::HashMap;
use std::collections::HashSet;
use std::hash::BuildHasherDefault;
use std::hash::Hasher;
use std::mem::size_of;
use std::ops::BitXor;

pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;

pub type FxHashSet<V> = HashSet<V, BuildHasherDefault<FxHasher>>;

#[derive(Default)]
pub struct FxHasher {
    hash: usize,
}

thread_local! {
    static K: Cell<usize> = Cell::new(
        ((SystemTime::UNIX_EPOCH.elapsed().unwrap().as_nanos().wrapping_mul(2) + 1) & 0xFFFFFFFFFFFFFFFF) as usize
    );
}

impl FxHasher {
    #[inline]
    fn add_to_hash(&mut self, i: usize) {
        self.hash = self
            .hash
            .rotate_left(5)
            .bitxor(i)
            .wrapping_mul(K.with(|k| k.get()));
    }
}

impl Hasher for FxHasher {
    #[inline]
    fn write(&mut self, mut bytes: &[u8]) {
        let read_usize = |bytes: &[u8]| u64::from_ne_bytes(bytes[..8].try_into().unwrap());

        let mut hash = FxHasher { hash: self.hash };
        while bytes.len() >= size_of::<usize>() {
            hash.add_to_hash(read_usize(bytes) as usize);
            bytes = &bytes[size_of::<usize>()..];
        }
        if (size_of::<usize>() > 4) && (bytes.len() >= 4) {
            hash.add_to_hash(u32::from_ne_bytes(bytes[..4].try_into().unwrap()) as usize);
            bytes = &bytes[4..];
        }
        if (size_of::<usize>() > 2) && bytes.len() >= 2 {
            hash.add_to_hash(u16::from_ne_bytes(bytes[..2].try_into().unwrap()) as usize);
            bytes = &bytes[2..];
        }
        if (size_of::<usize>() > 1) && !bytes.is_empty() {
            hash.add_to_hash(bytes[0] as usize);
        }
        self.hash = hash.hash;
    }

    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.add_to_hash(i as usize);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.add_to_hash(i as usize);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.add_to_hash(i as usize);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.add_to_hash(i as usize);
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.add_to_hash(i);
    }

    #[inline]
    fn finish(&self) -> u64 {
        self.hash as u64
    }
}
}
pub mod indexed_heap {
use crate::algo_lib::collections::slice_ext::legacy_fill::LegacyFill;
use std::mem;

#[derive(Default)]
enum Opt<T> {
    #[default]
    None,
    Some(u32, T),
}

impl<T> Opt<T> {
    fn index(&self) -> usize {
        match self {
            Opt::None => panic!("unreachable"),
            Opt::Some(index, _) => *index as usize,
        }
    }

    fn val(&self) -> &T {
        match self {
            Opt::None => panic!("unreachable"),
            Opt::Some(_, val) => val,
        }
    }

    fn set_index(&mut self, index: usize) {
        match self {
            Opt::None => panic!("unreachable"),
            Opt::Some(ind, _) => {
                *ind = index as u32;
            }
        }
    }

    fn set_val(&mut self, t: T) {
        match self {
            Opt::None => panic!("unreachable"),
            Opt::Some(_, val) => {
                *val = t;
            }
        }
    }

    fn take(&mut self) -> (usize, T) {
        let val = mem::take(self);
        match val {
            Opt::None => panic!("unreachable"),
            Opt::Some(ind, val) => (ind as usize, val),
        }
    }
}

impl<T> Clone for Opt<T> {
    fn clone(&self) -> Self {
        match self {
            Opt::None => Opt::None,
            Opt::Some(..) => panic!("unreachable"),
        }
    }
}

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: vec![Opt::None; 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) {
        match self.pos[el] {
            Opt::None => {
                self.pos[el] = Opt::Some(self.heap.len() as u32, val);
                self.heap.push(el as u32);
            }
            Opt::Some(..) => {
                self.pos[el].set_val(val);
            }
        }
        self.sift_up(self.pos[el].index());
        self.sift_down(self.pos[el].index());
    }

    pub fn add_or_relax(&mut self, el: usize, val: T) {
        match &self.pos[el] {
            Opt::None => {
                self.add_or_adjust(el, val);
            }
            Opt::Some(_, value) => {
                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();
        self.pos.legacy_fill(Opt::None);
    }

    pub fn remove(&mut self, el: usize) -> Option<T> {
        match self.pos[el] {
            Opt::None => None,
            Opt::Some(pos, _) => {
                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] = Opt::Some(pos, val);
                    self.heap[pos as usize] = last;
                    self.sift_down(pos as usize);
                    self.sift_up(pos as usize);
                    Some(top_val)
                }
            }
        }
    }

    pub fn value(&self, el: usize) -> Option<&T> {
        match &self.pos[el] {
            Opt::None => None,
            Opt::Some(_, val) => Some(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 collect {
pub trait IterCollect<T>: Iterator<Item = T> + Sized {
    fn collect_vec(self) -> Vec<T> {
        self.collect()
    }
}

impl<T, I: Iterator<Item = T> + Sized> IterCollect<T> for I {}
}
}
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 backward {
use std::ops::Index;
use std::ops::IndexMut;

pub struct Back(pub usize);

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

    fn index(&self, index: Back) -> &Self::Output {
        &self[self.len() - index.0 - 1]
    }
}

impl<T> IndexMut<Back> for [T] {
    fn index_mut(&mut self, index: Back) -> &mut Self::Output {
        &mut self[self.len() - index.0 - 1]
    }
}

impl<T> Index<Back> for Vec<T> {
    type Output = T;

    fn index(&self, index: Back) -> &Self::Output {
        self.as_slice().index(index)
    }
}

impl<T> IndexMut<Back> for Vec<T> {
    fn index_mut(&mut self, index: Back) -> &mut Self::Output {
        self.as_mut_slice().index_mut(index)
    }
}
}
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;
    fn less_or_eq(&self, el: &T) -> usize;
}

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)
    }

    fn less(&self, el: &T) -> usize {
        self.lower_bound(el)
    }

    fn less_or_eq(&self, el: &T) -> usize {
        self.upper_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 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 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;
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
use std::ops::Index;
use std::ops::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.join(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.join(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 edges {
pub mod bi_edge {
use crate::algo_lib::graph::edges::bi_edge_trait::BiEdgeTrait;
use crate::algo_lib::graph::edges::edge_id::EdgeId;
use crate::algo_lib::graph::edges::edge_id::NoId;
use crate::algo_lib::graph::edges::edge_id::WithId;
use crate::algo_lib::graph::edges::edge_trait::BidirectionalEdgeTrait;
use crate::algo_lib::graph::edges::edge_trait::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;
use crate::algo_lib::graph::edges::edge_id::NoId;
use crate::algo_lib::graph::edges::edge_id::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 flow_edge_trait {
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
use crate::algo_lib::graph::Graph;
use crate::algo_lib::numbers::num_traits::algebra::AdditionMonoidWithSub;

pub trait FlowEdgeTrait<C: AdditionMonoidWithSub + PartialOrd + Copy>: EdgeTrait {
    fn capacity(&self) -> C;
    fn capacity_mut(&mut self) -> &mut C;
    fn flow(&self, graph: &Graph<Self>) -> C;
    fn push_flow(&self, flow: C) -> (usize, usize, C) {
        (self.to(), self.reverse_id(), flow)
    }
}
}
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 weighted_flow_edge {
use crate::algo_lib::graph::edges::edge_id::EdgeId;
use crate::algo_lib::graph::edges::edge_id::NoId;
use crate::algo_lib::graph::edges::edge_id::WithId;
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
use crate::algo_lib::graph::edges::flow_edge_trait::FlowEdgeTrait;
use crate::algo_lib::graph::edges::weighted_edge_trait::WeightedEdgeTrait;
use crate::algo_lib::graph::Graph;
use crate::algo_lib::numbers::num_traits::algebra::AdditionGroup;
use crate::algo_lib::numbers::num_traits::algebra::AdditionMonoidWithSub;

#[derive(Clone)]
pub struct WeightedFlowEdgeRaw<
    W: AdditionGroup + Copy,
    C: AdditionMonoidWithSub + Ord + Copy,
    Id: EdgeId,
    P,
> {
    to: u32,
    weight: W,
    capacity: C,
    reverse_id: u32,
    id: Id,
    payload: P,
}

impl<W: AdditionGroup + Copy, C: AdditionMonoidWithSub + Ord + Copy, Id: EdgeId>
    WeightedFlowEdgeRaw<W, C, Id, ()>
{
    pub fn new(from: usize, to: usize, w: W, c: C) -> (usize, Self) {
        (
            from,
            Self {
                to: to as u32,
                weight: w,
                capacity: c,
                reverse_id: 0,
                id: Id::new(),
                payload: (),
            },
        )
    }
}

impl<W: AdditionGroup + Copy, C: AdditionMonoidWithSub + Ord + Copy, Id: EdgeId, P>
    WeightedFlowEdgeRaw<W, C, Id, P>
{
    pub fn with_payload(from: usize, to: usize, w: W, c: C, payload: P) -> (usize, Self) {
        (from, Self::with_payload_impl(to, w, c, payload))
    }

    fn with_payload_impl(to: usize, w: W, c: C, payload: P) -> Self {
        Self {
            to: to as u32,
            weight: w,
            capacity: c,
            reverse_id: 0,
            id: Id::new(),
            payload,
        }
    }
}

impl<
        W: AdditionGroup + Copy,
        C: AdditionMonoidWithSub + Ord + Copy,
        Id: EdgeId,
        P: Clone + Default,
    > EdgeTrait for WeightedFlowEdgeRaw<W, C, 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 {
        self.reverse_id as usize
    }

    fn set_reverse_id(&mut self, reverse_id: usize) {
        self.reverse_id = reverse_id as u32;
    }

    fn reverse_edge(&self, from: usize) -> Self {
        Self::with_payload_impl(from, -self.weight, C::zero(), P::default())
    }

    fn payload(&self) -> &P {
        &self.payload
    }
}

impl<
        W: AdditionGroup + Copy,
        C: AdditionMonoidWithSub + Ord + Copy,
        Id: EdgeId,
        P: Clone + Default,
    > WeightedEdgeTrait<W> for WeightedFlowEdgeRaw<W, C, Id, P>
{
    fn weight(&self) -> W {
        self.weight
    }

    fn weight_mut(&mut self) -> &mut W {
        &mut self.weight
    }
}

impl<
        W: AdditionGroup + Copy,
        C: AdditionMonoidWithSub + Ord + Copy,
        Id: EdgeId,
        P: Clone + Default,
    > FlowEdgeTrait<C> for WeightedFlowEdgeRaw<W, C, Id, P>
{
    fn capacity(&self) -> C {
        self.capacity
    }

    fn capacity_mut(&mut self) -> &mut C {
        &mut self.capacity
    }

    fn flow(&self, graph: &Graph<Self>) -> C {
        graph[self.to as usize][self.reverse_id as usize].capacity
    }
}

pub type WeightedFlowEdge<W, C, P> = WeightedFlowEdgeRaw<W, C, NoId, P>;
pub type WeightedFlowEdgeWithId<W, C, P> = WeightedFlowEdgeRaw<W, C, WithId, P>;
}
}
pub mod flow_graph {
use crate::algo_lib::graph::edges::flow_edge_trait::FlowEdgeTrait;
use crate::algo_lib::graph::Graph;
use crate::algo_lib::numbers::num_traits::algebra::AdditionMonoidWithSub;

pub trait FlowGraph<C: AdditionMonoidWithSub + PartialOrd + Copy, E: FlowEdgeTrait<C>> {
    fn push_flow(&mut self, push_data: (usize, usize, C));
}

impl<C: AdditionMonoidWithSub + PartialOrd + Copy, E: FlowEdgeTrait<C>> FlowGraph<C, E>
    for Graph<E>
{
    fn push_flow(&mut self, (to, reverse_id, flow): (usize, usize, C)) {
        *self.edges[to][reverse_id].capacity_mut() += flow;
        let from = self.edges[to][reverse_id].to();
        let direct_id = self.edges[to][reverse_id].reverse_id();
        let direct = &mut self.edges[from][direct_id];
        assert!(flow >= C::zero() && flow <= direct.capacity());
        *direct.capacity_mut() -= flow;
    }
}
}
pub mod min_cost_flow {
use crate::algo_lib::collections::indexed_heap::IndexedHeap;
use crate::algo_lib::collections::min_max::MinimMaxim;
use crate::algo_lib::collections::slice_ext::legacy_fill::LegacyFill;
use crate::algo_lib::graph::edges::edge_id::EdgeId;
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
use crate::algo_lib::graph::edges::flow_edge_trait::FlowEdgeTrait;
use crate::algo_lib::graph::edges::weighted_edge_trait::WeightedEdgeTrait;
use crate::algo_lib::graph::edges::weighted_flow_edge::WeightedFlowEdgeRaw;
use crate::algo_lib::graph::flow_graph::FlowGraph;
use crate::algo_lib::graph::Graph;
use crate::algo_lib::numbers::num_traits::algebra::Ring;
use crate::algo_lib::numbers::num_traits::bit_ops::Bits;
use crate::algo_lib::numbers::num_traits::ord::MinMax;
use std::fmt::Display;

pub struct CostAndFlow<C> {
    pub cost: C,
    pub flow: C,
}

pub trait MinCostFlow<C> {
    fn min_cost_flow(&mut self, source: usize, sink: usize) -> CostAndFlow<C>;
    fn min_cost_max_flow(&mut self, source: usize, sink: usize) -> CostAndFlow<C>;
}

fn min_cost_flow_impl<C, Id, P: Clone + Default>(
    or_graph: &mut Graph<WeightedFlowEdgeRaw<C, C, Id, P>>,
    source: usize,
    sink: usize,
    take_positive_cycles: bool,
) -> CostAndFlow<C>
where
    C: Ring + Ord + Copy + MinMax + Bits + Display,
    Id: EdgeId,
{
    let inf = C::max_val() >> 1;

    let n = or_graph.vertex_count();
    let mut p = vec![C::zero(); n + 1];
    p[n] = inf;

    let mut graph = Graph::new(n + 1);
    let mut corresponding = Vec::new();
    let mut max_capacity = C::zero();
    let mut sum_weight = C::zero();
    for i in 0..n {
        for (j, e) in or_graph[i].iter().enumerate() {
            if e.capacity() > C::zero() {
                max_capacity.maxim(e.capacity());
                sum_weight += e.weight().max(C::zero() - e.weight());
                corresponding.push((
                    i,
                    j,
                    graph.add_edge(WeightedFlowEdgeRaw::new(i, e.to(), e.weight(), C::zero())),
                ));
            }
        }
    }
    let mut bits = 0usize;
    while (C::one() << bits) <= max_capacity {
        bits += 1;
    }
    let back = graph.add_edge(WeightedFlowEdgeRaw::new(
        sink,
        source,
        if take_positive_cycles {
            C::zero() - sum_weight - C::one()
        } else {
            C::zero()
        },
        C::zero(),
    ));
    for i in 0..n {
        graph.add_edge(WeightedFlowEdgeRaw::new(n, i, C::zero(), C::one()));
    }

    let mut dis = vec![C::zero(); n + 1];
    let mut pre = vec![(0usize, 0usize); n + 1];
    let mut heap = IndexedHeap::new(n + 1);

    let c = |from: usize, e: &WeightedFlowEdgeRaw<C, C, Id, ()>, p: &Vec<C>| -> C {
        p[from] + e.weight() - p[e.to()]
    };

    let dijkstra = |graph: &mut Graph<WeightedFlowEdgeRaw<C, C, Id, ()>>,
                    dis: &mut Vec<C>,
                    pre: &mut Vec<(usize, usize)>,
                    heap: &mut IndexedHeap<C>,
                    p: &Vec<C>,
                    s: usize| {
        dis.legacy_fill(inf);
        dis[s] = C::zero();
        assert!(heap.is_empty());
        heap.add_or_adjust(s, C::zero());

        while let Some((u, w)) = heap.pop() {
            assert!(w == dis[u]);
            for (i, e) in graph[u].iter().enumerate() {
                let v = e.to();

                debug_assert!(e.capacity() <= C::zero() || c(u, e, p) >= C::zero());

                if e.capacity() > C::zero() && dis[v] > w + c(u, e, p) {
                    dis[v] = w + c(u, e, p);
                    pre[v] = (u, i);
                    heap.add_or_adjust(v, dis[v]);
                }
            }
        }
    };

    let mut add_one =
        |graph: &mut Graph<WeightedFlowEdgeRaw<C, C, Id, ()>>, from: usize, id: usize| {
            if graph[from][id].capacity() > C::zero() {
                *graph[from][id].capacity_mut() += C::one();
                return;
            }
            let mut u = from;
            let e = &graph[from][id];
            let v = e.to();
            let cur_len = c(u, e, &p);
            dijkstra(graph, &mut dis, &mut pre, &mut heap, &p, v);
            let e = &graph[from][id];
            if dis[u] < inf && dis[u] + c(u, e, &p) < C::zero() {
                let rev_id = e.reverse_id();
                *graph[v][rev_id].capacity_mut() += C::one();
                while u != v {
                    graph.push_flow(graph[pre[u].0][pre[u].1].push_flow(C::one()));
                    u = pre[u].0;
                }
            } else {
                *graph[from][id].capacity_mut() += C::one();
            }
            let mut max_dis = C::zero();
            for i in dis.iter().take(n) {
                if *i != inf {
                    max_dis.maxim(*i);
                }
            }
            for i in 0..n {
                p[i] += if dis[i] < inf {
                    dis[i]
                } else {
                    max_dis
                        + if cur_len > C::zero() {
                            cur_len
                        } else {
                            C::zero() - cur_len
                        }
                };
            }
            dijkstra(graph, &mut dis, &mut pre, &mut heap, &p, n);
            for i in 0..n {
                let npi = dis[i] - p[n];
                p[i] += npi;
            }
        };

    add_one(&mut graph, sink, back);
    for i in (0..bits).rev() {
        for j in 0..=n {
            for e in graph[j].iter_mut() {
                *e.capacity_mut() <<= 1;
            }
        }
        for (from, self_edge_id, graph_edge_id) in corresponding.iter() {
            if or_graph[*from][*self_edge_id].capacity().is_set(i) {
                add_one(&mut graph, *from, *graph_edge_id);
                if graph[sink][back].capacity() == C::one() {
                    *graph[sink][back].capacity_mut() += C::one();
                }
            }
        }
    }

    let mut min_cost = C::zero();
    let max_flow = graph[sink][back].flow(&graph);
    for (from, self_edge_id, graph_edge_id) in corresponding {
        let x = &graph[from][graph_edge_id];
        min_cost += x.flow(&graph) * x.weight();
        or_graph.push_flow(or_graph[from][self_edge_id].push_flow(x.flow(&graph)));
    }
    CostAndFlow {
        cost: min_cost,
        flow: max_flow,
    }
}

impl<C, Id, P: Clone + Default> MinCostFlow<C> for Graph<WeightedFlowEdgeRaw<C, C, Id, P>>
where
    C: Ring + Ord + Copy + MinMax + Bits + Display,
    Id: EdgeId,
{
    fn min_cost_flow(&mut self, source: usize, sink: usize) -> CostAndFlow<C> {
        min_cost_flow_impl(self, source, sink, false)
    }

    fn min_cost_max_flow(&mut self, source: usize, sink: usize) -> CostAndFlow<C> {
        min_cost_flow_impl(self, source, sink, true)
    }
}
}
}
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,
}

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)
    }
}

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;
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,
    precision: Option<usize>,
}

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,
        }
    }

    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,
        }
    }

    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;
    }
    pub fn set_precision(&mut self, precision: Option<usize>) {
        self.precision = precision;
    }
    pub fn get_precision(&self) -> Option<usize> {
        self.precision
    }
}

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 random {
use crate::algo_lib::collections::slice_ext::indices::Indices;
use crate::algo_lib::numbers::num_traits::algebra::IntegerSemiRingWithSub;
use crate::algo_lib::numbers::num_traits::primitive::Primitive;
use std::ops::Rem;
use std::time::SystemTime;

const NN: usize = 312;
const MM: usize = 156;
const MATRIX_A: u64 = 0xB5026F5AA96619E9;
const UM: u64 = 0xFFFFFFFF80000000;
const LM: u64 = 0x7FFFFFFF;
const F: u64 = 6364136223846793005;
const MAG01: [u64; 2] = [0, MATRIX_A];

pub struct Random {
    mt: [u64; NN],
    index: usize,
}

impl Random {
    pub fn new(seed: u64) -> Self {
        let mut res = Self {
            mt: [0u64; NN],
            index: NN,
        };
        res.mt[0] = seed;
        for i in 1..NN {
            res.mt[i] = F
                .wrapping_mul(res.mt[i - 1] ^ (res.mt[i - 1] >> 62))
                .wrapping_add(i as u64);
        }
        res
    }

    pub fn gen(&mut self) -> u64 {
        if self.index == NN {
            for i in 0..(NN - MM) {
                let x = (self.mt[i] & UM) | (self.mt[i + 1] & LM);
                self.mt[i] = self.mt[i + MM] ^ (x >> 1) ^ MAG01[(x & 1) as usize];
            }
            for i in (NN - MM)..(NN - 1) {
                let x = (self.mt[i] & UM) | (self.mt[i + 1] & LM);
                self.mt[i] = self.mt[i + MM - NN] ^ (x >> 1) ^ MAG01[(x & 1) as usize];
            }
            let x = (self.mt[NN - 1] & UM) | (self.mt[0] & LM);
            self.mt[NN - 1] = self.mt[MM - 1] ^ (x >> 1) ^ MAG01[(x & 1) as usize];
            self.index = 0;
        }
        let mut x = self.mt[self.index];
        self.index += 1;
        x ^= (x >> 29) & 0x5555555555555555;
        x ^= (x << 17) & 0x71D67FFFEDA60000;
        x ^= (x << 37) & 0xFFF7EEE000000000;
        x ^= x >> 43;
        x
    }

    pub fn next<T: Rem<Output = T> + Primitive<u64>>(&mut self, n: T) -> T
    where
        u64: Primitive<T>,
    {
        (self.gen() % n.to()).to()
    }

    pub fn next_bounds<T: IntegerSemiRingWithSub + Primitive<u64>>(&mut self, f: T, t: T) -> T
    where
        u64: Primitive<T>,
    {
        f + self.next(t - f + T::one())
    }
}

static mut RAND: Option<Random> = None;

pub fn random() -> &'static mut Random {
    unsafe {
        if RAND.is_none() {
            RAND = Some(Random::new(
                (SystemTime::UNIX_EPOCH.elapsed().unwrap().as_nanos() & 0xFFFFFFFFFFFFFFFF) as u64,
            ));
        }
        RAND.as_mut().unwrap()
    }
}

pub trait Shuffle {
    fn shuffle(&mut self);
}

impl<T> Shuffle for [T] {
    fn shuffle(&mut self) {
        for i in self.indices() {
            let at = random().next(i + 1);
            self.swap(i, at);
        }
    }
}
}
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 value_ref {
pub trait ConstValueRef<T: ?Sized + 'static> {
    fn val() -> &'static T;
}

pub trait ValueRef<T: 'static> {
    fn val() -> &'static T;
    fn set_val(t: T);
    fn val_mut() -> &'static mut T;
}

#[macro_export]
macro_rules! const_value_ref {
    ($name: ident $val_name: ident: $int_t: ty as $ext_t: ty = $base: expr) => {
        const $val_name: $int_t = $base;

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

        impl $crate::algo_lib::misc::value_ref::ConstValueRef<$ext_t> for $name {
            fn val() -> &'static $ext_t {
                &$val_name
            }
        }
    };
    ($name: ident $val_name: ident: $int_t: ty = $base: expr) => {
        const_value_ref!($name $val_name: $int_t as $int_t = $base);
    };
}

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

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

        impl $crate::algo_lib::misc::value_ref::ValueRef<$t> for $name {
            fn val() -> &'static $t {
                unsafe { $val_name.as_ref().unwrap() }
            }

            fn set_val(t: $t) {
                unsafe {
                    $val_name = Some(t);
                }
            }

            fn val_mut() -> &'static mut $t {
                unsafe { $val_name.as_mut().unwrap() }
            }
        }
    };
    ($name: ident $val_name: ident: $t: ty = $init_val: expr) => {
        value_ref!($name $val_name: $t);
        $name::set_val($init_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::collections::fx_hash_map::FxHashMap;
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::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 = FxHashMap::default();
        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 + Wideable, V: Value<T>> AsIndex for ModInt<T, V>
where
    T::W: AsIndex + IntegerRing + Ord,
{
    fn from_index(idx: usize) -> Self {
        let t = T::W::from_index(idx);
        if t >= T::W::from(V::val()) {
            Self::new_from_wide(t)
        } else {
            unsafe { Self::unchecked_new(T::downcast(t)) }
        }
    }

    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 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 bit_ops {
use crate::algo_lib::numbers::num_traits::algebra::One;
use crate::algo_lib::numbers::num_traits::algebra::Zero;
use std::ops::BitAnd;
use std::ops::BitAndAssign;
use std::ops::BitOr;
use std::ops::BitOrAssign;
use std::ops::BitXor;
use std::ops::BitXorAssign;
use std::ops::Not;
use std::ops::RangeInclusive;
use std::ops::Shl;
use std::ops::Sub;
use std::ops::ShlAssign;
use std::ops::Shr;
use std::ops::ShrAssign;

pub trait BitOps:
    Copy
    + BitAnd<Output = Self>
    + BitAndAssign
    + BitOr<Output = Self>
    + BitOrAssign
    + BitXor<Output = Self>
    + BitXorAssign
    + Not<Output = Self>
    + Shl<usize, Output = Self>
    + ShlAssign<usize>
    + Shr<usize, Output = Self>
    + ShrAssign<usize>
    + Zero
    + One
    + PartialEq
{
    #[inline]
    fn bit(at: usize) -> Self {
        Self::one() << at
    }

    #[inline]
    fn is_set(&self, at: usize) -> bool {
        (*self >> at & Self::one()) == Self::one()
    }

    #[inline]
    fn set_bit(&mut self, at: usize) {
        *self |= Self::bit(at)
    }

    #[inline]
    fn unset_bit(&mut self, at: usize) {
        *self &= !Self::bit(at)
    }

    #[must_use]
    #[inline]
    fn with_bit(mut self, at: usize) -> Self {
        self.set_bit(at);
        self
    }

    #[must_use]
    #[inline]
    fn without_bit(mut self, at: usize) -> Self {
        self.unset_bit(at);
        self
    }

    #[inline]
    fn flip_bit(&mut self, at: usize) {
        *self ^= Self::bit(at)
    }

    #[must_use]
    #[inline]
    fn flipped_bit(mut self, at: usize) -> Self {
        self.flip_bit(at);
        self
    }

    fn all_bits(n: usize) -> Self {
        let mut res = Self::zero();
        for i in 0..n {
            res.set_bit(i);
        }
        res
    }

    fn iter_all(n: usize) -> RangeInclusive<Self> {
        Self::zero()..=Self::all_bits(n)
    }
}

pub struct BitIter<T> {
    cur: T,
    all: T,
    ended: bool,
}

impl<T: Copy> BitIter<T> {
    pub fn new(all: T) -> Self {
        Self {
            cur: all,
            all,
            ended: false,
        }
    }
}

impl<T: BitOps + Sub<Output = T>> Iterator for BitIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        if self.ended {
            return None;
        }
        let res = self.cur;
        if self.cur == T::zero() {
            self.ended = true;
        } else {
            self.cur = (self.cur - T::one()) & self.all;
        }
        Some(res)
    }
}

impl<
        T: Copy
            + BitAnd<Output = Self>
            + BitAndAssign
            + BitOr<Output = Self>
            + BitOrAssign
            + BitXor<Output = Self>
            + BitXorAssign
            + Not<Output = Self>
            + Shl<usize, Output = Self>
            + ShlAssign<usize>
            + Shr<usize, Output = Self>
            + ShrAssign<usize>
            + One
            + Zero
            + PartialEq,
    > BitOps for T
{
}

pub trait Bits: BitOps {
    fn bits() -> u32;
}

macro_rules! bits_integer_impl {
    ($($t: ident $bits: expr),+) => {$(
        impl Bits for $t {
            fn bits() -> u32 {
                $bits
            }
        }
    )+};
}

bits_integer_impl!(i128 128, i64 64, i32 32, i16 16, i8 8, isize 64, u128 128, u64 64, u32 32, u16 16, u8 8, usize 64);
}
pub mod invertible {
pub trait Invertible {
    type Output;

    fn inv(&self) -> Option<Self::Output>;
}
}
pub mod ord {
pub trait MinMax: PartialOrd {
    fn min_val() -> Self;
    fn max_val() -> Self;
}

macro_rules! min_max_integer_impl {
    ($($t: ident)+) => {$(
        impl MinMax for $t {
            fn min_val() -> Self {
                // 1.43
                std::$t::MIN
            }

            fn max_val() -> Self {
                // 1.43
                std::$t::MAX
            }
        }
    )+};
}

min_max_integer_impl!(i128 i64 i32 i16 i8 isize u128 u64 u32 u16 u8 usize);
}
pub mod primitive {
pub trait Primitive<T>: Copy {
    fn to(self) -> T;
}

macro_rules! primitive_one {
    ($t: ident, $($u: ident)+) => {$(
        impl Primitive<$u> for $t {
            fn to(self) -> $u {
                self as $u
            }
        }
    )+};
}

macro_rules! primitive {
    ($($t: ident)+) => {$(
        primitive_one!($t, u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
    )+}
}

primitive!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
}
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 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 SumDigs {
    fn sum_digs(&self) -> Self;
}

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

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

impl<T: Mul<Output = T> + Copy> Square for T {
    fn square(self) -> Self {
        self * self
    }
}
}
pub mod primes {
pub mod prime {
use crate::algo_lib::misc::random::random;
use crate::algo_lib::misc::value::DynamicValue;
use crate::algo_lib::numbers::gcd::gcd;
use crate::algo_lib::numbers::mod_int::ModInt;
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::primitive::Primitive;
use crate::algo_lib::numbers::number_ext::Power;
use crate::dynamic_value;
use crate::when;

pub fn is_prime(n: impl Primitive<i64>) -> bool {
    let n = n.to();
    if n <= 1 {
        return false;
    }
    let mut s = 0;
    let mut d = n - 1;
    while d % 2 == 0 {
        s += 1;
        d >>= 1;
    }
    if s == 0 {
        return n == 2;
    }
    dynamic_value!(IsPrimeModule: i64 = n);
    type Mod = ModInt<i64, IsPrimeModule>;
    for _ in 0..20 {
        let a = Mod::new(random().next(n as u64) as i64);
        if a == Mod::zero() {
            continue;
        }
        if a.power(d) == Mod::one() {
            continue;
        }
        let mut dd = d;
        let mut good = true;
        for _ in 0..s {
            if a.power(dd) == -Mod::one() {
                good = false;
                break;
            }
            dd *= 2;
        }
        if good {
            return false;
        }
    }
    true
}

pub fn next_prime(mut n: i64) -> i64 {
    if n <= 2 {
        return 2;
    }
    n += 1 - (n & 1);
    while !is_prime(n) {
        n += 2;
    }
    n
}

fn brent(n: i64, x0: i64, c: i64) -> i64 {
    dynamic_value!(ModVal: i64 = n);
    type Mod = ModInt<i64, ModVal>;
    let mut x = Mod::new(x0);
    let c = Mod::new(c);
    let mut g = 1;
    let mut q = Mod::one();
    let mut xs = Mod::zero();
    let mut y = Mod::zero();
    let m = 128i64;
    let mut l = 1;
    while g == 1 {
        y = x;
        for _ in 1..l {
            x = x * x + c;
        }
        let mut k = 0;
        while k < l && g == 1 {
            xs = x;
            for _ in 0..m.min(l - k) {
                x = x * x + c;
                q *= y - x;
            }
            g = gcd(q.val(), n);
            k += m;
        }
        l *= 2;
    }
    if g == n {
        loop {
            xs = xs * xs + c;
            g = gcd((xs - y).val(), n);
            if g != 1 {
                break;
            }
        }
    }
    g
}

pub fn find_divisor(n: i64) -> i64 {
    when! {
        n == 1 => 1,
        n % 2 == 0 => 2,
        is_prime(n) => n,
        else => {
            loop {
                let res = brent(
                    n,
                    random().next_bounds(2, n as u64 - 1) as i64,
                    random().next_bounds(1, n as u64 - 1) as i64,
                );
                if res != n {
                    return res;
                }
            }
        },
    }
}
}
}
}
pub mod string {
pub mod hash {
use crate::algo_lib::misc::random::random;
use crate::algo_lib::misc::value::DynamicValue;
use crate::algo_lib::misc::value_ref::ValueRef;
use crate::algo_lib::numbers::mod_int::ModInt;
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::invertible::Invertible;
use crate::algo_lib::numbers::num_traits::primitive::Primitive;
use crate::algo_lib::numbers::primes::prime::next_prime;
use crate::dynamic_value;
use crate::value_ref;
use crate::when;
use std::cmp::Ordering;
use std::collections::Bound;
use std::ops::RangeBounds;

dynamic_value!(HM: i64);
type HashMod = ModInt<i64, HM>;

value_ref!(HashBaseContainer HBCS: HashBase);

pub struct HashBase {
    multiplier: HashMod,
    inv_multiplier: HashMod,
    power: Vec<HashMod>,
    inv_power: Vec<HashMod>,
}

impl HashBase {
    pub fn init() {
        if unsafe { HBCS.is_some() } {
            return;
        }
        HM::set_val(next_prime(
            random().next_bounds(10i64.pow(18), 2 * 10i64.pow(18)),
        ));
        let multiplier = HashMod::new(random().next_bounds(4 * 10i64.pow(17), 5 * 10i64.pow(17)));
        let inv_multiplier = multiplier.inv().unwrap();
        HashBaseContainer::set_val(Self {
            multiplier,
            inv_multiplier,
            power: vec![HashMod::one()],
            inv_power: vec![HashMod::one()],
        });
    }

    pub fn ensure_capacity(&mut self, n: usize) {
        if self.power.len() < n {
            self.power.reserve(n - self.power.len());
            while self.power.len() < n {
                self.power
                    .push(*self.power.last().unwrap() * self.multiplier);
            }
            self.inv_power.reserve(n - self.inv_power.len());
            while self.inv_power.len() < n {
                self.inv_power
                    .push(*self.inv_power.last().unwrap() * self.inv_multiplier);
            }
        }
    }
}

#[allow(clippy::len_without_is_empty)]
pub trait StringHash {
    fn len(&self) -> usize;
    fn hash<R: RangeBounds<usize>>(&self, r: R) -> i64;
    fn sub_hash<R: RangeBounds<usize>>(&self, r: R) -> SubstrigHash<Self> {
        SubstrigHash::new(self, r)
    }
}

#[derive(Clone)]
pub struct SimpleHash {
    hash: Vec<HashMod>,
}

impl SimpleHash {
    pub fn new(str: &[impl Primitive<i64>]) -> Self {
        HashBaseContainer::val_mut().ensure_capacity(str.len() + 1);
        let mut hash = Vec::with_capacity(str.len() + 1);
        hash.push(HashMod::zero());
        let multiplier = HashBaseContainer::val().multiplier;
        let mut power = HashMod::one();
        for c in str {
            let c = HashMod::new(c.to());
            let cur = *hash.last().unwrap() + c * power;
            hash.push(cur);
            power *= multiplier;
        }
        Self { hash }
    }

    pub fn push(&mut self, c: impl Primitive<i64>) {
        HashBaseContainer::val_mut().ensure_capacity(self.hash.len() + 1);
        self.hash.push(
            *self.hash.last().unwrap()
                + HashMod::new(c.to()) * HashBaseContainer::val().power[self.len()],
        );
    }
}

impl StringHash for SimpleHash {
    fn len(&self) -> usize {
        self.hash.len() - 1
    }

    fn hash<R: RangeBounds<usize>>(&self, r: R) -> i64 {
        let (from, to) = convert_bounds(r, self.len());
        let res = (self.hash[to] - self.hash[from]) * HashBaseContainer::val().inv_power[from];
        res.val()
    }
}

#[derive(Clone)]
pub struct SubstrigHash<'s, BaseHash: StringHash + ?Sized> {
    base: &'s BaseHash,
    from: usize,
    to: usize,
}

impl<'s, BaseHash: StringHash + ?Sized> SubstrigHash<'s, BaseHash> {
    pub fn new<R: RangeBounds<usize>>(base: &'s BaseHash, r: R) -> Self {
        let (from, to) = convert_bounds(r, base.len());
        Self { base, from, to }
    }
}

impl<'s, BaseHash: StringHash + ?Sized> StringHash for SubstrigHash<'s, BaseHash> {
    fn len(&self) -> usize {
        self.to - self.from
    }

    fn hash<R: RangeBounds<usize>>(&self, r: R) -> i64 {
        let (from, to) = convert_bounds(r, self.len());
        self.base.hash(from + self.from..to + self.from)
    }
}

fn convert_bounds<R: RangeBounds<usize>>(r: R, len: usize) -> (usize, usize) {
    let from = match r.start_bound() {
        Bound::Included(f) => *f,
        Bound::Excluded(f) => *f + 1,
        Bound::Unbounded => 0,
    };
    let to = match r.end_bound() {
        Bound::Included(t) => *t + 1,
        Bound::Excluded(t) => *t,
        Bound::Unbounded => len,
    };
    assert!(from <= to);
    assert!(to <= len);
    (from, to)
}

#[derive(Clone)]
pub struct CompositeHash<'s, Hash1: StringHash + ?Sized, Hash2: StringHash + ?Sized> {
    base1: &'s Hash1,
    base2: &'s Hash2,
}

impl<'s, Hash1: StringHash + ?Sized, Hash2: StringHash + ?Sized> CompositeHash<'s, Hash1, Hash2> {
    pub fn new(base1: &'s Hash1, base2: &'s Hash2) -> Self {
        Self { base1, base2 }
    }
}

impl<'s, Hash1: StringHash + ?Sized, Hash2: StringHash + ?Sized> StringHash
    for CompositeHash<'s, Hash1, Hash2>
{
    fn len(&self) -> usize {
        self.base1.len() + self.base2.len()
    }

    fn hash<R: RangeBounds<usize>>(&self, r: R) -> i64 {
        let (from, to) = convert_bounds(r, self.len());
        when! {
            to <= self.base1.len() => self.base1.hash(from..to),
            from >= self.base1.len() => self.base2.hash(from - self.base1.len()..to - self.base1.len()),
            else => {
                let h1 = self.base1.hash(from..);
                let h2 = self.base2.hash(..to - self.base1.len());
                (HashMod::new(h2) * HashBaseContainer::val().power[self.base1.len() - from]
                    + HashMod::new(h1))
                .val()
            },
        }
    }
}

pub trait Hashable {
    fn str_hash(&self) -> i64;
}

impl<T: Primitive<i64>> Hashable for [T] {
    fn str_hash(&self) -> i64 {
        HashBaseContainer::val_mut().ensure_capacity(self.len() + 1);
        let mut res = HashMod::zero();
        let multiplier = HashBaseContainer::val().multiplier;
        let mut power = HashMod::one();
        for c in self {
            let c = HashMod::new(c.to());
            res += c * power;
            power *= multiplier;
        }
        res.val()
    }
}

pub fn compare(h1: &impl StringHash, h2: &impl StringHash) -> Ordering {
    let mut left = 0;
    let mut right = h1.len().min(h2.len());

    while left < right {
        let mid = (left + right + 1) / 2;
        if h1.hash(..mid) == h2.hash(..mid) {
            left = mid;
        } else {
            right = mid - 1;
        }
    }

    if left == h1.len().min(h2.len()) {
        h1.len().cmp(&h2.len())
    } else {
        h1.hash(left..=left).cmp(&h2.hash(left..=left))
    }
}
}
pub mod str {
use crate::algo_lib::collections::iter_ext::collect::IterCollect;
use crate::algo_lib::collections::slice_ext::backward::Back;
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::cmp::Ordering;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::hash::Hash;
use std::hash::Hasher;
use std::iter::Copied;
use std::iter::FromIterator;
use std::marker::PhantomData;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ops::Index;
use std::ops::IndexMut;
use std::ops::RangeBounds;
use std::slice::Iter;
use std::slice::IterMut;
use std::slice::SliceIndex;
use std::str::FromStr;
use std::vec::IntoIter;

pub enum Str<'s> {
    Extendable(Vec<u8>, PhantomData<&'s [u8]>),
    Owned(Box<[u8]>, PhantomData<&'s [u8]>),
    Ref(&'s [u8]),
}

impl<'s> Str<'s> {
    pub fn substr(&self, range: impl RangeBounds<usize>) -> Str {
        let from = match range.start_bound() {
            std::ops::Bound::Included(&i) => i,
            std::ops::Bound::Excluded(&i) => i + 1,
            std::ops::Bound::Unbounded => 0,
        };
        let to = match range.end_bound() {
            std::ops::Bound::Included(&i) => i + 1,
            std::ops::Bound::Excluded(&i) => i,
            std::ops::Bound::Unbounded => self.len(),
        };
        Str::from(&self[from..to])
    }
}

impl Default for Str<'static> {
    fn default() -> Self {
        Self::new()
    }
}

impl Str<'static> {
    pub fn new() -> Self {
        Str::Extendable(Vec::new(), PhantomData)
    }

    pub fn with_capacity(cap: usize) -> Self {
        Str::Extendable(Vec::with_capacity(cap), PhantomData)
    }
}

impl<'s> Str<'s> {
    pub fn push(&mut self, c: u8) {
        self.transform_to_extendable();
        self.as_extendable().push(c)
    }

    pub fn pop(&mut self) -> Option<u8> {
        self.transform_to_extendable();
        self.as_extendable().pop()
    }

    pub fn as_slice(&self) -> &[u8] {
        match self {
            Str::Extendable(s, _) => s.as_ref(),
            Str::Owned(s, _) => s.as_ref(),
            Str::Ref(s) => s,
        }
    }

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

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn resize(&mut self, new_len: usize, value: u8) {
        self.transform_to_extendable();
        self.as_extendable().resize(new_len, value);
    }

    pub fn iter(&self) -> Copied<Iter<u8>> {
        match self {
            Str::Extendable(v, _) => v.iter(),
            Str::Owned(v, _) => v.iter(),
            Str::Ref(v) => v.iter(),
        }
        .copied()
    }

    pub fn iter_mut(&mut self) -> IterMut<u8> {
        self.transform_to_owned();
        self.as_mut_slice().iter_mut()
    }

    pub fn sort(&mut self) {
        self.transform_to_owned();
        self.as_mut_slice().sort_unstable();
    }

    pub fn into_owned(mut self) -> Str<'static> {
        self.transform_to_owned();
        match self {
            Str::Extendable(v, _) => Str::Extendable(v, PhantomData),
            Str::Owned(v, _) => Str::Owned(v, PhantomData),
            _ => unreachable!(),
        }
    }

    fn transform_to_extendable(&mut self) {
        match self {
            Str::Extendable(_, _) => {}
            Str::Owned(_, _) => {
                let mut fake = Str::new();
                std::mem::swap(self, &mut fake);
                if let Str::Owned(s, _) = fake {
                    *self = Str::Extendable(s.into_vec(), PhantomData)
                } else {
                    unreachable!();
                }
            }
            Str::Ref(s) => *self = Str::Extendable(s.to_vec(), PhantomData),
        }
    }

    fn as_extendable(&mut self) -> &mut Vec<u8> {
        match self {
            Str::Extendable(s, _) => s,
            _ => panic!("unreachable"),
        }
    }

    fn transform_to_owned(&mut self) {
        if let Str::Ref(s) = self {
            *self = Str::Owned(s.to_vec().into_boxed_slice(), PhantomData)
        }
    }

    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        self.transform_to_owned();
        match self {
            Str::Extendable(s, _) => s.as_mut_slice(),
            Str::Owned(s, _) => s.as_mut(),
            _ => panic!("unreachable"),
        }
    }

    pub fn into_string(self) -> String {
        match self {
            Str::Extendable(v, _) => unsafe { String::from_utf8_unchecked(v) },
            Str::Owned(v, _) => unsafe { String::from_utf8_unchecked(v.into_vec()) },
            Str::Ref(v) => String::from_utf8_lossy(v).into_owned(),
        }
    }

    pub fn reverse(&mut self) {
        self.as_mut_slice().reverse();
    }

    pub fn trim(&self) -> Str<'_> {
        let mut start = 0;
        let mut end = self.len();
        while start < end && (self[start] as char).is_whitespace() {
            start += 1;
        }
        while start < end && (self[end - 1] as char).is_whitespace() {
            end -= 1;
        }
        self[start..end].into()
    }

    pub fn split<'a, 'b>(&'a self, sep: impl Into<Str<'b>>) -> Vec<Str<'a>>
    where
        's: 'a,
    {
        let sep = sep.into();
        let mut res = Vec::new();
        let mut start = 0;
        for i in 0..self.len() {
            if self[i..].starts_with(sep.as_slice()) {
                res.push(self[start..i].into());
                start = i + sep.len();
            }
        }
        res.push(self[start..].into());
        res
    }

    pub fn parse<F: FromStr>(self) -> F
    where
        F::Err: Debug,
    {
        self.into_string().parse().unwrap()
    }

    pub fn parse_vec<T: Readable>(&self) -> Vec<T> {
        let mut bytes = self.as_slice();
        let mut input = Input::new(&mut bytes);
        let mut res = Vec::new();
        while !input.is_exhausted() {
            res.push(input.read());
        }
        res
    }

    pub fn qty(&self, from: u8, to: u8) -> Vec<usize> {
        let mut res = vec![0; (to - from + 1) as usize];
        for &c in self.as_slice() {
            res[(c - from) as usize] += 1;
        }
        res
    }

    pub fn qty_lower(&self) -> Vec<usize> {
        self.qty(b'a', b'z')
    }
}

impl<'s> IntoIterator for Str<'s> {
    type Item = u8;
    type IntoIter = IntoIter<u8>;

    #[allow(clippy::unnecessary_to_owned)]
    fn into_iter(self) -> Self::IntoIter {
        match self {
            Str::Extendable(v, _) => v.into_iter(),
            Str::Owned(v, _) => v.into_vec().into_iter(),
            Str::Ref(v) => v.to_vec().into_iter(),
        }
    }
}

impl From<String> for Str<'static> {
    fn from(s: String) -> Self {
        Str::Extendable(s.into(), PhantomData)
    }
}

impl<'s> From<&'s str> for Str<'s> {
    fn from(s: &'s str) -> Self {
        Str::Ref(s.as_bytes())
    }
}

impl From<Vec<u8>> for Str<'static> {
    fn from(s: Vec<u8>) -> Self {
        Str::Extendable(s, PhantomData)
    }
}

impl<'s> From<&'s [u8]> for Str<'s> {
    fn from(s: &'s [u8]) -> Self {
        Str::Ref(s)
    }
}

impl<'s, const N: usize> From<&'s [u8; N]> for Str<'s> {
    fn from(s: &'s [u8; N]) -> Self {
        Str::Ref(s)
    }
}

impl<'s> From<&'s String> for Str<'s> {
    fn from(s: &'s String) -> Self {
        Str::Ref(s.as_bytes())
    }
}

impl<'s> From<&'s Vec<u8>> for Str<'s> {
    fn from(s: &'s Vec<u8>) -> Self {
        Str::Ref(s.as_slice())
    }
}

impl From<u8> for Str<'static> {
    fn from(c: u8) -> Self {
        Str::Owned(Box::new([c]), PhantomData)
    }
}

impl From<char> for Str<'static> {
    fn from(c: char) -> Self {
        Str::from(c as u8)
    }
}

impl<'s, 't: 's> From<&'s Str<'t>> for Str<'s> {
    fn from(value: &'s Str<'t>) -> Self {
        Str::Ref(value.as_slice())
    }
}

impl<R: SliceIndex<[u8]>> Index<R> for Str<'_> {
    type Output = R::Output;

    fn index(&self, index: R) -> &Self::Output {
        self.as_slice().index(index)
    }
}

impl<R: SliceIndex<[u8]>> IndexMut<R> for Str<'_> {
    fn index_mut(&mut self, index: R) -> &mut Self::Output {
        self.transform_to_owned();
        self.as_mut_slice().index_mut(index)
    }
}

impl Clone for Str<'_> {
    fn clone(&self) -> Self {
        match self {
            Str::Extendable(s, _) => s.clone().into(),
            Str::Owned(s, _) => s.to_vec().into(),
            Str::Ref(s) => Str::Ref(s),
        }
    }
}

impl<'r, 's, S: Into<Str<'r>>> AddAssign<S> for Str<'s> {
    fn add_assign(&mut self, rhs: S) {
        self.transform_to_extendable();
        self.as_extendable()
            .extend_from_slice(rhs.into().as_slice());
    }
}

impl<'r, 's, S: Into<Str<'r>>> Add<S> for Str<'s> {
    type Output = Str<'s>;

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

impl Readable for Str<'static> {
    fn read(input: &mut Input) -> Self {
        input.next_token().unwrap().into()
    }
}

impl Writable for Str<'_> {
    fn write(&self, output: &mut Output) {
        for c in self.as_slice() {
            output.put(*c);
        }
        output.maybe_flush();
    }
}

impl Display for Str<'_> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        <String as Display>::fmt(&String::from_utf8(self.as_slice().to_vec()).unwrap(), f)
    }
}

impl Hash for Str<'_> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.as_slice().hash(state);
    }
}

impl<'r> PartialEq<Str<'r>> for Str<'_> {
    fn eq(&self, other: &Str<'r>) -> bool {
        self.as_slice().eq(other.as_slice())
    }
}

impl Eq for Str<'_> {}

impl<'r> PartialOrd<Str<'r>> for Str<'_> {
    fn partial_cmp(&self, other: &Str<'r>) -> Option<Ordering> {
        self.as_slice().partial_cmp(other.as_slice())
    }
}

impl Ord for Str<'_> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.as_slice().cmp(other.as_slice())
    }
}

impl FromIterator<u8> for Str<'static> {
    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
        Self::Extendable(iter.into_iter().collect_vec(), Default::default())
    }
}

impl<'r> FromIterator<&'r u8> for Str<'static> {
    fn from_iter<T: IntoIterator<Item = &'r u8>>(iter: T) -> Self {
        Self::Extendable(iter.into_iter().cloned().collect_vec(), Default::default())
    }
}

impl Deref for Str<'_> {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        self.as_slice()
    }
}

impl DerefMut for Str<'_> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.as_mut_slice()
    }
}

pub trait StrReader {
    fn read_str(&mut self) -> Str<'static>;
    fn read_str_vec(&mut self, n: usize) -> Vec<Str<'static>>;
    fn read_line(&mut self) -> Str<'static>;
    fn read_line_vec(&mut self, n: usize) -> Vec<Str<'static>>;
    fn read_lines(&mut self) -> Vec<Str<'static>>;
}

impl StrReader for Input<'_> {
    fn read_str(&mut self) -> Str<'static> {
        self.read()
    }

    fn read_str_vec(&mut self, n: usize) -> Vec<Str<'static>> {
        self.read_vec(n)
    }

    fn read_line(&mut self) -> Str<'static> {
        let mut res = Str::new();
        while let Some(c) = self.get() {
            if c == b'\n' {
                break;
            }
            res.push(c);
        }
        res
    }

    fn read_line_vec(&mut self, n: usize) -> Vec<Str<'static>> {
        let mut res = Vec::with_capacity(n);
        for _ in 0..n {
            res.push(self.read_line());
        }
        res
    }

    fn read_lines(&mut self) -> Vec<Str<'static>> {
        let mut res = Vec::new();
        while !self.is_exhausted() {
            res.push(self.read_line());
        }
        if let Some(s) = res.last() {
            if s.is_empty() {
                res.pop();
            }
        }
        res
    }
}

impl Index<Back> for Str<'_> {
    type Output = u8;

    fn index(&self, index: Back) -> &Self::Output {
        &self[self.len() - index.0 - 1]
    }
}

impl IndexMut<Back> for Str<'_> {
    fn index_mut(&mut self, index: Back) -> &mut Self::Output {
        let len = self.len();
        &mut self[len - index.0 - 1]
    }
}

impl AsRef<[u8]> for Str<'_> {
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}
}
}
}
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: 0ms
memory: 2184kb

input:

5
automated teller machine
active teller machine
active trouble maker
always telling misinformation
American Teller Machinery

output:

atm
actm
atrm
atmi
ATM

result:

ok len=18

Test #2:

score: 0
Accepted
time: 0ms
memory: 2348kb

input:

5
Forest Conservation Committee Forum
Fuming Corruption Collusion Federation
Fulsome Cash Concealment Foundation
Funky Crony Capitalism Facilitator
Funny Cocky Cocky Funny

output:

FCCF
FCCFe
FCaCF
FCCaF
FCCFu

result:

ok len=24

Test #3:

score: 0
Accepted
time: 0ms
memory: 2212kb

input:

3
A AA
AA A
A A A

output:

no solution

result:

ok len=-1

Test #4:

score: 0
Accepted
time: 0ms
memory: 2324kb

input:

2
QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnmertyuiop
Q W E R T Y U I O P A S D F G H J K L Z X C V B N M q w e r t y u i o p a s d f g h j k l z x c v b n m j k l z x c v b n m

output:

Q
QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnmjklzxcvbnm

result:

ok len=63

Test #5:

score: 0
Accepted
time: 0ms
memory: 2376kb

input:

10
aaa aaa aaa aaa aaa aaa
aab aaa aaa aaa aaa aaa
aaa aab aaa aaa aaa aaa
aab aab aaa aaa aaa aaa
a a a a a a
ab ab a a a a a a
ab ab b a a a a a a
aw a a a a a
az az a a a a
az a a a a a

output:

aaaaaaa
aaaaaaaa
aaabaaaa
aabaaaaa
aaaaaa
abaaaaaaa
aabaaaaaa
awaaaaa
aazaaaa
azaaaaa

result:

ok len=76

Test #6:

score: -100
Time Limit Exceeded

input:

128
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz...

output:


result: