pub trait Readable {
    #[doc = " Output type."]
    #[doc = ""]
    #[doc = " In most cases, `Output` should be `Self`."]
    #[doc = " This type field exists for implementing 1-origin to 0-origin conversion"]
    #[doc = " by `usize_` etc."]
    type Output;
    #[doc = " Returns how many words are read."]
    fn words_count() -> usize;
    #[doc = " Converts words into `Output`s."]
    #[doc = ""]
    #[doc = " If the conversion fails, returns `Err` with error message."]
    #[doc = ""]
    #[doc = " # Panics"]
    #[doc = ""]
    #[doc = " If `words.len()` differs from `words_count()`,"]
    #[doc = " the method may panic."]
    fn read_words(words: &[&str]) -> Result<Self::Output, String>;
}
#[macro_export]
macro_rules! readable {
    ( $ t : ty , |$ words : ident | $ read_words : expr ) => {
        readable!($t, 1, |$words| $read_words);
    };
    ( $ t : ty , $ words_count : expr , |$ words : ident | $ read_words : expr ) => {
        impl Readable for $t {
            type Output = $t;
            fn words_count() -> usize {
                $words_count
            }
            fn read_words($words: &[&str]) -> Result<$t, String> {
                Ok($read_words)
            }
        }
    };
}
readable!((), |_ss| ());
readable!(String, |ss| ss[0].to_string());
macro_rules ! impl_readable_for_ints { ( $ ( $ t : ty ) * ) => { $ ( impl Readable for $ t { type Output = Self ; fn words_count ( ) -> usize { 1 } fn read_words ( words : & [ & str ] ) -> Result <$ t , String > { use std :: str :: FromStr ; <$ t >:: from_str ( words [ 0 ] ) . map_err ( | _ | { format ! ( "cannot parse \"{}\" as {}" , words [ 0 ] , stringify ! ( $ t ) ) } ) } } ) * } ; }
impl_readable_for_ints ! ( i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 ) ;
macro_rules ! define_one_origin_int_types { ( $ new_t : ident $ int_t : ty ) => { # [ doc = " Converts 1-origin integer into 0-origin when read from stdin." ] # [ doc = "" ] # [ doc = " # Example" ] # [ doc = "" ] # [ doc = " ```no_run" ] # [ doc = " # #[macro_use] extern crate atcoder_snippets;" ] # [ doc = " # use atcoder_snippets::read::*;" ] # [ doc = " // Stdin: \"1\"" ] # [ doc = " read!(a = usize_);" ] # [ doc = " assert_eq!(a, 0);" ] # [ doc = " ```" ] # [ allow ( non_camel_case_types ) ] pub struct $ new_t ( ) ; impl Readable for $ new_t { type Output = $ int_t ; fn words_count ( ) -> usize { 1 } fn read_words ( words : & [ & str ] ) -> Result < Self :: Output , String > { <$ int_t >:: read_words ( words ) . map ( | n | n - 1 ) } } } ; ( $ new_t : ident $ int_t : ty ; $ ( $ inner_new_t : ident $ inner_int_t : ty ) ;* ) => { define_one_origin_int_types ! ( $ new_t $ int_t ) ; define_one_origin_int_types ! ( $ ( $ inner_new_t $ inner_int_t ) ;* ) ; } ; }
define_one_origin_int_types ! ( u8_ u8 ; u16_ u16 ; u32_ u32 ; u64_ u64 ; usize_ usize ) ;
macro_rules ! impl_readable_for_tuples { ( $ t : ident $ var : ident ) => ( ) ; ( $ t : ident $ var : ident ; $ ( $ inner_t : ident $ inner_var : ident ) ;* ) => { impl_readable_for_tuples ! ( $ ( $ inner_t $ inner_var ) ;* ) ; impl <$ t : Readable , $ ( $ inner_t : Readable ) ,*> Readable for ( $ t , $ ( $ inner_t ) ,* ) { type Output = ( <$ t >:: Output , $ ( <$ inner_t >:: Output ) ,* ) ; fn words_count ( ) -> usize { let mut n = <$ t >:: words_count ( ) ; $ ( n += <$ inner_t >:: words_count ( ) ; ) * n } # [ allow ( unused_assignments ) ] fn read_words ( words : & [ & str ] ) -> Result < Self :: Output , String > { let mut start = 0 ; let $ var = <$ t >:: read_words ( & words [ start .. start +<$ t >:: words_count ( ) ] ) ?; start += <$ t >:: words_count ( ) ; $ ( let $ inner_var = <$ inner_t >:: read_words ( & words [ start .. start +<$ inner_t >:: words_count ( ) ] ) ?; start += <$ inner_t >:: words_count ( ) ; ) * Ok ( ( $ var , $ ( $ inner_var ) ,* ) ) } } } ; }
impl_readable_for_tuples ! ( T4 x4 ; T3 x3 ; T2 x2 ; T1 x1 ) ;
pub trait ReadableFromLine {
    type Output;
    fn read_line(line: &str) -> Result<Self::Output, String>;
}
fn split_into_words(line: &str) -> Vec<&str> {
    #[allow(deprecated)]
    line.trim_right_matches('\n').split_whitespace().collect()
}
impl<T: Readable> ReadableFromLine for T {
    type Output = T::Output;
    fn read_line(line: &str) -> Result<T::Output, String> {
        let words = split_into_words(line);
        if words.len() != T::words_count() {
            return Err(format!(
                "line \"{}\" has {} words, expected {}",
                line,
                words.len(),
                T::words_count()
            ));
        }
        T::read_words(&words)
    }
}
impl<T: Readable> ReadableFromLine for Vec<T> {
    type Output = Vec<T::Output>;
    fn read_line(line: &str) -> Result<Self::Output, String> {
        let n = T::words_count();
        let words = split_into_words(line);
        if words.len() % n != 0 {
            return Err(format!(
                "line \"{}\" has {} words, expected multiple of {}",
                line,
                words.len(),
                n
            ));
        }
        let mut result = Vec::new();
        for chunk in words.chunks(n) {
            match T::read_words(chunk) {
                Ok(v) => result.push(v),
                Err(msg) => {
                    let flagment_msg = if n == 1 {
                        format!("word {}", result.len())
                    } else {
                        let l = result.len();
                        format!("words {}-{}", n * l + 1, (n + 1) * l)
                    };
                    return Err(format!("{} of line \"{}\": {}", flagment_msg, line, msg));
                }
            }
        }
        Ok(result)
    }
}
impl<T: Readable, U: Readable> ReadableFromLine for (T, Vec<U>) {
    type Output = (T::Output, <Vec<U> as ReadableFromLine>::Output);
    fn read_line(line: &str) -> Result<Self::Output, String> {
        let n = T::words_count();
        #[allow(deprecated)]
        let trimmed = line.trim_right_matches('\n');
        let words_and_rest: Vec<&str> = trimmed.splitn(n + 1, ' ').collect();
        if words_and_rest.len() < n {
            return Err(format!(
                "line \"{}\" has {} words, expected at least {}",
                line,
                words_and_rest.len(),
                n
            ));
        }
        let words = &words_and_rest[..n];
        let empty_str = "";
        let rest = words_and_rest.get(n).unwrap_or(&empty_str);
        Ok((T::read_words(words)?, Vec::<U>::read_line(rest)?))
    }
}
macro_rules ! impl_readable_from_line_for_tuples_with_vec { ( $ t : ident $ var : ident ) => ( ) ; ( $ t : ident $ var : ident ; $ ( $ inner_t : ident $ inner_var : ident ) ;+ ) => { impl_readable_from_line_for_tuples_with_vec ! ( $ ( $ inner_t $ inner_var ) ;+ ) ; impl <$ t : Readable , $ ( $ inner_t : Readable ) ,+ , U : Readable > ReadableFromLine for ( $ t , $ ( $ inner_t ) ,+ , Vec < U > ) { type Output = ( $ t :: Output , $ ( $ inner_t :: Output ) ,+ , Vec < U :: Output > ) ; fn read_line ( line : & str ) -> Result < Self :: Output , String > { let mut n = $ t :: words_count ( ) ; $ ( n += $ inner_t :: words_count ( ) ; ) + # [ allow ( deprecated ) ] let trimmed = line . trim_right_matches ( '\n' ) ; let words_and_rest : Vec <& str > = trimmed . splitn ( n + 1 , ' ' ) . collect ( ) ; if words_and_rest . len ( ) < n { return Err ( format ! ( "line \"{}\" has {} words, expected at least {}" , line , words_and_rest . len ( ) , n ) ) ; } let words = & words_and_rest [ .. n ] ; let empty_str = "" ; let rest = words_and_rest . get ( n ) . unwrap_or ( & empty_str ) ; let ( $ var , $ ( $ inner_var ) ,* ) = < ( $ t , $ ( $ inner_t ) ,+ ) >:: read_words ( words ) ?; Ok ( ( $ var , $ ( $ inner_var ) ,* , Vec ::< U >:: read_line ( rest ) ? ) ) } } } ; }
impl_readable_from_line_for_tuples_with_vec ! ( T4 t4 ; T3 t3 ; T2 t2 ; T1 t1 ) ;
pub fn read<T: ReadableFromLine>() -> T::Output {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    T::read_line(&line).unwrap()
}
#[macro_export]
macro_rules ! read { ( ) => { let mut line = String :: new ( ) ; std :: io :: stdin ( ) . read_line ( & mut line ) . unwrap ( ) ; } ; ( $ pat : pat = $ t : ty ) => { let $ pat = read ::<$ t > ( ) ; } ; ( $ ( $ pat : pat = $ t : ty ) ,+ ) => { read ! ( ( $ ( $ pat ) ,* ) = ( $ ( $ t ) ,* ) ) ; } ; }
#[macro_export]
macro_rules ! readls { ( $ ( $ pat : pat = $ t : ty ) ,+ ) => { $ ( read ! ( $ pat = $ t ) ; ) * } ; }
pub fn readx<T: ReadableFromLine>() -> Vec<T::Output> {
    use std::io::{self, BufRead};
    let stdin = io::stdin();
    let result = stdin
        .lock()
        .lines()
        .map(|line_result| {
            let line = line_result.expect("read from stdin failed");
            T::read_line(&line).unwrap()
        }).collect();
    result
}
#[macro_export]
macro_rules ! readx_loop { ( |$ pat : pat = $ t : ty | $ body : expr ) => { use std :: io :: BufRead ; let stdin = std :: io :: stdin ( ) ; for line in stdin . lock ( ) . lines ( ) { let line = line . expect ( "read from stdin failed" ) ; let $ pat = <$ t >:: read_line ( & line ) . unwrap ( ) ; $ body } } ; ( |$ ( $ pat : pat = $ t : ty ) ,*| $ body : expr ) => { readx_loop ! ( | ( $ ( $ pat ) ,* ) = ( $ ( $ t ) ,* ) | $ body ) ; } ; }
pub fn readn<T: ReadableFromLine>(n: usize) -> Vec<T::Output> {
    use std::io::{self, BufRead};
    let stdin = io::stdin();
    let result: Vec<T::Output> = stdin
        .lock()
        .lines()
        .take(n)
        .map(|line_result| {
            let line = line_result.expect("read from stdin failed");
            T::read_line(&line).unwrap()
        }).collect();
    if result.len() < n {
        panic!(
            "expected reading {} lines, but only {} lines are read",
            n,
            result.len()
        );
    }
    result
}
#[macro_export]
macro_rules ! readn_loop { ( $ n : expr , |$ pat : pat = $ t : ty | $ body : expr ) => { use std :: io :: BufRead ; let stdin = std :: io :: stdin ( ) ; { let mut lock = stdin . lock ( ) ; for _ in 0 ..$ n { let mut line = String :: new ( ) ; lock . read_line ( & mut line ) . expect ( "read from stdin failed" ) ; let $ pat = <$ t >:: read_line ( & line ) . unwrap ( ) ; $ body } } } ; ( $ n : expr , |$ ( $ pat : pat = $ t : ty ) ,*| $ body : expr ) => { readn_loop ! ( $ n , | ( $ ( $ pat ) ,* ) = ( $ ( $ t ) ,* ) | $ body ) ; } ; }
pub trait Words {
    fn read<T: Readable>(&self) -> T::Output;
}
impl<'a> Words for [&'a str] {
    fn read<T: Readable>(&self) -> T::Output {
        T::read_words(self).unwrap()
    }
}
impl<'a> Words for &'a str {
    fn read<T: Readable>(&self) -> T::Output {
        T::read_words(&[self]).unwrap()
    }
}

#[derive(Clone, PartialEq, Eq)]
pub enum ListInner<T: Clone> {
    Nil,
    Cons(T, List<T>),
}
pub use self::ListInner::{Cons, Nil};
#[derive(Clone, PartialEq, Eq)]
pub struct List<T: Clone> {
    inner: std::rc::Rc<ListInner<T>>,
    len: usize,
}
impl<T: Clone> List<T> {
    pub fn nil() -> List<T> {
        List {
            inner: std::rc::Rc::new(Nil),
            len: 0,
        }
    }
    #[doc = " Whether the list is nil."]
    pub fn is_nil(&self) -> bool {
        match self.as_ref() {
            &Nil => true,
            &Cons(_, _) => false,
        }
    }
    #[doc = " Length of the list."]
    #[doc = ""]
    #[doc = " `len()` is O(1) time because each sublist holds its length."]
    pub fn len(&self) -> usize {
        self.len
    }
    #[doc = " Extract head of non-empty list."]
    #[doc = ""]
    #[doc = " # Panic"]
    #[doc = ""]
    #[doc = " Panics if `self` is nil."]
    #[doc = ""]
    #[doc = " # Example"]
    #[doc = ""]
    #[doc = " ```"]
    #[doc = " # #[macro_use] extern crate atcoder_snippets;"]
    #[doc = " # use atcoder_snippets::collections::list::*;"]
    #[doc = " assert_eq!(list![1, 2, 3].head(), 1);"]
    #[doc = " ```"]
    pub fn head(&self) -> T {
        match self.as_ref() {
            &Nil => panic!("cannot find head of nil"),
            &Cons(ref head, _) => head.clone(),
        }
    }
    #[doc = " Extract tail of non-empty list."]
    #[doc = ""]
    #[doc = " # Panic"]
    #[doc = ""]
    #[doc = " Panics if `self` is nil."]
    #[doc = ""]
    #[doc = " # Example"]
    #[doc = ""]
    #[doc = " ```"]
    #[doc = " # #[macro_use] extern crate atcoder_snippets;"]
    #[doc = " # use atcoder_snippets::collections::list::*;"]
    #[doc = " assert_eq!(list![1, 2, 3].tail(), list![2, 3]);"]
    #[doc = " ```"]
    pub fn tail(&self) -> List<T> {
        match self.as_ref() {
            &Nil => panic!("cannot find head of nil"),
            &Cons(_, ref tail) => tail.clone(),
        }
    }
    #[doc = " Gets an iterator without moving `self`."]
    pub fn iter(&self) -> List<T> {
        self.clone()
    }
    #[doc = " Concatenates two lists."]
    pub fn append(&self, other: &List<T>) -> List<T> {
        append_tailrec(self, other, List::nil())
    }
    #[doc = " Reverses `self`, then concatenates two lists."]
    pub fn rev_append(&self, other: &List<T>) -> List<T> {
        match self.as_ref() {
            &Nil => other.clone(),
            &Cons(ref head, ref tail) => tail.rev_append(&head.clone().cons(other)),
        }
    }
    #[cfg(test)]
    fn take(self) -> std::rc::Rc<ListInner<T>> {
        self.inner
    }
}
fn append_tailrec<T: Clone>(list1: &List<T>, list2: &List<T>, list1_rev: List<T>) -> List<T> {
    match list1.as_ref() {
        &Nil => list1_rev.rev_append(list2),
        &Cons(ref head, ref tail) => append_tailrec(tail, list2, head.clone().cons(list1_rev)),
    }
}
impl<T: Clone> AsRef<ListInner<T>> for List<T> {
    fn as_ref(&self) -> &ListInner<T> {
        self.inner.as_ref()
    }
}
impl<T: Clone + std::fmt::Debug> std::fmt::Debug for List<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self.inner.as_ref() {
            &Nil => write!(f, "nil"),
            &Cons(ref head, ref tail) => write!(f, "{:?} :: {:?}", head, tail),
        }
    }
}
impl<T: Clone + PartialOrd> PartialOrd for List<T> {
    fn partial_cmp(&self, other: &List<T>) -> Option<std::cmp::Ordering> {
        use std::cmp::Ordering::*;
        match (self.as_ref(), other.as_ref()) {
            (&Nil, &Nil) => Some(Equal),
            (&Nil, &Cons(_, _)) => Some(Less),
            (&Cons(_, _), &Nil) => Some(Greater),
            (&Cons(ref head1, ref tail1), &Cons(ref head2, ref tail2)) => head1
                .partial_cmp(&head2)
                .and_then(|ordering| match ordering {
                    Equal => tail1.partial_cmp(tail2),
                    _ => Some(ordering),
                }),
        }
    }
}
impl<T: Clone + Ord> Ord for List<T> {
    fn cmp(&self, other: &List<T>) -> std::cmp::Ordering {
        use std::cmp::Ordering::*;
        match (self.as_ref(), other.as_ref()) {
            (&Nil, &Nil) => Equal,
            (&Nil, &Cons(_, _)) => Less,
            (&Cons(_, _), &Nil) => Greater,
            (&Cons(ref head1, ref tail1), &Cons(ref head2, ref tail2)) => match head1.cmp(&head2) {
                Equal => tail1.cmp(tail2),
                determined => determined,
            },
        }
    }
}
impl<T: Clone> Iterator for List<T> {
    type Item = T;
    fn next(&mut self) -> Option<T> {
        let cons;
        match self.as_ref() {
            &Nil => return None,
            &Cons(ref head, ref tail) => cons = (head.clone(), tail.clone()),
        }
        *self = cons.1;
        Some(cons.0)
    }
}
impl<'a, T: Clone> IntoIterator for &'a List<T> {
    type Item = T;
    type IntoIter = List<T>;
    fn into_iter(self) -> List<T> {
        self.iter()
    }
}
impl<T: Clone> std::iter::FromIterator<T> for List<T> {
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> List<T> {
        let xs: Vec<T> = iter.into_iter().collect();
        let mut list = List::nil();
        for x in xs.into_iter().rev() {
            list = x.cons(list);
        }
        list
    }
}
pub trait IntoCons<T: Clone, L: std::borrow::Borrow<List<T>>> {
    fn cons(self, tail: L) -> List<T>;
}
impl<T: Clone, L: std::borrow::Borrow<List<T>>> IntoCons<T, L> for T {
    fn cons(self, tail: L) -> List<T> {
        let tail_cloned: List<T> = tail.borrow().clone().into();
        let tail_len = tail_cloned.len;
        List {
            inner: std::rc::Rc::new(Cons(self, tail_cloned)),
            len: tail_len + 1,
        }
    }
}
#[macro_export]
macro_rules ! list { [ ] => { List :: nil ( ) } ; [ $ head : expr ] => { $ head . cons ( List :: nil ( ) ) } ; [ $ head : expr , $ ( $ tail : expr ) ,* ] => { $ head . cons ( list ! [ $ ( $ tail ) ,* ] ) } ; [ $ head : expr , $ ( $ tail : expr ) ,+ , ] => { list ! [ $ head , $ ( $ tail ) ,* ] } ; }

#[derive(Clone)]
pub struct StepBy<I> {
    iter: I,
    step: usize,
    first_take: bool,
}
impl<I: Iterator> Iterator for StepBy<I> {
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        if self.first_take {
            self.first_take = false;
            self.iter.next()
        } else {
            self.iter.nth(self.step)
        }
    }
}
#[derive(Clone)]
pub struct LScan<I: Iterator, S: Clone, F: FnMut(&S, I::Item) -> S> {
    iter: I,
    state: Option<S>,
    f: F,
}
impl<I: Iterator, S: Clone, F> Iterator for LScan<I, S, F>
where
    F: FnMut(&S, I::Item) -> S,
{
    type Item = S;
    fn next(&mut self) -> Option<S> {
        if self.state.is_none() {
            return None;
        }
        let state_inner = self.state.take().unwrap();
        if let Some(item) = self.iter.next() {
            self.state = Some((self.f)(&state_inner, item));
        }
        Some(state_inner)
    }
}
pub struct Flatten<I: Iterator>
where
    I::Item: IntoIterator,
{
    outer_iter: I,
    inner_iter: Option<<<I as Iterator>::Item as IntoIterator>::IntoIter>,
}
impl<I, J> Iterator for Flatten<I>
where
    I: Iterator<Item = J>,
    J: IntoIterator,
{
    type Item = <<J as IntoIterator>::IntoIter as Iterator>::Item;
    fn next(&mut self) -> Option<J::Item> {
        loop {
            if let Some(inner_iter) = self.inner_iter.as_mut() {
                if let item @ Some(_) = inner_iter.next() {
                    return item;
                }
            }
            match self.outer_iter.next() {
                None => return None,
                Some(inner) => self.inner_iter = Some(inner.into_iter()),
            }
        }
    }
}
pub struct GroupBy<K: Eq, I: Iterator, F: FnMut(&I::Item) -> K> {
    cur: Option<(I::Item, K)>,
    iter: I,
    key_fn: F,
}
impl<K: Eq, I: Iterator, F: FnMut(&I::Item) -> K> Iterator for GroupBy<K, I, F> {
    type Item = Vec<I::Item>;
    fn next(&mut self) -> Option<Vec<I::Item>> {
        let cur = self.cur.take();
        cur.map(|(item, key)| {
            let mut group = vec![item];
            loop {
                let next = self.iter.next();
                match next {
                    Some(next_item) => {
                        let next_key = (self.key_fn)(&next_item);
                        if key == next_key {
                            group.push(next_item);
                        } else {
                            self.cur = Some((next_item, next_key));
                            break;
                        }
                    }
                    None => {
                        self.cur = None;
                        break;
                    }
                }
            }
            group
        })
    }
}
use std::fmt;
pub trait RichIterator: Iterator {
    fn step_by_(self, step: usize) -> StepBy<Self>
    where
        Self: Sized,
    {
        assert_ne!(step, 0);
        StepBy {
            iter: self,
            step: step - 1,
            first_take: true,
        }
    }
    fn for_each<F: FnMut(Self::Item)>(self, mut f: F)
    where
        Self: Sized,
    {
        for item in self {
            f(item);
        }
    }
    fn lscan<S: Clone, F>(self, state: S, f: F) -> LScan<Self, S, F>
    where
        Self: Sized,
        F: FnMut(&S, Self::Item) -> S,
    {
        LScan {
            iter: self,
            state: Some(state),
            f: f,
        }
    }
    fn get_unique(mut self) -> Option<Self::Item>
    where
        Self: Sized,
        Self::Item: Eq,
    {
        let first_opt = self.next();
        first_opt.and_then(|first| {
            if self.all(|item| item == first) {
                Some(first)
            } else {
                None
            }
        })
    }
    fn flatten(mut self) -> Flatten<Self>
    where
        Self: Sized,
        Self::Item: IntoIterator,
    {
        let inner_opt = self.next();
        Flatten {
            outer_iter: self,
            inner_iter: inner_opt.map(|inner| inner.into_iter()),
        }
    }
    #[doc = " `f`\u{306b}\u{3088}\u{3063}\u{3066}\u{30b0}\u{30eb}\u{30fc}\u{30d7}\u{5206}\u{3051}\u{3055}\u{308c}\u{305f}`Vec`\u{3092}\u{751f}\u{6210}\u{3059}\u{308b}\u{30a4}\u{30c6}\u{30ec}\u{30fc}\u{30bf}\u{3092}\u{8fd4}\u{3059}"]
        #[doc = ""]
        #[doc = " SQL\u{306e}group_by\u{3067}\u{306f}\u{306a}\u{304f}\u{3001}Python\u{306e}itertool\u{3084}Rust\u{306e}itertool\u{3068}\u{540c}\u{3058}\u{610f}\u{5473}\u{8ad6}\u{3067}\u{3042}\u{308b}"]
    fn group_by<K: Eq, F: FnMut(&Self::Item) -> K>(mut self, mut f: F) -> GroupBy<K, Self, F>
    where
        Self: Sized,
    {
        let next = self.next();
        GroupBy {
            cur: next.map(|item| {
                let key = f(&item);
                (item, key)
            }),
            iter: self,
            key_fn: f,
        }
    }
    fn join(mut self, sep: &str) -> String
    where
        Self: Sized,
        Self::Item: fmt::Display,
    {
        let mut result = String::new();
        if let Some(first) = self.next() {
            result.push_str(&format!("{}", first));
        }
        for s in self {
            result.push_str(&format!("{}{}", sep, s));
        }
        result
    }
    fn cat(self) -> String
    where
        Self: Sized,
        Self::Item: fmt::Display,
    {
        self.join("")
    }
}
impl<I: Iterator> RichIterator for I {}
pub struct Unfold<T, F>
where
    F: FnMut(&T) -> Option<T>,
{
    state: Option<T>,
    f: F,
}
impl<T, F> Iterator for Unfold<T, F>
where
    F: FnMut(&T) -> Option<T>,
{
    type Item = T;
    fn next(&mut self) -> Option<T> {
        if self.state.is_none() {
            return None;
        }
        let state_inner = self.state.take().unwrap();
        self.state = (self.f)(&state_inner);
        Some(state_inner)
    }
}
pub fn unfold<T, F>(init: T, f: F) -> Unfold<T, F>
where
    F: FnMut(&T) -> Option<T>,
{
    Unfold {
        state: Some(init),
        f: f,
    }
}
pub struct Iterate<T, F>
where
    F: FnMut(&T) -> T,
{
    state: T,
    f: F,
}
impl<T, F> Iterator for Iterate<T, F>
where
    F: FnMut(&T) -> T,
{
    type Item = T;
    fn next(&mut self) -> Option<T> {
        use std::mem::swap;
        let mut state = (self.f)(&self.state);
        swap(&mut state, &mut self.state);
        Some(state)
    }
}
pub fn iterate<T, F>(init: T, f: F) -> Iterate<T, F>
where
    F: FnMut(&T) -> T,
{
    Iterate { state: init, f: f }
}

use std::collections::HashMap;

fn split(mut r: Vec<u8>, mut b: Vec<u8>, rest: &[u8],
         map: &mut HashMap<(Vec<u8>, Vec<u8>), usize>) {
    match rest.split_first() {
        None => {
            r.reverse();
            b.reverse();
            let mut count = map.entry((b, r)).or_insert(0);
            *count += 1;
        },
        Some((&hd, tl)) => {
            let mut next_r = r.clone();
            next_r.push(hd);
            let mut next_b = b.clone();
            next_b.push(hd);
            split(next_r, b, tl, map);
            split(r, next_b, tl, map);
        }
    }
}

fn count(r: Vec<u8>, b: Vec<u8>, rest: &[u8],
         map: &HashMap<(Vec<u8>, Vec<u8>), usize>) -> usize {
    match rest.split_first() {
        None => map.get(&(r, b)).cloned().unwrap_or(0),
        Some((&hd, tl)) => {
            let mut next_r = r.clone();
            next_r.push(hd);
            let mut next_b = b.clone();
            next_b.push(hd);
            count(next_r, b, tl, map) + count(r, next_b, tl, map)
        }
    }
}

fn main() {
    read!();
    read!(s = String);
    let (left, right) = s.as_bytes().split_at(s.len()/2);

    let mut map = HashMap::new();
    split(Vec::new(), Vec::new(), &left, &mut map);
    println!("{}", count(Vec::new(), Vec::new(), &right, &map));
}


Measured memory_bytes: 63756