#![allow(dead_code, unused_imports)]
#[rustfmt::skip] #[macro_use] mod scanner {use std::io::{stdin, BufReader, Bytes, Error as IoError, Read, Stdin};use std::str::{self, FromStr, Utf8Error};#[derive(Debug)] pub struct Scanner<R: Read> { bytes: Bytes<BufReader<R>>, buf: Vec<u8>, }  #[derive(Debug)] pub enum ScanError<T: FromStr> { Io(IoError), Parse(T::Err, String), NonUtf8(Utf8Error, Vec<u8>), }  impl Scanner<Stdin> { pub fn stdin() -> Self { Self::new(stdin()) } }  impl<R: Read> Scanner<R> { pub fn new(reader: R) -> Self { Self { bytes: BufReader::new(reader).bytes(), buf: Vec::new(), } }  #[allow(clippy::should_implement_trait)] pub fn next<T: FromStr>(&mut self) -> Result<T, ScanError<T>> { assert!(self.buf.is_empty());for b in &mut self.bytes { let b = b.map_err(ScanError::Io)?;if b.is_ascii_whitespace() {  if self.buf.is_empty() { continue;} else { break;} } else { self.buf.push(b);} }   match str::from_utf8(&self.buf) { Err(err) => Err(ScanError::NonUtf8(err, std::mem::take(&mut self.buf))), Ok(s) => { let ret = s.parse().map_err(|err| ScanError::Parse(err, s.to_owned()));self.buf.clear();ret } } } }  #[macro_export] macro_rules! scan { ($scanner:expr) => { $scanner.next().expect("failed to read token") };($scanner:expr, $type:ty) => { $scanner .next::<$type>() .expect(concat!("failed to read token of type ", stringify!($type))) };($scanner:expr, $type:ty; $n:expr) => { (0..$n).map(|_| scan!($scanner)).collect::<Vec<$type>>() };($scanner:expr, $($type:ty),+) => { ($( scan!($scanner, $type), )+) };} }
#[rustfmt::skip] #[macro_use] mod writer {use std::fmt::Display;use std::io::{stdout, BufWriter, Error as IoError, Stdout, Write};#[derive(Debug)] pub struct Writer<W: Write> { writer: BufWriter<W>, }  impl Writer<Stdout> { pub fn stdout() -> Self { Self::new(stdout()) } }  impl<W: Write> Writer<W> { pub fn new(writer: W) -> Self { Self { writer: BufWriter::new(writer), } }  pub fn write<M, T: Writable<M>>(&mut self, val: T) -> Result<(), IoError> { val.write_to(&mut self.writer) }  pub fn flush(&mut self) -> Result<(), IoError> { self.writer.flush() } }  pub trait Writable<Mode> { fn write_to<W: Write>(self, w: &mut W) -> Result<(), IoError>;}  #[non_exhaustive] pub struct Single;impl<T: Display> Writable<Single> for T { fn write_to<W: Write>(self, w: &mut W) -> Result<(), IoError> { writeln!(w, "{}", self) } }  #[non_exhaustive] pub struct Many;impl<I> Writable<Many> for I where I: Iterator, I::Item: Display, { fn write_to<W: Write>(mut self, w: &mut W) -> Result<(), IoError> { if let Some(x) = self.next() { write!(w, "{}", x)?;} else {  return Ok(());}  for x in self { write!(w, " {}", x)?;} writeln!(w) } }  #[non_exhaustive] pub struct Array;impl<T: Display> Writable<Array> for &[T] { fn write_to<W: Write>(self, w: &mut W) -> Result<(), IoError> { self.iter().write_to(w) } } }
#[rustfmt::skip] #[macro_use] mod prefix_sum {use std::ops::{Add, Bound, Range, RangeBounds, Sub};#[derive(Debug, Clone)] pub struct PrefixOp<T, I> { pref: Vec<T>, inverse: Option<I>, }  impl<T, I> PrefixOp<T, I> {  pub fn len(&self) -> usize { self.pref.len() }   pub fn is_empty(&self) -> bool { self.pref.is_empty() }   #[track_caller] fn verify_range_bounds<R: RangeBounds<usize>>(&self, range: R) -> Range<usize> { let start = match range.start_bound() { Bound::Unbounded => 0, Bound::Included(&x) => x, Bound::Excluded(&x) => x + 1, };let end = match range.end_bound() { Bound::Unbounded => self.len(), Bound::Included(&x) => x + 1, Bound::Excluded(&x) => x, };assert!( start < end, "range inverted: start >= end ({} >= {})", start, end );assert!( end <= self.len(), "range out of bounds: end > len ({} > {})", end, self.len() );Range { start, end } }     pub fn query_prefix<R: RangeBounds<usize>>(&self, range: R) -> T where T: Clone, { let Range { start, end } = self.verify_range_bounds(range);assert!(start == 0, "query start bound is non-zero: {} > 0", start);self.pref[end - 1].clone() } }  impl<T> PrefixOp<T, ()> {  pub fn new<F>(mut arr: Vec<T>, op: F) -> Self where F: Fn(&T, &T) -> T, { for i in 1..arr.len() { arr[i] = op(&arr[i - 1], &arr[i]);} PrefixOp { pref: arr, inverse: None, } } }  impl<T, I> PrefixOp<T, I> where I: Fn(&T, &T) -> T, {     pub fn new_invertible<F>(mut arr: Vec<T>, op: F, inverse: I) -> Self where F: Fn(&T, &T) -> T, { for i in 1..arr.len() { arr[i] = op(&arr[i - 1], &arr[i]);} PrefixOp { pref: arr, inverse: Some(inverse), } }   pub fn query<R: RangeBounds<usize>>(&self, range: R) -> T where T: Clone, { let Range { start, end } = self.verify_range_bounds(range);if start == 0 { self.pref[end - 1].clone() } else { (self .inverse .as_ref() .expect("range query is not supported on non-invertible operation"))( &self.pref[end - 1], &self.pref[start - 1], ) } } }  type NextFn<T> = fn(&T, &T) -> T;pub trait PrefixSums { type Data;fn prefix_sums(self) -> PrefixOp<Self::Data, NextFn<Self::Data>>;}  impl<T> PrefixSums for Vec<T> where T: Add<Output = T> + Sub<Output = T> + Clone, { type Data = T;fn prefix_sums(self) -> PrefixOp<Self::Data, NextFn<Self::Data>> { PrefixOp::new_invertible( self, |a, b| a.clone() + b.clone(), |b, a| b.clone() - a.clone(), ) } } }
#[rustfmt::skip] #[macro_use] mod util {   pub trait IntoVec<T, _Hack> { fn into_vec(self) -> Vec<T>;}  #[non_exhaustive] pub struct Owned;impl<I, T> IntoVec<T, Owned> for I where I: Iterator<Item = T>, { fn into_vec(self) -> Vec<T> { self.collect() } }  #[non_exhaustive] pub struct Reference;impl<'a, I, T> IntoVec<T, Reference> for I where I: Iterator<Item = &'a T>, T: Clone + 'a, { fn into_vec(self) -> Vec<T> { self.cloned().collect() } }  pub trait Argmax { fn argmax(self) -> Option<usize>;}  impl<I> Argmax for I where I: Iterator, I::Item: Ord, { fn argmax(self) -> Option<usize> { self.fold((0, None), |(i, mx), next| { if let Some((mx_i, mx_v)) = mx { if next.gt(&mx_v) { (i + 1, Some((i, next))) } else { (i + 1, Some((mx_i, mx_v))) } } else { (i + 1, Some((i, next))) } }) .1 .map(|x| x.0) } }  pub trait Sorted { fn sorted(self) -> Self;}  impl<T> Sorted for Vec<T> where T: Ord, { fn sorted(mut self) -> Self { self.sort();self } }  pub trait Choose { fn choose<T>(self, a: T, b: T) -> T;}  impl Choose for bool { fn choose<T>(self, a: T, b: T) -> T { if self { a } else { b } } }  #[allow(unused_macros)] macro_rules! p { ( $( $x:expr ),* ) => { #[cfg(any(debug_assertions, debug_print))] { dbg!( $( & $x, )* );} };} }
#[rustfmt::skip] #[macro_use] mod graph {use std::{convert::TryInto, fmt::Debug};#[derive(Debug, Clone, PartialEq, Eq)] pub struct Graph<Id: VertexRepr> { adj: Vec<Vec<Id>>, }      pub trait VertexRepr: Clone + Copy { fn from(id: usize) -> Self;fn to_usize(self) -> usize;fn invalid() -> Self;fn is_valid(&self) -> bool;}  impl VertexRepr for u32 { fn from(id: usize) -> Self { let id = match id.try_into() { Ok(x) => x, Err(_) => panic!("vertex id {} excceds implementation limit", id), };assert_ne!( id, u32::MAX, "vertex id {} exceeds implementation limit", id );id }  fn to_usize(self) -> usize { self as usize }  fn invalid() -> Self { u32::MAX }  fn is_valid(&self) -> bool { *self != u32::MAX } }  impl<Id: VertexRepr> Graph<Id> {  pub fn empty() -> Self { Graph { adj: Vec::new() } }   pub fn with_vertices(n: usize) -> Self { Graph { adj: (0..n).map(|_| Vec::new()).collect(), } }   #[track_caller] fn verify_vertex(&self, v: Id) -> Id { assert!(v.is_valid(), "vertex is invalid");assert!( v.to_usize() < self.n(), "vertex {} does not exist", v.to_usize() );v }   pub fn add_vertex(&mut self) -> Id { self.adj.push(Vec::new());Id::from(self.adj.len() - 1) }      pub fn add_edge(&mut self, u: Id, v: Id, directed: bool) { let (u, v) = (self.verify_vertex(u), self.verify_vertex(v));if !directed { self.adj[v.to_usize()].push(u);} self.adj[u.to_usize()].push(v);}   pub fn adjacent( &self, u: Id, ) -> impl Iterator<Item = Id> + DoubleEndedIterator + ExactSizeIterator + '_ { let u = self.verify_vertex(u);self.adj[u.to_usize()].iter().copied() }   pub fn n(&self) -> usize { self.adj.len() }     pub fn dfs(&self, source: Id, mut state: DfsState<Id>) -> DfsState<Id> { let s = self.verify_vertex(source).to_usize();let mut stack = Vec::new();if !state.visited[s] { stack.push((s, 0));state.visited[s] = true;state.parent[s] = Id::invalid();state.depth[s] = Id::from(0);}  while let Some((cur, child_id)) = stack.last_mut() { if let Some(&child_vid) = self.adj[*cur].get(*child_id) { *child_id += 1;let child = child_vid.to_usize();if !state.visited[child] { state.visited[child] = true;state.parent[child] = Id::from(*cur);state.depth[child] = Id::from(stack.len());stack.push((child, 0));} } else { stack.pop();} }  state } }    #[non_exhaustive] #[derive(Debug, Clone, PartialEq, Eq)] pub struct DfsState<Id: VertexRepr> { pub visited: Vec<bool>,   pub parent: Vec<Id>, pub depth: Vec<Id>, }  impl<Id: VertexRepr> DfsState<Id> {  pub fn new(graph: &Graph<Id>) -> Self { DfsState { visited: vec![false; graph.n()], parent: vec![Id::invalid(); graph.n()], depth: vec![Id::invalid(); graph.n()], } } } }
#[rustfmt::skip] #[macro_use] mod number_theory {            pub fn gcd(mut a: i64, mut b: i64) -> i64 { while b != 0 { let t = b;b = a % b;a = t;}  a.checked_abs().unwrap_or(a) }      pub fn egcd(a: i64, b: i64) -> (i64, i64, i64) { if b == 0 {  if a >= 0 || a == i64::MIN { (a, 1, 0) } else { (-a, -1, 0) } } else { let (g, s, t) = egcd(b, a % b);(g, t, s - a / b * t) } }      pub fn mod_exp(a: i64, mut b: i64, m: i64) -> i64 { assert!(m > 0, "modulus must be positive: {} <= 0", m);if b < 0 { return mod_exp( mod_mulinv(a, m), b.checked_neg().expect("cannot raise to i64::MIN power"), m, );}  let intermediate_error = "intermediate value overflowed";let mut x = 1i64;let mut pwr = a;while b > 0 { if b & 1 > 0 { x = x.checked_mul(pwr).expect(intermediate_error).rem_euclid(m);} pwr = pwr .checked_mul(pwr) .expect(intermediate_error) .rem_euclid(m);b >>= 1;} x }      pub fn mod_mulinv(a: i64, m: i64) -> i64 { assert!(m > 0, "modulus must be positive: {} <= 0", m);let (g, s, _) = egcd(a, m);assert_eq!( g, 1, "multiplicative inverse does not exist: {} and {} have gcd {}", a, m, g );s.rem_euclid(m) } }
#[rustfmt::skip] #[macro_use] mod segment_tree {use std::{ fmt::{self, Debug, Formatter}, ops::{Bound, Range, RangeBounds}, };pub trait Spec { type Node;type Update: Clone;type Formatter: Format<Node = Self::Node>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node;fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node;fn compose(f: &Self::Update, g: &Self::Update) -> Self::Update;}        pub trait EagerSpec { type Node;type Formatter: Format<Node = Self::Node>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node;}  impl<T: EagerSpec> Spec for T { type Node = T::Node;type Update = ();type Formatter = T::Formatter;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { T::op(a, b) } fn apply(_f: &Self::Update, _a: &Self::Node) -> Self::Node { panic!("eager spec does not support range updates") } fn compose(_f: &Self::Update, _g: &Self::Update) -> Self::Update { panic!("eager spec does not support range updates") } }      pub trait Format { type Node;type Input;type Output;fn input(a: Self::Input, i: usize) -> Self::Node;fn output(a: &Self::Node) -> Self::Output;}               pub struct SegmentTree<S: Spec> { data: Vec<S::Node>, updates: Vec<Option<S::Update>>,  needs_update_propagation: bool, }  impl<S: Spec> SegmentTree<S> {  #[track_caller] pub fn new(vals: Vec<<S::Formatter as Format>::Input>) -> Self { let n = vals.len();let mut data = Vec::with_capacity( n.checked_mul(2) .expect("size needed for tree overflowed") .saturating_sub(1), );data.extend( vals.into_iter() .enumerate() .map(|(i, x)| S::Formatter::input(x, i)) .rev(), );for i in 0..n.saturating_sub(1) { data.push(S::op(&data[2 * i + 1], &data[2 * i]));} data.reverse();let mut updates = Vec::with_capacity(n.saturating_sub(1));updates.resize_with(n.saturating_sub(1), || None);SegmentTree { data, updates, needs_update_propagation: false, } }   pub fn len(&self) -> usize { (self.data.len() + 1) / 2 }   pub fn is_empty(&self) -> bool { self.data.is_empty() }   pub fn height(&self) -> usize { let n = self.len();(0usize.leading_zeros() - n.leading_zeros()) as usize }   #[track_caller] pub fn query(&mut self, range: impl RangeBounds<usize>) -> <S::Formatter as Format>::Output { let Range { start: left, end: right, } = self.verify_range_bounds(range);if self.needs_update_propagation { self.push_updates_to(left + self.len());self.push_updates_to(right + self.len() - 1);}  let (mut res_l_owned, mut res_r_owned);let (mut res_l, mut res_r) = (None, None);let (mut l, mut r) = (left + self.len(), right + self.len());while l < r { if l % 2 == 1 { if let Some(prev_res_l) = res_l.take() { res_l_owned = S::op(prev_res_l, &self.data[l - 1]);res_l = Some(&res_l_owned);} else { res_l = Some(&self.data[l - 1]);} l += 1;} if r % 2 == 1 { r -= 1;if let Some(prev_res_r) = res_r { res_r_owned = S::op(&self.data[r - 1], prev_res_r);res_r = Some(&res_r_owned);} else { res_r = Some(&self.data[r - 1]);} } l /= 2;r /= 2;}  match (res_l, res_r) { (Some(l), Some(r)) => S::Formatter::output(&S::op(l, r)), (Some(x), None) | (None, Some(x)) => S::Formatter::output(x), (None, None) => unreachable!( "both left and right results are None - empty query should not have been allowed" ), } }    #[track_caller] fn verify_range_bounds(&self, range: impl RangeBounds<usize>) -> Range<usize> { let left = match range.start_bound() { Bound::Included(&x) => x, Bound::Excluded(&x) => x + 1, Bound::Unbounded => 0, };let right = match range.end_bound() { Bound::Included(&x) => x + 1, Bound::Excluded(&x) => x, Bound::Unbounded => self.len(), };assert!( left < right, "range inverted: left >= right ({} >= {})", left, right );assert!( right <= self.len(), "range out of bounds: right > n ({} > {})", right, self.len() );Range { start: left, end: right, } }   fn push_updates_to(&mut self, i: usize) { for h in (1..self.height()).rev() { let ip = i >> h;if let Some(upd) = self.updates[ip - 1].take() { self.apply_update_to(2 * ip, &upd);self.apply_update_to(2 * ip + 1, &upd);} } }   fn push_updates_to_range(&mut self, range: Range<usize>) { let (l, r) = (range.start, range.end - 1);for h in (1..self.height()).rev() { let (lp, rp) = (l >> h, r >> h);for x in lp..=rp { if let Some(upd) = self.updates[x - 1].take() { self.apply_update_to(2 * x, &upd);self.apply_update_to(2 * x + 1, &upd);} } } }   fn update_parents_of(&mut self, i: usize) { for h in 1..self.height() { let ip = i >> h;self.data[ip - 1] = S::op(&self.data[2 * ip - 1], &self.data[2 * ip]);if self.needs_update_propagation { if let Some(ref upd) = self.updates[ip - 1] { self.data[ip - 1] = S::apply(upd, &self.data[ip - 1]);} } } }   fn update_parents_of_range(&mut self, range: Range<usize>) { let (l, r) = (range.start, range.end - 1);for h in 1..self.height() { let (lp, rp) = (l >> h, r >> h);for x in lp..=rp { self.data[x - 1] = S::op(&self.data[2 * x - 1], &self.data[2 * x]);if self.needs_update_propagation { if let Some(ref upd) = self.updates[x - 1] { self.data[x - 1] = S::apply(upd, &self.data[x - 1]);} } } } }   fn apply_update_to(&mut self, i: usize, f: &S::Update) { self.data[i - 1] = S::apply(f, &self.data[i - 1]);if i < self.len() { self.updates[i - 1] = match self.updates[i - 1].take() { None => Some(f.clone()), Some(g) => Some(S::compose(&g, f)), };} }   #[track_caller] fn verify_index(&self, index: usize) -> usize { assert!( index < self.len(), "index out of bounds: index >= n ({} >= {})", index, self.len() );index }   #[track_caller] pub fn set(&mut self, index: usize, val: <S::Formatter as Format>::Input) { let i = self.verify_index(index) + self.len();if self.needs_update_propagation { self.push_updates_to(i);} self.data[i - 1] = S::Formatter::input(val, i);self.update_parents_of(i) }   #[track_caller] pub fn get(&mut self, index: usize) -> <S::Formatter as Format>::Output { let i = self.verify_index(index) + self.len();if self.needs_update_propagation { self.push_updates_to(i);} S::Formatter::output(&self.data[i - 1]) }   #[track_caller] pub fn update(&mut self, range: impl RangeBounds<usize>, update: S::Update) { let Range { start: left, end: right, } = self.verify_range_bounds(range);if self.needs_update_propagation { self.push_updates_to(left + self.len());self.push_updates_to(right + self.len() - 1);} self.needs_update_propagation = true;let (mut l, mut r) = (left + self.len(), right + self.len());while l < r { if l % 2 == 1 { self.apply_update_to(l, &update);l += 1;} if r % 2 == 1 { r -= 1;self.apply_update_to(r, &update);} l /= 2;r /= 2;}  self.update_parents_of(left + self.len());self.update_parents_of(right + self.len() - 1);}   #[track_caller] pub fn view(&mut self, range: impl RangeBounds<usize>, f: impl FnOnce(&[S::Node])) { let Range { start: left, end: right, } = self.verify_range_bounds(range);let range = left + self.len()..right + self.len();if self.needs_update_propagation { self.push_updates_to_range(range.clone());} f(&self.data[range.start - 1..range.end - 1]);}    #[track_caller] pub fn view_mut(&mut self, range: impl RangeBounds<usize>, f: impl FnOnce(&mut [S::Node])) { let Range { start: left, end: right, } = self.verify_range_bounds(range);let range = left + self.len()..right + self.len();if self.needs_update_propagation { self.push_updates_to_range(range.clone());} f(&mut self.data[range.start - 1..range.end - 1]);self.update_parents_of_range(range);} }  impl<S> Debug for SegmentTree<S> where S: Spec, S::Node: Debug, S::Update: Debug, { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.debug_struct("SegmentTree") .field("data", &self.data) .field("updates", &self.updates) .field("needs_update_propagation", &self.needs_update_propagation) .finish() } }  impl<S> Clone for SegmentTree<S> where S: Spec, S::Node: Clone, S::Update: Clone, { fn clone(&self) -> Self { SegmentTree { data: self.data.clone(), updates: self.updates.clone(), needs_update_propagation: self.needs_update_propagation, } } }  pub mod ops { use super::{EagerSpec, Format, Spec};use std::{marker::PhantomData, ops::Add};pub struct AsNode<T>(PhantomData<T>);impl<T> Format for AsNode<T> where T: Clone, { type Node = T;type Input = T;type Output = T;fn input(a: Self::Input, _i: usize) -> Self::Node { a } fn output(a: &Self::Node) -> Self::Output { a.clone() } }   pub struct Sum<T>(PhantomData<T>);impl<T> EagerSpec for Sum<T> where T: Clone + Add<Output = T>, { type Node = T;type Formatter = AsNode<T>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { a.clone() + b.clone() } }    pub struct Min<T>(PhantomData<T>);impl<T> Spec for Min<T> where T: Clone + Ord, { type Node = T;type Update = T;type Formatter = AsNode<T>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { Ord::min(a, b).clone() } fn compose(f: &Self::Update, g: &Self::Update) -> Self::Update { Ord::min(f, g).clone() } fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node { Ord::min(f, a).clone() } }    pub struct Max<T>(PhantomData<T>);impl<T> Spec for Max<T> where T: Clone + Ord, { type Node = T;type Update = T;type Formatter = AsNode<T>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { Ord::max(a, b).clone() } fn compose(f: &Self::Update, g: &Self::Update) -> Self::Update { Ord::max(f, g).clone() } fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node { Ord::max(f, a).clone() } }   pub struct ValueIndex<T>(PhantomData<T>);impl<T> Format for ValueIndex<T> { type Node = (T, usize);type Input = T;type Output = usize;fn input(a: Self::Input, i: usize) -> Self::Node { (a, i) } fn output(a: &Self::Node) -> Self::Output { a.1 } }      pub struct Argmin<T>(PhantomData<T>);impl<T> Spec for Argmin<T> where T: Clone + Ord, { type Node = (T, usize);type Update = T;type Formatter = ValueIndex<T>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { if a.0 <= b.0 { a.clone() } else { b.clone() } } fn compose(f: &Self::Update, g: &Self::Update) -> Self::Update { Ord::min(f, g).clone() } fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node { (Ord::min(&a.0, f).clone(), a.1) } }      pub struct Argmax<T>(PhantomData<T>);impl<T> Spec for Argmax<T> where T: Clone + Ord, { type Node = (T, usize);type Update = T;type Formatter = ValueIndex<T>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { if a.0 >= b.0 { a.clone() } else { b.clone() } } fn compose(f: &Self::Update, g: &Self::Update) -> Self::Update { Ord::max(f, g).clone() } fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node { (Ord::max(&a.0, f).clone(), a.1) } }   pub struct MinAdd<T>(PhantomData<T>);impl<T> Spec for MinAdd<T> where T: Clone + Ord + Add<Output = T>, { type Node = T;type Update = T;type Formatter = AsNode<T>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { Ord::min(a, b).clone() } fn compose(f: &Self::Update, g: &Self::Update) -> Self::Update { f.clone() + g.clone() } fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node { f.clone() + a.clone() } }   pub struct MaxAdd<T>(PhantomData<T>);impl<T> Spec for MaxAdd<T> where T: Clone + Ord + Add<Output = T>, { type Node = T;type Update = T;type Formatter = AsNode<T>;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { Ord::max(a, b).clone() } fn compose(f: &Self::Update, g: &Self::Update) -> Self::Update { f.clone() + g.clone() } fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node { f.clone() + a.clone() } }      pub struct SumSet(());impl Spec for SumSet { type Node = (i64, usize);type Update = i64;type Formatter = SumSet;fn op(a: &Self::Node, b: &Self::Node) -> Self::Node { (a.0 + b.0, a.1 + b.1) }  fn compose(_f: &Self::Update, g: &Self::Update) -> Self::Update { *g } fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node { (a.1 as i64 * *f, a.1) } }  impl Format for SumSet { type Node = (i64, usize);type Input = i64;type Output = i64;fn input(a: Self::Input, _i: usize) -> Self::Node { (a, 1) } fn output(a: &Self::Node) -> Self::Output { a.0 } } } }

use std::sync::atomic::{AtomicI64, Ordering};

use graph::{DfsState, Graph};
use number_theory::{egcd, gcd, mod_exp, mod_mulinv};
use prefix_sum::{PrefixOp, PrefixSums};
use scanner::Scanner;
use segment_tree::{SegmentTree, Spec};
use util::{Argmax, Choose, IntoVec, Sorted};
use writer::Writer;

static mut MOD: i64 = 0;

fn main() {
    let mut sc = Scanner::stdin();
    let mut wr = Writer::stdout();

    let (n, m) = scan!(sc, usize, i64);
    unsafe {
        MOD = m;
    }
    //let mut tree = SegmentTree::<MySpec>::new(vec![0; n + 1]);
    //tree.set(n, 1);
    // suffix[i] = sum of ways to get to i and later fields
    let mut suffix = vec![0; n + 1];
    suffix[n] = 1;

    for x in (1..=n).rev() {
        //let mut cnt = tree.query(x..);
        let mut cnt = suffix[x];
        //p!(x, cnt);

        for z in 2.. {
            if x * z > n {
                break;
            }
            //let inc = tree.query(x * z..((x + 1) * z).min(n + 1));
            let inc = suffix[x * z] - suffix.get((x + 1) * z).copied().unwrap_or(0);
            p!(x, z, inc);
            cnt = (cnt + inc) % m;
        }

        //tree.set(x, cnt);
        p!(x, cnt);
        suffix[x] = (suffix.get(x + 1).copied().unwrap_or(0) + cnt) % m;
        suffix[x - 1] = suffix[x];
        p!(x, suffix[x]);
    }

    //wr.write(tree.get(1)).unwrap();
    wr.write((suffix[1] - suffix[2] + m) % m).unwrap();
}

struct MySpec;
impl Spec for MySpec {
    type Node = i64;
    type Update = ();
    type Formatter = segment_tree::ops::AsNode<i64>;
    fn op(a: &Self::Node, b: &Self::Node) -> Self::Node {
        unsafe { (*a + *b) % MOD }
    }
    fn compose(a: &Self::Update, b: &Self::Update) -> Self::Update {
        unreachable!()
    }
    fn apply(f: &Self::Update, a: &Self::Node) -> Self::Node {
        unreachable!()
    }
}


#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![allow(unused_mut)]
#![allow(unused_variables)]
#![allow(dead_code)]

type Vec2<T> = Vec<Vec<T>>;
type Vec3<T> = Vec<Vec<Vec<T>>>;

#[allow(unused_macros)]
macro_rules! invec {
    ( $ t : ty ) => {{
        let mut s = String::new();
        match std::io::stdin().read_line(&mut s) {
            Ok(0) => Vec::<$t>::new(),
            Ok(n) => s
                .trim()
                .split_whitespace()
                .map(|s| s.parse::<$t>().unwrap())
                .collect::<Vec<$t>>(),
            Err(_) => Vec::<$t>::new(),
        }
    }};
}

#[allow(unused_macros)]
macro_rules! get {
      ($t:ty) => {
          {
              let mut line: String = String::new();
              std::io::stdin().read_line(&mut line).unwrap();
              line.trim().parse::<$t>().unwrap()
          }
      };
      ($($t:ty),*) => {
          {
              let mut line: String = String::new();
              std::io::stdin().read_line(&mut line).unwrap();
              let mut iter = line.split_whitespace();
              (
                  $(iter.next().unwrap().parse::<$t>().unwrap(),)*
              )
          }
      };
      ($t:ty; $n:expr) => {
          (0..$n).map(|_|
              get!($t)
          ).collect::<Vec<_>>()
      };
      ($($t:ty),*; $n:expr) => {
          (0..$n).map(|_|
              get!($($t),*)
          ).collect::<Vec<_>>()
      };
      ($t:ty ;;) => {
          {
              let mut line: String = String::new();
              std::io::stdin().read_line(&mut line).unwrap();
              line.split_whitespace()
                  .map(|t| t.parse::<$t>().unwrap())
                  .collect::<Vec<_>>()
          }
      };
      ($t:ty ;; $n:expr) => {
          (0..$n).map(|_| get!($t ;;)).collect::<Vec<_>>()
      };
}

#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
    ($iter:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($next:expr, [$t:tt]) => {
        {
            let len = read_value!($next, usize);
            (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
        }
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_macros)]
#[cfg(debug_assertions)]
macro_rules! mydbg {
    //($arg:expr) => (dbg!($arg))
    //($arg:expr) => (println!("{:?}",$arg));
      ($($a:expr),*) => {
          eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
      }
}
#[cfg(not(debug_assertions))]
macro_rules! mydbg {
    ($($arg:expr),*) => {};
}

macro_rules! echo {
    ($($a:expr),*) => {
          $(println!("{}",$a))*
      }
}

use std::cmp::*;
use std::collections::*;
use std::ops::{Add, Div, Mul, Rem, Sub};

trait SafeRangeContain {
    fn safe_contains(&self, x: i64) -> bool;
}

impl SafeRangeContain for std::ops::Range<usize> {
    fn safe_contains(&self, x: i64) -> bool {
        if x < 0 {
            return false;
        }
        return self.contains(&(x as usize));
    }
}

#[allow(dead_code)]
static INF_I64: i64 = i64::max_value() / 2;
#[allow(dead_code)]
static INF_I32: i32 = i32::max_value() / 2;
#[allow(dead_code)]
static INF_USIZE: usize = usize::max_value() / 2;
#[allow(dead_code)]
static M_O_D: usize = 1000000007;
#[allow(dead_code)]
static PAI: f64 = 3.1415926535897932;

trait IteratorExt: Iterator {
    fn toVec(self) -> Vec<Self::Item>;
}

impl<T: Iterator> IteratorExt for T {
    fn toVec(self) -> Vec<Self::Item> {
        self.collect()
    }
}

trait CharExt {
    fn toNum(&self) -> usize;
    fn toAlphabetIndex(&self) -> usize;
    fn toNumIndex(&self) -> usize;
}
impl CharExt for char {
    fn toNum(&self) -> usize {
        return *self as usize;
    }
    fn toAlphabetIndex(&self) -> usize {
        return self.toNum() - 'a' as usize;
    }
    fn toNumIndex(&self) -> usize {
        return self.toNum() - '0' as usize;
    }
}

trait VectorExt {
    fn joinToString(&self, s: &str) -> String;
}
impl<T: ToString> VectorExt for Vec<T> {
    fn joinToString(&self, s: &str) -> String {
        return self
            .iter()
            .map(|x| x.to_string())
            .collect::<Vec<_>>()
            .join(s);
    }
}

trait StringExt {
    fn get_reverse(&self) -> String;
}
impl StringExt for String {
    fn get_reverse(&self) -> String {
        self.chars().rev().collect::<String>()
    }
}

trait UsizeExt {
    fn pow(&self, n: usize) -> usize;
}
impl UsizeExt for usize {
    fn pow(&self, n: usize) -> usize {
        return ((*self as u64).pow(n as u32)) as usize;
    }
}

fn main() {
    solve();
}

fn solve() {
    let mut ans: u64 = 0;
    let (N, M) = get!(usize, u64);

    let mut dp = vec![0; N + 5];
    dp[N] = 1;
    let mut sum = 0;
    for i in (1..=N).rev() {
        dp[i] += sum;
        dp[i] %= M;

        for j in 1..i {
            if j * j > i {
                break;
            }

            let b = i / (j + 1);
            let c = i / j;
            let d = (dp[i] * (c - b) as u64) % M;
            dp[j] += d;
            dp[j] %= M;

            if j != i / j {
                let a = i / j;
                if a == i {
                    continue;
                }
                let b = i / (a + 1);
                let c = i / a;
                let d = (dp[i] * (c - b) as u64) % M;
                dp[a] += d;
                dp[a] %= M;
            }
        }

        sum += dp[i];
        sum %= M;
    }
    let ans = dp[1] % M;

    echo!(ans);
}


use std::io::{ self, BufRead };
use std::collections::*;

macro_rules! scan_line {
    () => ({
        let stdin = io::stdin();
        let mut handle = stdin.lock();
        let mut buffer = String::new();
        handle.read_line(&mut buffer)
            .expect("scan_line: failed at `handle.read_line`.");
        buffer
    });
    ( $($t:ty)+ ) => ({
        let stdin = io::stdin();
        let mut handle = stdin.lock();
        let mut buffer = String::new();
        handle.read_line(&mut buffer)
            .expect("scan_line: failed at `handle.read_line`.");
        let mut chunks = buffer.split_whitespace();

        ($(
            {
                chunks.next()
                    .expect("scan_line: failed at `next`, # of space separated strings not equal to requested #")
                .parse::<$t>()
                    .expect("scan_line: failed at `parse::<$t>`.")
            },
        )+)
    })
}

fn main() {
    let (ax, ay, bx, by, cx, cy) = scan_line!(i64 i64 i64 i64 i64 i64);

    let d1 = (ax - bx)*(ax - bx) + (ay - by)*(ay - by);
    let d2 = (bx - cx)*(bx - cx) + (by - cy)*(by - cy);
    let area = ax*(by - cy) + bx*(cy - ay) + cx*(ay - by);

    if d1 == d2 && area != 0 {
        println!("YES");
    } else {
        println!("NO");
    }
}


use std::io::{self, Read};
use std::iter::FromIterator;

#[allow(dead_code)]
struct Source {
    chars: Box<Iterator<Item = char>>,
}

#[allow(dead_code)]
impl Source {
    fn next_chr(&mut self) -> char {
        self.chars
            .by_ref()
            .skip_while(|c| char::is_whitespace(*c))
            .next()
            .expect("eof")
    }

    fn next_str(&mut self) -> String {
        let it = self
            .chars
            .by_ref()
            .skip_while(|c| char::is_whitespace(*c))
            .take_while(|c| !char::is_whitespace(*c));
        let s = String::from_iter(it);
        if s.is_empty() {
            panic!("eof")
        } else {
            s
        }
    }

    fn from_stdin() -> Self {
        let mut data = String::new();
        io::stdin().read_to_string(&mut data).expect("Input error");
        Self::from_str(&data)
    }

    fn from_str(s: &str) -> Self {
        let data = String::from(s);
        let chars = data.chars().collect::<Vec<char>>().into_iter();
        Source {
            chars: Box::new(chars),
        }
    }
}

#[allow(unused_macros)]
macro_rules! input {
    ($src:expr; $($elem:tt)*) => {
        input_inner!($src, $($elem)*)
    };
}

#[allow(unused_macros)]
macro_rules! input_inner {
    ($src:expr) => {};
    ($src:expr,) => {};
    ($src:expr, $var:ident : mut $ty:tt $($rest:tt)*) => {
        let mut $var = parse!($src, $ty);
        input_inner!($src $($rest)*)
    };
    ($src:expr, $var:ident : $ty:tt $($rest:tt)*) => {
        let $var = parse!($src, $ty);
        input_inner!($src $($rest)*)
    };
}

#[allow(unused_macros)]
macro_rules! parse {
    ($src:expr, ( $($ty:tt),* )) => {
        ( $(parse!($src,$ty)),* )
    };
    ($src:expr, char) => {
        $src.next_chr()
    };
    ($src:expr, [ $ty:tt; $len:expr ]) => {
        (0..$len).map(|_| parse!($src,$ty)).collect::<Vec<_>>()
    };
    ($src:expr, $ty:tt) => {
        parse_str!($src,$ty)
    };
}

#[allow(unused_macros)]
macro_rules! parse_str {
    ($src:expr, chars) => {
        $src.next_str().chars().collect::<Vec<char>>()
    };
    ($src:expr, $ty:ty) => {
        $src.next_str().parse::<$ty>().expect("Parse error")
    };
}

use std::cmp::min;

fn max_height(pos: usize, height: usize, restriction: &[(usize, usize, usize)]) -> usize {
    restriction.iter().fold(height, |cur, (l, r, h)| {
        if *l <= pos && pos <= *r {
            min(cur, *h)
        } else {
            cur
        }
    })
}

fn main() {
    let mut src = Source::from_stdin();
    input! { src;
             n: usize, h: usize, m: usize,
             r: [(usize,usize,usize); m]
    }

    let res: usize = (1..=n)
        .map(|pos| {
            let h = max_height(pos, h, &r);
            h * h
        })
        .sum();

    println!("{}", res)
}


use std::io;

macro_rules! parse_line {
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        io::stdin().read_line(&mut a_str).unwrap();
        let mut a_iter = a_str.split_whitespace();
        (
            $(
            a_iter.next().unwrap().parse::<$t>().unwrap(),
            )+
        )
    })
}

fn main() {
    let (mut r, mut g, mut b) = parse_line!(u64, u64, u64);
    if r > g {
        std::mem::swap(&mut r, &mut g)
    }
    if g > b {
        std::mem::swap(&mut g, &mut b)
    }
    let s = r + g + b;
    let v = r + g;
    println!("{:?}", if s / 3 < v { s / 3 } else { v });
}


use self::algebra::*;
use self::matrix::Matrix;
use self::mod_int::ModInt;
use std::cmp::*;
use std::collections::*;
use std::f64::consts::PI;
use std::io::*;
use std::str::*;
use std::string::*;

macro_rules! read {
    (($($t:tt),*)) => {
        ( $(read!($t)),* )
    };
    ([[$t:tt; $len1:expr]; $len2:expr]) => {
        (0..$len2).map(|_| read!([$t; $len1])).collect::<Vec<_>>()
    };

    ([$t:tt; $len:expr]) => {
        (0..$len).map(|_| read!($t)).collect::<Vec<_>>()
    };

    (chars) => {
        read!(String).chars().collect::<Vec<char>>()
    };

    (usize1) => {
        read!(usize) - 1
    };

    ($t:ty) => {{
        let stdin = stdin();
        let stdin = stdin.lock();
        let token: String = stdin
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect();

        token.parse::<$t>().unwrap()
    }};
}

macro_rules! input {
    (mut $name:ident: $t:tt, $($r:tt)*) => {
        let mut $name = read!($t);
        input!($($r)*);
    };

    (mut $name:ident: $t:tt) => {
        let mut $name = read!($t);
    };

    ($name:ident: $t:tt, $($r:tt)*) => {
        let $name = read!($t);
        input!($($r)*);
    };

    ($name:ident: $t:tt) => {
        let $name = read!($t);
    };
}

macro_rules! min {
    ($a:expr $(,)*) => {{
        $a
    }};
    ($a:expr, $b:expr $(,)*) => {{
        std::cmp::min($a, $b)
    }};
    ($a:expr, $($rest:expr),+ $(,)*) => {{
        std::cmp::min($a, min!($($rest),+))
    }};
}

macro_rules! chmin {
    ($base:expr, $($cmps:expr),+ $(,)*) => {{
        let cmp_min = min!($($cmps),+);
        if $base > cmp_min {
            $base = cmp_min;
            true
        } else {
            false
        }
    }};
}

macro_rules! max {
    ($a:expr $(,)*) => {{
        $a
    }};
    ($a:expr, $b:expr $(,)*) => {{
        std::cmp::max($a, $b)
    }};
    ($a:expr, $($rest:expr),+ $(,)*) => {{
        std::cmp::max($a, max!($($rest),+))
    }};
}

macro_rules! chmax {
    ($base:expr, $($cmps:expr),+ $(,)*) => {{
        let cmp_max = max!($($cmps),+);
        if $base < cmp_max {
            $base = cmp_max;
            true
        } else {
            false
        }
    }};
}

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

impl<T: PartialOrd> PartialOrd for Rev<T> {
    fn partial_cmp(&self, other: &Rev<T>) -> Option<std::cmp::Ordering> {
        other.0.partial_cmp(&self.0)
    }
}

impl<T: Ord> Ord for Rev<T> {
    fn cmp(&self, other: &Rev<T>) -> std::cmp::Ordering {
        other.0.cmp(&self.0)
    }
}

struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        IO(r, std::io::BufWriter::new(w))
    }

    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.to_string().as_bytes()).unwrap();
    }

    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let s: String = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect();

        return s.parse::<T>().ok().unwrap();
    }

    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }

    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}

fn prime_factorization(n: i64) -> HashMap<i64, i64> {
    let mut n = n;
    let mut res = HashMap::new();
    let mut i = 2;
    while i * i <= n {
        while n % i == 0 {
            n /= i;
            let count = res.entry(i).or_insert(0);
            *count += 1;
        }
        i += 1;
    }

    if n > 1 {
        res.insert(n, 1);
    }

    return res;
}

struct Combination {
    MOD: i64,
    fac: Vec<i64>,
    fac_inv: Vec<i64>,
}

impl Combination {
    pub fn new(n: i64) -> Self {
        let MOD: i64 = 1_000_000_007;
        let mut fac: Vec<i64> = vec![0; n as usize + 1];
        let mut fac_inv: Vec<i64> = vec![0; n as usize + 1];

        let get_inverse = |mut n: i64| -> i64 {
            let (mut res, mut p) = (1, MOD - 2);

            while p != 0 {
                if p & 1 == 1 {
                    res = (res * n) % MOD;
                }
                n = (n * n) % MOD;
                p >>= 1;
            }

            return res;
        };

        fac[0] = 1;

        for i in 1..n + 1 {
            fac[i as usize] = (fac[i as usize - 1] * i) % MOD;
        }

        for i in 0..n + 1 {
            fac_inv[i as usize] = get_inverse(fac[i as usize]);
        }

        Combination {
            MOD: MOD,
            fac: fac,
            fac_inv: fac_inv,
        }
    }

    fn nCr(&self, n: i64, r: i64) -> i64 {
        if n < r {
            return 0;
        }

        let a: i64 = self.fac[n as usize];
        let b: i64 = self.fac_inv[(n - r) as usize];
        let c: i64 = self.fac_inv[r as usize];
        let bc: i64 = (b * c) % self.MOD;

        return (a * bc) % self.MOD;
    }

    fn nPr(&self, n: i64, r: i64) -> i64 {
        if n < r {
            return 0;
        }

        let a: i64 = self.fac[n as usize];
        let b: i64 = self.fac_inv[(n - r) as usize];

        return (a * b) % self.MOD;
    }

    fn nHr(&self, n: i64, r: i64) -> i64 {
        if n == 0 && r == 0 {
            return 1;
        }

        return self.nCr(n + r - 1, r);
    }
}

#[derive(Copy, Clone, Eq, PartialEq)]
struct Edge {
    to: usize,
    cost: i64,
}

fn dijkstra(graph: &Vec<Vec<Edge>>, s: &usize) -> Vec<i64> {
    use std::collections::BinaryHeap;
    let mut dist = vec![1e18 as i64; graph.len()];
    let mut heap = BinaryHeap::new();
    dist[*s] = 0;
    heap.push(Rev((0, *s)));
    while let Some(Rev((cost, v))) = heap.pop() {
        if dist[v] < cost {
            continue;
        }

        for e in &graph[v] {
            if dist[e.to] <= dist[v] + e.cost {
                continue;
            }
            dist[e.to] = dist[v] + e.cost;
            heap.push(Rev((dist[e.to], e.to)));
        }
    }
    return dist;
}

struct LCA {
    par: Vec<Vec<Option<usize>>>,
    dist: Vec<i64>,
}

impl LCA {
    pub fn new(graph: &Vec<Vec<usize>>, root: usize) -> LCA {
        let V = graph.len();
        let mut K = 1;

        while (1 << K) < V {
            K += 1;
        }

        let mut par = vec![vec![None; V]; K];
        let mut dist = vec![-1; V];
        let graph = graph.to_vec();

        fn dfs(
            v: usize,
            p: Option<usize>,
            d: i64,
            graph: &Vec<Vec<usize>>,
            par: &mut Vec<Vec<Option<usize>>>,
            dist: &mut Vec<i64>,
        ) {
            par[0][v] = p;
            dist[v] = d;
            for &to in &graph[v] {
                match p {
                    Some(p) => {
                        if to != p {
                            dfs(to, Some(v), d + 1, graph, par, dist)
                        }
                    }
                    None => dfs(to, Some(v), d + 1, graph, par, dist),
                }
            }
        }

        dfs(root, None, 0, &graph, &mut par, &mut dist);

        for k in 0..K - 1 {
            for v in 0..V {
                match par[k][v] {
                    Some(x) => par[k + 1][v] = par[k][x],
                    None => (),
                }
            }
        }

        LCA {
            par: par,
            dist: dist,
        }
    }

    pub fn query(&self, u: usize, v: usize) -> usize {
        let mut u = u;
        let mut v = v;
        if self.dist[u] < self.dist[v] {
            return self.query(v, u);
        }

        let K = self.par.len();
        for k in 0..K {
            if ((self.dist[u] - self.dist[v]) >> k & 1) == 1 {
                u = self.par[k][u].unwrap();
            }
        }

        if u == v {
            return u;
        }

        for k in (0..K - 1).rev() {
            if self.par[k][u] != self.par[k][v] {
                u = self.par[k][u].unwrap();
                v = self.par[k][v].unwrap();
            }
        }

        return self.par[0][u].unwrap();
    }
}

struct Doubling {
    N: usize,
    LOG: usize,
    next: Vec<Vec<Option<usize>>>,
}

impl Doubling {
    pub fn new(vec: &Vec<usize>, lim: &usize) -> Doubling {
        let N = vec.len();
        let lim = *lim;
        let mut LOG = 1;
        while (1 << LOG) < 2 * lim {
            LOG += 1;
        }

        let mut next = vec![vec![None; N]; LOG];

        for i in 0..N {
            next[0][i] = Some(vec[i]);
        }

        for k in 0..LOG - 1 {
            for i in 0..N {
                match next[k][i] {
                    Some(x) => next[k + 1][i] = next[k][x],
                    None => (),
                }
            }
        }

        Doubling {
            N: N,
            LOG: LOG,
            next: next,
        }
    }

    pub fn query(&self, i: usize, n: usize) -> usize {
        let mut i = i;
        for k in (0..self.LOG).rev() {
            if (n >> k) & 1 == 1 {
                i = self.next[k][i].unwrap();
            }
        }
        return i;
    }
}

struct UnionFind {
    par: Vec<i32>,
}

impl UnionFind {
    pub fn new(n: usize) -> UnionFind {
        UnionFind { par: vec![-1; n] }
    }

    pub fn root(&mut self, x: usize) -> usize {
        if self.par[x] < 0 {
            return x;
        } else {
            let a = self.par[x] as usize;
            self.par[x] = self.root(a) as i32;
            return self.par[x] as usize;
        }
    }

    pub fn same(&mut self, x: usize, y: usize) -> bool {
        self.root(x) == self.root(y)
    }

    pub fn merge(&mut self, x: usize, y: usize) -> bool {
        let mut x = self.root(x);
        let mut y = self.root(y);
        if x == y {
            return false;
        } else {
            if self.par[x] > self.par[y] {
                std::mem::swap(&mut x, &mut y);
            }
            self.par[x] += self.par[y];
            self.par[y] = x as i32;
            return true;
        }
    }

    pub fn size(&mut self, x: usize) -> i64 {
        let a = self.root(x);
        return -self.par[a] as i64;
    }
}

pub mod algebra {
    pub trait Monoid {
        fn id() -> Self;
        fn op(&self, rhs: &Self) -> Self;
    }

    #[derive(Clone, Debug)]
    pub struct Min(i64);

    #[derive(Clone, Debug)]
    pub struct RangeUpdate(i64);

    #[derive(Clone, Debug)]
    pub struct RangeAdd(i64);

    #[derive(Clone, Debug)]
    pub struct Sum(i64);

    impl Monoid for Sum {
        fn id() -> Self {
            Sum(0)
        }

        fn op(&self, rhs: &Self) -> Self {
            Sum(self.0 + rhs.0)
        }
    }

    impl Monoid for Min {
        fn id() -> Self {
            Min(std::i32::MAX as i64)
        }

        fn op(&self, rhs: &Self) -> Self {
            Min(std::cmp::min(self.0, (*rhs).0))
        }
    }

    pub trait Operator {
        type T;
        fn id() -> Self;
        fn op(&self, rhs: &Self) -> Self;
        fn act(&self, tar: &Self::T, x: usize) -> Self::T;
    }

    impl Operator for RangeUpdate {
        type T = Min;
        fn id() -> Self {
            RangeUpdate(0)
        }

        fn op(&self, rhs: &Self) -> Self {
            (*rhs).clone()
        }

        fn act(&self, tar: &Self::T, x: usize) -> Self::T {
            Min(self.0)
        }
    }

    impl Operator for RangeAdd {
        type T = Sum;
        fn id() -> Self {
            RangeAdd(0)
        }

        fn op(&self, rhs: &Self) -> Self {
            RangeAdd(self.0 + rhs.0)
        }

        // Sum(tar.0 + self.0 * x as i64)
        fn act(&self, tar: &Self::T, x: usize) -> Self::T {
            Sum(tar.0 + self.0 * x as i64)
        }
    }

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

    impl Zero for usize {
        fn zero() -> Self {
            0usize
        }
    }

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

    impl One for usize {
        fn one() -> Self {
            1usize
        }
    }
}

struct LazySegTree<M: Monoid, O: Operator<T = M>> {
    dat: Vec<M>,
    lzy: Vec<O>,
    need_update: Vec<bool>,
    size: usize,
}

impl<M: Monoid + Clone, O: Operator<T = M> + Clone> LazySegTree<M, O> {
    pub fn new(vec: Vec<M>) -> LazySegTree<M, O> {
        let n = vec.len();
        let mut sz = 1;
        while sz < n {
            sz <<= 1;
        }
        let mut dat = vec![M::id(); sz << 1];
        for i in 0..n {
            dat[i + sz] = vec[i].clone();
        }
        for k in (1..sz).rev() {
            dat[k] = dat[k << 1].op(&dat[(k << 1) + 1]);
        }

        return LazySegTree {
            dat: dat,
            lzy: vec![O::id(); sz << 1],
            need_update: vec![false; sz << 1],
            size: sz,
        };
    }

    pub fn eval(&mut self, l: usize, r: usize, k: usize) {
        if !self.need_update[k] {
            return;
        }
        self.dat[k] = self.lzy[k].act(&self.dat[k], r - l);
        if (k << 1) < self.dat.len() {
            self.lzy[k << 1] = self.lzy[k << 1].op(&self.lzy[k]);
            self.lzy[(k << 1) + 1] = self.lzy[(k << 1) + 1].op(&self.lzy[k]);
            self.need_update[k << 1] = true;
            self.need_update[(k << 1) + 1] = true;
        }
        self.lzy[k] = O::id();
        self.need_update[k] = false;
    }

    pub fn update(&mut self, a: usize, b: usize, x: O) {
        let sz = self.size;
        self._update(a, b, &x, 0, sz, 1);
    }

    pub fn _update(&mut self, a: usize, b: usize, x: &O, l: usize, r: usize, k: usize) {
        self.eval(l, r, k);
        if b <= l || r <= a {
            return;
        } else if a <= l && r <= b {
            self.lzy[k] = self.lzy[k].op(x);
            self.need_update[k] = true;
            self.eval(l, r, k);
        } else {
            let mid = (l + r) >> 1;
            self._update(a, b, x, l, mid, k << 1);
            self._update(a, b, x, mid, r, (k << 1) + 1);
            self.dat[k] = self.dat[k << 1].op(&self.dat[(k << 1) + 1]);
        }
    }

    pub fn query(&mut self, a: usize, b: usize) -> M {
        let sz = self.size;
        return self._query(a, b, 0, sz, 1);
    }

    pub fn _query(&mut self, a: usize, b: usize, l: usize, r: usize, k: usize) -> M {
        self.eval(l, r, k);
        if b <= l || r <= a {
            return M::id();
        } else if a <= l && r <= b {
            return self.dat[k].clone();
        } else {
            let mid = (l + r) >> 1;
            let vl = self._query(a, b, l, mid, k << 1);
            let vr = self._query(a, b, mid, r, (k << 1) + 1);
            return vl.op(&vr);
        }
    }
}

struct SegTree<M: Monoid> {
    dat: Vec<M>,
    size: usize,
}

impl<M: Monoid + Clone> SegTree<M> {
    pub fn new(n: usize) -> SegTree<M> {
        let mut sz = 1;
        while sz < n {
            sz <<= 1;
        }

        SegTree::<M> {
            dat: vec![M::id(); sz * 2],
            size: sz,
        }
    }

    pub fn update(&mut self, k: usize, val: M) {
        let mut k = k + self.size;
        self.dat[k] = val;
        while k > 0 {
            k = k >> 1;
            self.dat[k] = self.dat[k << 1].op(&self.dat[(k << 1) + 1]);
        }
    }

    pub fn query(&self, a: usize, b: usize) -> M {
        let mut lx = M::id();
        let mut rx = M::id();
        let mut l = a + self.size;
        let mut r = b + self.size;
        while l < r {
            if (l & 1) == 1 {
                lx = lx.op(&self.dat[l]);
                l += 1;
            }

            if (r & 1) == 1 {
                r -= 1;
                rx = self.dat[r].op(&rx);
            }

            l >>= 1;
            r >>= 1;
        }

        return lx.op(&rx);
    }
}

fn decode(v: Vec<char>) -> Vec<(char, usize)> {
    let mut res = Vec::new();
    let mut now = v[0];
    let mut cnt = 1;

    for i in 1..v.len() {
        if v[i] == now {
            cnt += 1;
        } else {
            res.push((now, cnt));
            cnt = 1;
            now = v[i];
        }
    }
    res.push((now, cnt));

    return res;
}

pub mod mod_int {
    use super::algebra::{One, Zero};
    use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};

    type Num = usize;

    const MOD: usize = 1e9 as usize + 7;

    #[derive(Clone, Copy)]
    pub struct ModInt<T: Copy + Clone>(pub T);

    impl Add<ModInt<Num>> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn add(self, rhs: ModInt<Num>) -> ModInt<Num> {
            self + rhs.0
        }
    }

    impl Add<Num> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn add(self, mut rhs: Num) -> ModInt<Num> {
            if rhs >= MOD {
                rhs %= MOD;
            }
            let mut t = rhs + self.0;
            if t >= MOD {
                t = t - MOD;
            }
            ModInt(t)
        }
    }

    impl Sub<Num> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn sub(self, rhs: Num) -> ModInt<Num> {
            let rhs = if rhs >= MOD { rhs % MOD } else { rhs };
            let value = if self.0 < rhs { self.0 + MOD } else { self.0 };
            ModInt(value - rhs)
        }
    }

    impl Sub<ModInt<Num>> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn sub(self, rhs: ModInt<Num>) -> ModInt<Num> {
            self - rhs.0
        }
    }

    impl AddAssign<Num> for ModInt<Num> {
        fn add_assign(&mut self, other: Num) {
            *self = *self + other;
        }
    }

    impl AddAssign<ModInt<Num>> for ModInt<Num> {
        fn add_assign(&mut self, other: ModInt<Num>) {
            *self = *self + other;
        }
    }

    impl SubAssign<Num> for ModInt<Num> {
        fn sub_assign(&mut self, other: Num) {
            *self = *self - other;
        }
    }

    impl SubAssign<ModInt<Num>> for ModInt<Num> {
        fn sub_assign(&mut self, other: ModInt<Num>) {
            *self = *self - other;
        }
    }

    impl Div<Num> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn div(self, mut rhs: Num) -> ModInt<Num> {
            if rhs >= MOD {
                rhs %= MOD;
            }
            self * ModInt(rhs).pow(MOD - 2)
        }
    }

    impl Div<ModInt<Num>> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn div(self, rhs: ModInt<Num>) -> ModInt<Num> {
            self / rhs.0
        }
    }

    impl DivAssign<Num> for ModInt<Num> {
        fn div_assign(&mut self, rhs: Num) {
            *self = *self / rhs
        }
    }

    impl DivAssign<ModInt<Num>> for ModInt<Num> {
        fn div_assign(&mut self, rhs: ModInt<Num>) {
            *self = *self / rhs
        }
    }

    impl Mul<ModInt<Num>> for ModInt<Num> {
        type Output = ModInt<Num>;

        fn mul(self, rhs: ModInt<Num>) -> ModInt<Num> {
            self * rhs.0
        }
    }

    impl Mul<Num> for ModInt<Num> {
        type Output = ModInt<Num>;

        fn mul(self, mut rhs: Num) -> ModInt<Num> {
            if rhs >= MOD {
                rhs %= MOD;
            }
            let t = (self.0 * rhs) % MOD;
            ModInt(t)
        }
    }

    impl MulAssign<Num> for ModInt<Num> {
        fn mul_assign(&mut self, rhs: Num) {
            *self = *self * rhs;
        }
    }

    impl MulAssign<ModInt<Num>> for ModInt<Num> {
        fn mul_assign(&mut self, rhs: ModInt<Num>) {
            *self = *self * rhs;
        }
    }

    impl ModInt<Num> {
        pub fn pow(self, e: Num) -> ModInt<Num> {
            let mut result = ModInt(1);
            let mut cur = self;
            let mut e = e;
            while e > 0 {
                if e & 1 == 1 {
                    result *= cur;
                }
                e >>= 1;
                cur *= cur;
            }
            result
        }
    }

    impl Zero for ModInt<Num> {
        fn zero() -> Self {
            ModInt(0)
        }
    }

    impl One for ModInt<Num> {
        fn one() -> Self {
            ModInt(1)
        }
    }
}

struct Eratosthenes {
    n: usize,
    prime: Vec<bool>,
}

impl Eratosthenes {
    pub fn new(n: usize) -> Eratosthenes {
        let mut prime = vec![true; n + 1];
        prime[0] = false;
        prime[1] = false;
        let mut i = 2;
        while i * i <= n {
            if prime[i] {
                let mut p = i * 2;
                while p <= n {
                    prime[p] = false;
                    p += i;
                }
            }
            i += 1;
        }

        Eratosthenes { n: n, prime: prime }
    }
}

pub mod matrix {
    use super::algebra::{One, Zero};
    use std::ops::{Add, Mul};

    #[derive(Clone)]
    pub struct Matrix<T: Add + Mul + Clone + Copy + One + Zero>(pub Vec<Vec<T>>);

    impl<T: Add<Output = T> + Mul<Output = T> + Clone + Copy + One + Zero> Matrix<T> {
        pub fn mul(&mut self, rhs: &Matrix<T>) -> Matrix<T> {
            let n = self.0.len();
            let m = rhs.0[0].len();
            let p = self.0[0].len();
            let mut res = vec![vec![T::zero(); m]; n];
            for i in 0..n {
                for j in 0..m {
                    for k in 0..p {
                        res[i][j] = res[i][j] + self.0[i][k] * rhs.0[k][j]
                    }
                }
            }

            return Matrix(res);
        }

        // pub fn update(&mut self) -> Vec<Vec<T>> {
        //     let m = self.mat.len();
        //     let mut res = vec![vec![T::zero(); m]; m];
        //     for i in 0..m {
        //         for j in 0..m {
        //             for k in 0..m {
        //                 res[i][j] = res[i][j] + self.mat[i][k] * self.mat[k][j];
        //             }
        //         }
        //     }
        //     return res;
        // }

        pub fn pow(&mut self, k: usize) -> Matrix<T> {
            let n = self.0.len();
            let mut k = k;
            let mut res = Matrix(vec![vec![T::zero(); n]; n]);
            let mut b = (*self).clone();
            for i in 0..n {
                res.0[i][i] = T::one();
            }

            while k > 0 {
                if k & 1 == 1 {
                    res = b.mul(&res);
                }
                b = b.mul(&b.clone());
                k >>= 1;
            }

            return res;
        }
    }
}

#[derive(Clone, Copy)]
struct Alpha(i64);

impl Monoid for Alpha {
    fn id() -> Self {
        Alpha(0i64)
    }

    fn op(&self, rhs: &Self) -> Self {
        Alpha(self.0 | rhs.0)
    }
}

pub trait BinarySearch<T> {
    fn lower_bound(&self, x: T) -> usize;
    fn upper_bound(&self, x: T) -> usize;
}

impl<T: Ord> BinarySearch<T> for [T] {
    fn lower_bound(&self, x: T) -> usize {
        let mut ok = self.len() as i32;
        let mut ng = -1i32;
        while ok - ng > 1 {
            let mid = ((ok + ng) / 2);
            match self[mid as usize].cmp(&x) {
                Ordering::Greater | Ordering::Equal => {
                    ok = mid;
                }
                Ordering::Less => {
                    ng = mid;
                }
            }
        }
        return ok as usize;
    }

    fn upper_bound(&self, x: T) -> usize {
        let mut ok = self.len() as i32;
        let mut ng = -1i32;
        while ok - ng > 1 {
            let mid = ((ok + ng) / 2);
            match self[mid as usize].cmp(&x) {
                Ordering::Greater => {
                    ok = mid;
                }
                Ordering::Equal | Ordering::Less => {
                    ng = mid;
                }
            }
        }
        return ok as usize;
    }
}

fn solve() {
    input! {
        n: usize,
        k: usize,
        d: usize
    }

    let mut dp = vec![vec![ModInt(0); 2]; 110];
    dp[0][0] += 1;

    for i in 1..=n {
        for j in 1..=k {
            if i < j {
                continue;
            }
            if j < d {
                dp[i][0] = dp[i][0] + dp[i - j][0];
                dp[i][1] = dp[i][1] + dp[i - j][1];
            } else {
                dp[i][1] = dp[i][1] + dp[i - j][0];
                dp[i][1] = dp[i][1] + dp[i - j][1];
            }
        }
    }
    println!("{}", dp[n][1].0);
}

fn main() {
    // input! {
    //     t: usize
    // }

    let mut t = 1;
    for _ in 0..t {
        solve();
    }
}


use std::io::{self, Read};

fn main() -> io::Result<()> {
    let m: i64 = 1000000007;
    let mut input = String::new();
    io::stdin().read_to_string(&mut input)?;
    let mut ws = input.split_whitespace();
    let n: usize = ws.next().unwrap().parse().unwrap();
    let k: usize = ws.next().unwrap().parse().unwrap();
    let d: usize = ws.next().unwrap().parse().unwrap();
    let mut v0 = vec![1];
    for i in 1..n + 1 {
        let mut s: i64 = 0;
        for j in 1..k + 1 {
            if i >= j {
                s += v0[i - j];
            }
        }
        v0.push(s % m);
    }
    let mut v1 = vec![0];
    for i in 1..n + 1 {
        let mut s: i64 = 0;
        for j in 1..d {
            if i >= j {
                s += v1[i - j];
            }
        }
        for j in d..k + 1 {
            if i >= j {
                s += v0[i - j];
            }
        }
        v1.push(s % m);
    }
    println!("{}", v1[n]);
    Ok(())
}


struct Scan {
    buffer: std::collections::VecDeque<String>,
}

impl Scan {
    fn new() -> Scan {
        Scan {
            buffer: std::collections::VecDeque::new(),
        }
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop_front() {
                break token.parse::<T>().ok().unwrap();
            }
            let mut line = String::new();
            std::io::stdin().read_line(&mut line).expect("Fail to read");
            self.buffer = line.split_whitespace().map(String::from).collect();
        }
    }
}

fn _main() {
    let mut scan = Scan::new();
    let n: usize = scan.next();
    let k: usize = scan.next();
    let d: usize = scan.next();
    let mut dp = [[0usize; 2]; 128];
    dp[0][0] = 1;
    for i in 1..=n {
        for j in 1..=k {
            if i < j {
                continue;
            }
            if j < d {
                dp[i][0] = (dp[i][0] + dp[i - j][0]) % 1000000007;
                dp[i][1] = (dp[i][1] + dp[i - j][1]) % 1000000007;
            } else {
                dp[i][1] = (dp[i][1] + dp[i - j][0]) % 1000000007;
                dp[i][1] = (dp[i][1] + dp[i - j][1]) % 1000000007;
            }
        }
    }
    println!("{}", dp[n][1]);
}

fn main() {
    std::thread::Builder::new()
        .stack_size(1 << 23)
        .spawn(_main)
        .unwrap()
        .join()
        .unwrap();
}


use std::io::stdin;
fn main() {
    let evolutions = ["vaporeon", "jolteon", "flareon", "espeon", "umbreon", "leafeon", "glaceon", "sylveon"];

    let mut entry = String::new();
    stdin().read_line(&mut entry).unwrap();
    let len:usize = entry.trim().parse().unwrap();
    entry.clear();
    stdin().read_line(&mut entry).unwrap();
    let name = entry.trim();
    let mut coord:Vec<(char, usize)> = vec!();
    for (i, c) in name.chars().enumerate(){
        if c != '.' {
            coord.push((c, i));
        }
    }
    for ev in evolutions.iter() {
        if len == ev.len(){
            let mut is_it = true;
            let chars :Vec<char> = ev.chars().collect();
            for i in &coord{
                if i.0 != chars[i.1] {
                    is_it = false;
                    break;
                }
            }
            if is_it {
                println!("{}", ev);
                break;
            }
        }
    }
}


use std::io::{self, BufWriter, Write};
use std::str::{self, SplitAsciiWhitespace};

// I have no idea what I'm doing

/// Copied from https://github.com/EbTech/rust-algorithms/blob/master/src/scanner.rs
/// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts
/// **REQUIRES** Rust 1.34 or higher
pub struct UnsafeScanner<R> {
    reader: R,
    buf_str: Vec<u8>,
    buf_iter: SplitAsciiWhitespace<'static>,
}

impl<R: io::BufRead> UnsafeScanner<R> {
    pub fn new(reader: R) -> Self {
        Self {
            reader,
            buf_str: vec![],
            buf_iter: "".split_ascii_whitespace(),
        }
    }

    /// This function should be marked unsafe, but noone has time for that in a
    /// programming contest. Use at your own risk!
    pub fn token<T: str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buf_iter.next() {
                return token.parse().ok().expect("Failed parse");
            }
            self.buf_str.clear();
            self.reader
                .read_until(b'\n', &mut self.buf_str)
                .expect("Failed read");
            self.buf_iter = unsafe {
                let slice = str::from_utf8_unchecked(&self.buf_str);
                std::mem::transmute(slice.split_ascii_whitespace())
            }
        }
    }

    pub fn pair<T: str::FromStr>(&mut self) -> (T, T) {
        (self.token(), self.token())
    }
}

fn is_match(pat: &str, text: &str) -> bool {
    pat.len() == text.len() &&
    pat.chars().zip(text.chars())
        .all(|(p, t)| p == '.' || t == p)
}

fn main() -> Result<(), io::Error> {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = UnsafeScanner::new(stdin.lock());
    let mut out = BufWriter::new(stdout.lock());

    let pool: Vec<_> = "vaporeon jolteon flareon espeon umbreon leafeon glaceon and sylveon"
        .split_ascii_whitespace()
        .collect();

    let _n: usize = scan.token();
    let s: String = scan.token();

    writeln!(out, "{}", pool.into_iter().filter(|t| is_match(&s, t)).next().unwrap())?;

    Ok(())
}


use std::io::stdin;

use std::collections::HashMap;

fn main() {
    let k = {
        let mut input = String::new();
        stdin().read_line(&mut input).unwrap();
        let mut it = input.split_whitespace().map(|k| k.parse::<usize>().unwrap());
        it.next();
        it.next().unwrap()
    };

    let mut hm: HashMap<u8, usize> = HashMap::new();

    let mut s = String::new();
    stdin().read_line(&mut s).unwrap();
    let s = s.trim();
    for c in s.as_bytes() {
        let cnt = hm.entry(*c).or_insert(0);
        *cnt += 1;
    }

    let l = hm.values().max().unwrap();
    if k < *l {
        println!("NO");
    } else {
        println!("YES");
    }
}


use std::error::Error;
use std::io;
use std::collections::HashMap;

fn main() {
    if let Err(e) = run() {
        println!("{}", e);
    }
}

fn run() -> Result<(), Box<Error>> {
    let mut s = String::new();
    io::stdin().read_line(&mut s)?;
    let s: Vec<&str> = s.trim().split(" ").collect();
    let _: i32 = s[0].parse()?;
    let k: i32 = s[1].parse()?;
    let mut s = String::new();
    io::stdin().read_line(&mut s)?;
    let mut m = HashMap::new();
    for b in s.trim().as_bytes() {
        match m.get(b).cloned() {
            Some(x) => m.insert(b, x + 1),
            _ => m.insert(b, 1)
        };
    }
    for (_, x) in &m {
        if *x > k {
            println!("NO");
            return Ok(())
        }
    }
    println!("YES");
    Ok(())
}


// https://codeforces.com/contest/1118/problem/D2
//
#![allow(unused_imports)]
use std::io::*;
use std::io::Write;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };

    ($iter:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, [ next / $t:tt ]) => {
        {
            let len = read_value!($iter, usize);
            (0..len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
        }
    };

    ($iter:expr, switch) => {
        {
            let ty = read_value!($iter, i32);
            if ty == 1 {
                vec![ty, read_value!($iter, i32), read_value!($iter, i32)]
            } else if ty == 2 {
                vec![ty, read_value!($iter, i32)]
            } else {
                vec![ty, read_value!($iter, i32)]
            }
        }
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_macros)]
macro_rules! dvec {
    ($t:expr ; $len:expr) => {
        vec![$t; $len]
    };

    ($t:expr ; $len:expr, $($rest:expr),*) => {
        vec![dvec!($t; $($rest),*); $len]
    };
}

#[allow(unused_macros)]
macro_rules! ifv {
    ($t:expr, $a:expr, $b: expr) => {
        if $t { $a } else { $b }
    }
}

#[allow(unused_macros)]
macro_rules! fill {
    ($t:expr, $v:expr) => {
        for i in 0..$t.len() {
            $t[i] = $v;
        }
    };
}

#[allow(unused_macros)]
macro_rules! join {
    ($t:expr, $glue:expr) => {
        $t.into_iter().map(|w| w.to_string()).collect::<Vec<_>>().join($glue)
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

fn isok(days: usize, a: &Vec<i64>) -> i64 {
    let n = a.len();
    let mut total = 0;
    let mut cup = 0;
    let mut fr = 0;
    while fr < n {
        for i in 0..days {
            if fr == n {
                break;
            }
            total += max(0, a[fr]-cup);
            fr += 1;
        }
        cup += 1;
    }
    total
}

fn main() {
    input! {
        n: usize, m: i64,
        mut a: [i64; n]
    };
    a.sort();
    a.reverse();

    let mut sum = 0;
    for i in 0..n {
        sum += a[i];
    }
    if sum < m {
        println!("-1");
        return;
    }

    let mut ng = 0;
    let mut ok = n;
    while ok - ng > 1 {
        let med = (ok + ng) / 2;
        if isok(med, &a) >= m {
            ok = med;
        } else {
            ng = med;
        }
    }
    println!("{}", ok);
}


//https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 より
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

//

fn run() {
    input! {
        n: usize,
        m: i64,
        a: [i64; n],
    }
    if a.iter().fold(0, |s, a| s + *a) < m {
        println!("-1");
        return;
    }
    let mut a = a;
    a.sort();
    a.reverse();
    let mut ok = n;
    let mut ng = 0;
    while ok - ng > 1 {
        let mid = (ok + ng) / 2;
        let mut sum = 0;
        let mut sub = 0;
        for a in a.chunks(mid) {
            for a in a.iter() {
                sum += std::cmp::max(0, *a - sub);
            }
            sub += 1;
        }
        if sum >= m {
            ok = mid;
        } else {
            ng = mid;
        }
    }
    println!("{}", ok);
}

fn main() {
    run();
}


use std::io::stdin;
use std::cmp::*;

fn main() {
    let (n, k) = {
        let mut input = String::new();
        stdin().read_line(&mut input).unwrap();
        let mut it = input.split_whitespace().map(|k| k.parse::<usize>().unwrap());
        (it.next().unwrap(), it.next().unwrap())
    };

    let mut input = String::new();
    stdin().read_line(&mut input).unwrap();
    let it = input.split_whitespace().map(|k| k.parse::<usize>().unwrap());

    let mut ac = 0;
    let mut bc = 0;

    for (i, a) in it.enumerate() {
        ac += a;
        bc += min(ac, 8);
        ac -= min(ac, 8);
        if k <= bc {
            println!("{}", i + 1);
            std::process::exit(0);
        }
    }

    println!("-1");
}


//https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 より
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

// ここまで

fn run() {
    input! {
        n: usize,
        m: usize,
    }
    let ans = if n == m {
        0
    } else if m <= 1 {
        1
    } else if m <= n / 2 {
        m
    } else {
        n - m
    };
    println!("{}", ans);
}

fn main() {
    run();
}


use std::io;

fn read_line() -> Vec<i64> {
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    return buf.trim().split(" ").map(|x| { x.parse::<i64>().unwrap() }).collect();
}

fn main() {
    let line = read_line();
    let (n, x) = (line[0], line[1]);
    let arr = read_line();
    let count_lt = arr.iter().filter(|e| { **e < x }).count() as i64;
    let has_eq = arr.iter().filter(|e| { **e == x }).count() == 1;
    let result = (x - count_lt) + (if has_eq { 1 } else { 0 });
    println!("{}", result);
}


use std::io;
use std::str::FromStr;

use std::io::prelude::*;
use std::io::BufReader;
use std::cmp::{max, min};

fn get_line() -> String {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input
}

fn get_vec<T>(s: String) -> Vec<T>
    where T: FromStr,
          <T as FromStr>::Err: std::fmt::Debug,
{
    s.split_whitespace().map(|k| k.parse().unwrap()).collect()
}

fn main() {
    let (n, x): (usize, usize) = {
        let input = get_line();
        let mut it = input.split_whitespace().map(|k| k.parse().unwrap());
        (
            it.next().unwrap(),
            it.next().unwrap(),
            )
    };

    let v: Vec<usize> = get_line().split_whitespace().map(|k| k.parse().unwrap())
        .filter(|&k: &usize| k <= x).collect();

    let ans = v.into_iter().fold(x, |acc, i| {
        if i == x {
            acc + 1
        } else {
            acc - 1
        }
    });

    println!("{}", ans);
}


use std::str::FromStr;
use std::fmt;
use std::io;

const MODULO: u64 = 1000000007;

fn main() {
    let n: u64 = read();
    let mut k = 0;

    for i in 2..(n+1) {
        if i%2 == 0 {
            k = (3 * (k + 1)) % MODULO;
        } else {
            k = (3 * (k - 1)) % MODULO;
        }
    }

    println!("{}", k);
}

fn read_line() -> String {
    let mut pre_n = String::new();
    io::stdin().read_line(&mut pre_n).unwrap();
    pre_n
}

fn read<T: FromStr>() -> T
    where <T as FromStr>::Err: fmt::Debug
{
    read_line().trim().parse().unwrap()
}


struct Scan {
    buffer: std::collections::VecDeque<String>,
}

impl Scan {
    fn new() -> Scan {
        Scan {
            buffer: std::collections::VecDeque::new(),
        }
    }

    fn next_line(&self) -> String {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).expect("Fail to read");
        line
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop_front() {
                break token.parse::<T>().ok().unwrap();
            }
            let line = self.next_line();
            self.buffer = line.split_whitespace().map(String::from).collect();
        }
    }
}

fn mult(m1: &[[u64; 4]; 4], m2: &[[u64; 4]; 4]) -> [[u64; 4]; 4] {
    let mut result = [[0u64; 4]; 4];
    for i in 0..4 {
        for j in 0..4 {
            let mut sum = 0u64;
            for k in 0..4 {
                sum = (sum + m1[i][k] * m2[k][j]) % 1000000007;
            }
            result[i][j] = sum;
        }
    }
    result
}

fn exp(m: &[[u64; 4]; 4], mut e: u64) -> [[u64; 4]; 4] {
    let mut m2 = m.clone();
    let mut result = [[0u64; 4]; 4];
    result[0][0] = 1;
    result[1][1] = 1;
    result[2][2] = 1;
    result[3][3] = 1;
    while e > 0 {
        if e & 1 == 1 {
            result = mult(&result, &m2);
        }
        e >>= 1;
        m2 = mult(&m2, &m2);
    }
    result
}

fn _main() {
    let mut scan = Scan::new();
    let n: u64 = scan.next();
    let mat: [[u64; 4]; 4] = [[0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1], [1, 1, 1, 0]];
    let result = exp(&mat, n);
    println!("{}", result[0][0]);
}

fn main() {
    std::thread::Builder::new()
        .stack_size(1 << 23)
        .spawn(_main)
        .unwrap()
        .join()
        .unwrap();
}


use std::io::Read;

fn input(read_file: bool) -> String {
    if read_file {
        let mut file = std::fs::File::open("sample.txt").unwrap();
        let mut buf = String::new();
        file.read_to_string(&mut buf).unwrap();
        buf
    } else {
        let mut buf = String::new();
        std::io::stdin().read_to_string(&mut buf).unwrap();
        buf.trim_end().to_owned()
    }
}

fn solve(ws: &mut std::str::SplitWhitespace) {
    let n: usize = ws.next().unwrap().parse().unwrap();
    const MOD: i64 = 1_000_000_007;

    let mut nd = 1;
    let mut na = 0;

    for i in 0..n {
        let d = na * 3 % MOD;
        let a = (nd + na * 2) % MOD;
        nd = d;
        na = a;
    }

    println!("{}", nd);
}

fn main() {
    const READ_FROM_FILE: bool = false;

    let s = input(READ_FROM_FILE);
    let mut ws = s.split_whitespace();

    // let t = ws.next().unwrap().parse().unwrap();
    // for _ in 0..t {}
    solve(&mut ws);
}


macro_rules! parse_line {
    ($t: ty) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let a_str = a_str.trim();
        a_str.parse::<$t>().expect("parse error")
    });
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let mut a_iter = a_str.split_whitespace();
        (
            $(
            a_iter.next().unwrap().parse::<$t>().expect("parse error"),
            )+
        )
    })
}

macro_rules! parse_line_to_vec {
    ($t: ty) => {{
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        (a_str
            .split_whitespace()
            .map(|x| x.parse::<$t>().unwrap())
            .collect::<Vec<$t>>())
    }};
}

fn solve() {
    let (a, b) = parse_line!(u64, u64);
    let mut pos = 0;
    let mut count = 0;
    while pos != a * b {
        let closest_a = (pos / a + 1) * a;
        let closest_b = (pos / b + 1) * b;
        if closest_a < closest_b {
            count += closest_a - pos;
            pos = closest_a;
        }else if closest_b < closest_a {
            pos = closest_b;
        }else if closest_a == closest_b {
            if a > b {
                count += closest_a - pos;
            }
            pos = closest_a;
        }
    }
    if count * 2 == a * b {
        println!("Equal");
    }else if count * 2 > a * b {
        println!("Dasha");
    }else{
        println!("Masha");
    }
}

fn main() {
    let tests = 1; // parse_line!(usize);
    for _ in 0..tests {
        solve();
    }
}


use std::io;
use std::str::FromStr;

use std::io::prelude::*;
use std::io::BufReader;
use std::cmp::{max, min};

fn get_line() -> String {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input
}

fn get_vec<T>() -> Vec<T>
where T: FromStr,
      <T as FromStr>::Err: std::fmt::Debug,
{
    get_line().split_whitespace().map(|k| k.parse().unwrap()).collect()
}

const N: i64 = 998_244_353;

fn extended_euclid(a: i64, b: i64) -> (i64, i64, i64) {
    if b == 0 {
        (a, 1, 0)
    } else {
        let (d0, x0, y0) = extended_euclid(b, a % b);
        (d0, y0, x0 - a / b * y0)
    }
}

fn main() {
    let s = get_line().trim().to_string();

    let names = vec![
        "Danil",
        "Olya",
        "Slava",
        "Ann",
        "Nikita",
    ];

    let count = names.into_iter()
        .map(|name| s.split(name).count() - 1)
        .sum::<usize>();

    if count == 1 {
        println!("YES");
    } else {
        println!("NO");
    }
}


//spnauti-rusT {{{
use std::io::*; use std::str::{self,*}; use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::{self,*};
#[allow(unused_imports)] use std::iter::{self,*};
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_imports)] use std::cell::*;
#[allow(unused_macros)] macro_rules! m {
	($c:tt,$x:expr,$y:expr) => {{
		let b=$y; let a=&mut$x; if b$c*a {*a=b; true} else {false}
	}};
}
#[allow(unused_macros)] macro_rules! l {
	($($v:ident),+ =$e:expr) => {$(let$v=$e;)+};
	($($v:ident),+:$t:ty=$e:expr) => {$(let$v:$t=$e;)+};
	(mut $($v:ident),+ =$e:expr) => {$(let mut$v=$e;)+};
	(mut $($v:ident),+:$t:ty=$e:expr) => {$(let mut$v:$t=$e;)+};
}
#[allow(unused_macros)] macro_rules! vec_dim {
	([$d:expr]$($s:tt)+) => {vec![vec_dim!($($s)+);$d]}; (=$e:expr) => {$e};
}
#[allow(unused_macros)] macro_rules! rep { {[$c:expr]$($s:tt)+} => {for _ in 0..$c {$($s)+}} }
#[allow(dead_code)] fn reader() -> WordReaderC { WordReaderC::new() }
#[allow(dead_code)] fn writer() -> BufWriter<Stdout> { BufWriter::new(stdout()) }
struct WordReaderC {buf: Vec<u8>, pos: usize, q: std::io::StdinLock<'static>}//'
#[allow(dead_code)] impl WordReaderC {
	fn new() -> Self {
		let r = unsafe {&*Box::into_raw(Box::new(stdin()))};
		Self { q: r.lock(), buf: Vec::new(), pos: 0 }
	}
	fn next_line(&mut self) -> bool {
		self.buf.clear(); self.pos = 0;
		self.q.read_until(b'\n', &mut self.buf).unwrap_or(0) > 0
	}
	fn is_ws(c: u8) -> bool {
		c == b' ' || c == b'\r' || c == b'\n' || c == b'\t'
	}
	fn byte(&mut self) -> Option<u8> {
		if self.pos == self.buf.len() { if !self.next_line() { return None; } }
		self.pos += 1; Some(self.buf[self.pos - 1])
	}
	fn vb(&mut self) -> Vec<u8> {
		let mut s = Vec::with_capacity(8);
		let mut f = false;
		loop {
			if let Some(c) = self.byte() {
				if !Self::is_ws(c) {
					s.push(c);
					f = true;
				} else if f { break; }
			} else { break; }
		}
		s
	}
	fn s(&mut self) -> String { String::from_utf8(self.vb()).expect("invalid utf8") }
	fn i(&mut self) ->    i32 { self.p() }
	fn l(&mut self) ->    i64 { self.p() }
	fn u(&mut self) ->  usize { self.p() }
	fn f(&mut self) ->    f64 { self.p() }
	fn vi(&mut self, n: usize) -> Vec<i32> { self.vp(n) }
	fn vl(&mut self, n: usize) -> Vec<i64> { self.vp(n) }
	fn vu(&mut self, n: usize) -> Vec<usize> { self.vp(n) }
	fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> { self.ip(n).into_iter() }
	fn iu(&mut self, n: usize) -> impl Iterator<Item=usize> { self.ip(n).into_iter() }
	fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
		let w = self.vb(); str::from_utf8(w.as_ref()).unwrap().parse::<T>().unwrap()
	}
	fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
		(0..n).map(|_|self.p()).collect()
	}
	fn ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
		self.vp(n).into_iter()
	}
}
//------------------- End rusT }}}

// Field (mod prime) {{{
mod field {
	use std::ops::*;
	const P5: i32 = 1_000_000_007;
	const P6: i64 = P5 as i64;
	#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Default)] pub struct Field(i32);
	#[allow(dead_code)] impl Field {
		pub fn new<T: Into<i64>>(a: T) -> Self { Self(Self::cv(a)) }
		pub unsafe fn new_unchecked(a: i32) -> Self { Self(a) }
		fn hi(mut a: i32) -> i32 { if a >= P5 { a -= P5; } a }
		fn lo(mut a: i32) -> i32 { if a < 0 { a += P5; } a }
		fn cv<T: Into<i64>>(a: T) -> i32 { Self::lo((a.into() % P6) as i32) }
		pub fn inv(self) -> Self { self.pow(P5-2) }
		pub fn pow<T: Into<i64>>(self, b: T) -> Self {
			let b = b.into(); if b == 0 { Self(1) } else {
				let mut res = self.pow(b/2); res *= res; if b % 2 == 1 {res *= self;} res
			}
		}
	}
	impl Add for Field { type Output = Self; fn add(self, a: Self) -> Self::Output { Self(Self::hi(self.0 + a.0)) }}
	impl Sub for Field { type Output = Self; fn sub(self, a: Self) -> Self::Output { Self(Self::lo(self.0 - a.0)) }}
	impl Mul for Field { type Output = Self; fn mul(self, a: Self) -> Self::Output { Self(Self::cv(self.0 as i64 * a.0 as i64)) }}
	impl Div for Field { type Output = Self; fn div(self, a: Self) -> Self::Output { self * a.inv() }}
	impl Neg for Field { type Output = Self; fn neg(self) -> Self::Output { Self(Self::lo(-self.0)) }}
	impl AddAssign for Field { fn add_assign(&mut self, a: Self) { *self = *self + a; } }
	impl SubAssign for Field { fn sub_assign(&mut self, a: Self) { *self = *self - a; } }
	impl MulAssign for Field { fn mul_assign(&mut self, a: Self) { *self = *self * a; } }
	impl DivAssign for Field { fn div_assign(&mut self, a: Self) { *self = *self / a; } }
	use std::fmt::{Display, Formatter, Result};
	impl Display for Field { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "{}", self.0) } }
}
use field::Field as Z;
//}}}

fn main() {
	let mut rin = reader();
	let mut rout = writer();
	let z0 = Z::new(0);

	l!(r,g = rin.u());
	let mut dp = vec![z0; r+1];
	dp[r] = Z::new(1);
	let mut sum = dp[r];
	let mut sol = sum;
	let mut rg = 0;
	for n in 1.. {
		if sum == z0 {
			break;
		}
		sol = sum;
		let mut dp1 = vec![z0; r+1];
		sum = z0;
		for i in 0..=r {
			if r + g < rg + i { break; }
			let j = r + g - rg - i;
			if j > g { continue; }
			if dp[i] == z0 { continue; }
			sum += dp[i];
			if j >= n {
				dp1[i] += dp[i];
			}
			if i >= n {
				dp1[i - n] += dp[i];
			}
		}
		rg += n;
		dp = dp1;
	}
	writeln!(rout, "{}", sol).ok();
}


use std::io;
use std::str::FromStr;
use std::collections::HashMap;

fn get_num() -> usize{
    let mut input = String::new();

    io::stdin().read_line(&mut input)
        .expect("");

    usize::from_str(input.trim()).unwrap()
}

fn main() {
    let n = get_num();

    let mut m = HashMap::new();
    m.insert(0, (0, 0));
    m.insert(1, (0, 1));
    m.insert(2, (0, 2));
    m.insert(3, (0, 2));
    m.insert(4, (0, 2));
    m.insert(5, (0, 2));
    m.insert(6, (1, 2));
    m.insert(7, (2, 2));

    if n < 8 {
        let r = m.get(&n).unwrap();
        println!("{} {}", r.0, r.1);
    } else {
        let r = m.get(&(n%7)).unwrap();
        println!("{} {}", (n/7) * 2 + r.0, (n/7) * 2 + r.1);
    }
}


//spnauti-rusT
use std::io::*;
use std::str::*;
use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::*;
#[allow(unused_imports)] use std::iter::*;
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_macros)]
macro_rules! m {
    ($c:tt, $x:expr, $y:expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
#[allow(unused_macros)]
macro_rules! l {
    ($i:ident . $e:tt : $t:ty; $($a:ident),*) => {
        $( let $a: $t = $i.$e(); )*
    };
    ($i:ident . $e:tt; $($a:ident),*) => {
        $( let $a = $i.$e(); )*
    };
}
struct WordReader<'a> { it : SplitAsciiWhitespace<'a> }
#[allow(dead_code)]
impl<'a> WordReader<'a> {
    fn new<T: Read>(b: &mut String, mut r: T) -> WordReader {
        b.clear();
        r.read_to_string(b).ok();
        WordReader { it: b.split_ascii_whitespace() }
    }
    fn from_stdin(b: &mut String) -> WordReader {
        WordReader::new(b, stdin())
    }
    fn sl(&mut self) ->  &str { self.it.next().unwrap() }
    fn bs(&mut self) -> &[u8] { self.sl().as_bytes()    }
    fn s(&mut self) -> String { String::from(self.sl()) }
    fn i(&mut self) ->    i32 { self.p()                }
    fn f(&mut self) ->    f64 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn sk(&mut self, n: usize) { self.it.nth(n - 1); }
    fn vi(&mut self, n: usize) -> Vec<i32> {
        self.vp::<i32>(n)
    }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
        self.vp(n).into_iter()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}
//------------------- End rusT

fn main() {
    let mut bin = String::new();
    let mut input = WordReader::from_stdin(&mut bin);

    let n = input.i();
    let a = n / 7 * 2;
    let b = n % 7;
    println!("{} {}", a + (b-5).max(0).min(2), a + b.min(2));
}


#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_imports)]
use std::io::stdin;

mod util {
    use std::io::stdin;
    use std::str::FromStr;
    use std::fmt::Debug;

    #[allow(dead_code)]
    pub fn line() -> String {
        let mut line: String = String::new();
        stdin().read_line(&mut line).unwrap();
        line.trim().to_string()
    }

    #[allow(dead_code)]
    pub fn gets<T: FromStr>() -> Vec<T>
    where
        <T as FromStr>::Err: Debug,
    {
        let mut line: String = String::new();
        stdin().read_line(&mut line).unwrap();
        line.split_whitespace()
            .map(|t| t.parse().unwrap())
            .collect()
    }
}

#[allow(unused_macros)]
macro_rules! get {
    ($t:ty) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.trim().parse::<$t>().unwrap()
        }
    };
    ($($t:ty),*) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            (
                $(iter.next().unwrap().parse::<$t>().unwrap(),)*
            )
        }
    };
    ($t:ty; $n:expr) => {
        (0..$n).map(|_|
                    get!($t)
                   ).collect::<Vec<_>>()
    };
    ($($t:ty),*; $n:expr) => {
        (0..$n).map(|_|
                    get!($($t),*)
                   ).collect::<Vec<_>>()
    };
    ($t:ty ;;) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.split_whitespace()
                .map(|t| t.parse::<$t>().unwrap())
                .collect::<Vec<_>>()
        }
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

// https://github.com/bluss/permutohedron
pub trait LexicalPermutation {
    /// Return `true` if the slice was permuted, `false` if it is already
    /// at the last ordered permutation.
    fn next_permutation(&mut self) -> bool;
    /// Return `true` if the slice was permuted, `false` if it is already
    /// at the first ordered permutation.
    fn prev_permutation(&mut self) -> bool;
}

impl<T> LexicalPermutation for [T]
where
    T: Ord,
{
    /// Original author in Rust: Thomas Backman <serenity@exscape.org>
    fn next_permutation(&mut self) -> bool {
        // These cases only have 1 permutation each, so we can't do anything.
        if self.len() < 2 {
            return false;
        }

        // Step 1: Identify the longest, rightmost weakly decreasing part of the vector
        let mut i = self.len() - 1;
        while i > 0 && self[i - 1] >= self[i] {
            i -= 1;
        }

        // If that is the entire vector, this is the last-ordered permutation.
        if i == 0 {
            return false;
        }

        // Step 2: Find the rightmost element larger than the pivot (i-1)
        let mut j = self.len() - 1;
        while j >= i && self[j] <= self[i - 1] {
            j -= 1;
        }

        // Step 3: Swap that element with the pivot
        self.swap(j, i - 1);

        // Step 4: Reverse the (previously) weakly decreasing part
        self[i..].reverse();

        true
    }

    fn prev_permutation(&mut self) -> bool {
        // These cases only have 1 permutation each, so we can't do anything.
        if self.len() < 2 {
            return false;
        }

        // Step 1: Identify the longest, rightmost weakly increasing part of the vector
        let mut i = self.len() - 1;
        while i > 0 && self[i - 1] <= self[i] {
            i -= 1;
        }

        // If that is the entire vector, this is the first-ordered permutation.
        if i == 0 {
            return false;
        }

        // Step 2: Reverse the weakly increasing part
        self[i..].reverse();

        // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
        let mut j = self.len() - 1;
        while j >= i && self[j - 1] < self[i - 1] {
            j -= 1;
        }

        // Step 4: Swap that element with the pivot
        self.swap(i - 1, j);

        true
    }
}

fn main() {
    let mut v = get!(usize;;);

    v.sort();

    if v[0] == 1 {
        println!("YES");
        return;
    }

    while {
        let a = v[0];
        let b = v[1];
        let c = v[2];

        let t0 = 0;
        let t1 = 1;

        let mut t2 = 0;

        for t in 2..2000 {
            if !((t - t0) % a == 0 || (t - t1) % b == 0) {
                t2 = t;
                break;
            }
        }

        if (0..2000).all(|t| {
            (t >= t0 && (t - t0) % a == 0) || (t >= t1 && (t - t1) % b == 0)
                || (t >= t2 && (t - t2) % c == 0)
        }) {
            println!("YES");
            return;
        }

        v.next_permutation()
    } {}

    println!("NO");
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::*;
#[allow(dead_code)]
fn getline() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok();
    return ret;
}
fn get_word() -> String {
    let mut stdin = std::io::stdin();
    let mut u8b: [u8; 1] = [0];
    loop {
        let mut buf: Vec<u8> = Vec::with_capacity(16);
        loop {
            let res = stdin.read(&mut u8b);
            if res.unwrap_or(0) == 0 || u8b[0] <= b' ' {
                break;
            } else {
                buf.push(u8b[0]);
            }
        }
        if buf.len() >= 1 {
            let ret = std::string::String::from_utf8(buf).unwrap();
            return ret;
        }
    }
}
fn parse<T: std::str::FromStr>(s: &str) -> T { s.parse::<T>().ok().unwrap() }

#[allow(dead_code)]
fn get<T: std::str::FromStr>() -> T { parse(&get_word()) }

fn main() {
    let k: i64 = get();
    let a: i64 = get();
    let b: i64 = get();
    let aq = a / k;
    let bq = b / k;
    let res: i64 = if (aq == 0 && b % k != 0) || (bq == 0 && a % k != 0) {
        -1
    } else {
        a / k + b / k
    };
    println!("{}", res);
}


use std::io::{ self, BufRead };
use std::collections::*;

macro_rules! scan_line {
    () => ({
        let stdin = io::stdin();
        let mut handle = stdin.lock();
        let mut buffer = String::new();
        handle.read_line(&mut buffer)
            .expect("scan_line: failed at `handle.read_line`.");
        buffer
    });
    ( $($t:ty)+ ) => ({
        let stdin = io::stdin();
        let mut handle = stdin.lock();
        let mut buffer = String::new();
        handle.read_line(&mut buffer)
            .expect("scan_line: failed at `handle.read_line`.");
        let mut chunks = buffer.split_whitespace();

        ($(
            {
                chunks.next()
                    .expect("scan_line: failed at `next`, # of space separated strings not equal to requested #")
                .parse::<$t>()
                    .expect("scan_line: failed at `parse::<$t>`.")
            },
        )+)
    })
}

fn main() {
    let (n, k, t) = scan_line!(i64 i64 i64);

    if t <= k {
        println!("{}", t);
    } else if t <= n {
        println!("{}", k);
    } else {
        let d = k - (t - n);
        println!("{}", d);
    }
}


use std::io;

fn main() {
    let (n, k, t) = {
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();
        let mut it = input.split_whitespace().map(|k| k.parse::<u32>().unwrap());
        (
            it.next().unwrap(),
            it.next().unwrap(),
            it.next().unwrap(),
            )
    };

    let ans = if t < k {
        (t - 1) % k + 1
    } else if t > n {
        n + k - t
    } else {
        k
    };

    println!("{}", ans);
}


use std::io;

fn main()
{
   let mut n =String::new();
   let mut opt = String::new();
   io::stdin().read_line(&mut n);
   io::stdin().read_line(&mut opt);

    let n:usize = n.trim().parse().expect("");
    let mut ans = 0;
   for i in 0..n
   {
       if opt.chars().nth(i) == Some('-')
       {
           ans-=1;
           if ans<0
           {
                ans=0;
           }
       }
       else
       {
           ans+=1;
       }
   }

   println!("{}", ans);
}