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

pub struct Scanner<R> {
    reader: R,
    buffer: Vec<String>,
}

impl<R: io::BufRead> Scanner<R> {
    pub fn new(reader: R) -> Self {
        Self {
            reader,
            buffer: vec![],
        }
    }

    pub fn token<T: str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            self.reader.read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

fn zeros_factorial(n: u64) -> u64 {
    let mut ans = 0;
    let mut n = n;
    while n > 0 {
        ans += n / 5;
        n /= 5;
    }
    ans
}

fn search(m: u64) -> u64 {
    let mut lo = 0;
    let mut hi = 500000; // zeros_factorial(n) >= n / 5
    while lo < hi {
        let mid = lo + (hi - lo) / 2;
        if zeros_factorial(mid) >= m {
            hi = mid;
        } else {
            lo = mid + 1;
        }
    }
    lo
}

fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
    let m: u64 = scan.token();
    let n = search(m);
    if zeros_factorial(n) == m {
        writeln!(out, "5").ok();
        for i in 0..5 {
            write!(out, "{} ", n + i).ok();
        }
        writeln!(out).ok();
    } else {
        writeln!(out, "0").ok();
    }
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());
    solve(&mut scan, &mut out);
}


fn input_split() -> Vec<u16> {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    buf.trim()
        .split_whitespace()
        .map(|elem| elem.parse().unwrap())
        .collect()
}

fn determine_b(v: &[u16]) -> Option<u16> {
    let sum: u16 = v.iter().sum();
    if sum % 5 == 0 && sum != 0 {
        Some(sum / 5)
    } else {
        None
    }
}

fn print(res: Option<u16>) {
    match res {
        Some(val) => print!("{}", val),
        None => print!("-1"),
    }
}

fn main() {
    print(determine_b(&input_split()))
}


#![allow(unused_imports)]
#![allow(non_snake_case)]

use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::fmt::{Debug, Formatter};
use std::io::*;
use std::ops::*;
use std::*;

// -----------------------------------------------
// Framework
// -----------------------------------------------

#[allow(unused_macros)]
macro_rules! read {
    ([$t:ty] ; $n:expr) =>
        ((0..$n).map(|_| read!([$t])).collect::<Vec<_>>());
    ($($t:ty),+ ; $n:expr) =>
        ((0..$n).map(|_| read!($($t),+)).collect::<Vec<_>>());
    ([$t:ty]) =>
        (rl().split_whitespace().map(|w| w.parse().unwrap()).collect::<Vec<$t>>());
    ($t:ty) =>
        (rl().parse::<$t>().unwrap());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($arg:expr),*) => {
        #[cfg(debug_assertions)]
        {
            let entries = [$(&stringify!([$arg]:), &$arg as &Debug),*];
            stderr().write_fmt(format_args!("{:#?}\n", entries)).unwrap();
        }
    };
}

#[allow(dead_code)]
fn rl() -> String {
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    buf.trim_right().to_owned()
}

trait IteratorExt: Iterator + Sized {
    fn vec(self) -> Vec<Self::Item> {
        self.collect()
    }
}

impl<T: Iterator> IteratorExt for T {}

// -----------------------------------------------
// Solution
// -----------------------------------------------

pub fn main() {
    let (_, d) = read!(usize, i64);
    let mut A = read![[i64]];
    A.sort();

    let mut l = 0;
    let mut r = 0;
    let mut ma = 0;
    while l < A.len() {
        while r < A.len() && A[r] - A[l] <= d {
            r += 1;
        }

        ma = max(ma, r - l);
        l += 1;
    }

    println!("{}", A.len() - ma);
    return;
}


use std::io;

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s = s.trim().to_string();
    let n = s.len();
    let mut flag = 1;   // 0,一般，1,开头, 2,中间
    let mut i = 0;
    while i < n {
        if i+2 < n && s[i..i+3] == String::from("WUB") {
            i += 3;
            if flag == 1 {

            } else if flag == 2 {

            } else {    // flag == 0
                flag = 2;
                print!(" ");
            }
        }
        else {
            flag = 0;
            print!("{}", s.as_bytes()[i] as char);
            i += 1;
        }
    }
}


#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

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

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

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

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

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

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

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

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

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*);
    }
}

#[allow(unused_imports)]
use std::cmp::{min, max};
#[allow(unused_imports)]
use std::io::{stdout, stdin, BufWriter, Write};

fn main() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (writeln!(out,$($format)*).unwrap());
    }

    input!{
      n: usize,
      m: usize,
      a: usize,
      b: usize,
      g0: u64,
      x: u64,
      y: u64,
      z: u64,
    }

    let mut hs = vec![vec![0; m]; n];
    let mut g = g0;
    for i in 0..n*m {
        let a = i/m;
        let b = i%m;
        hs[a][b] = g;
        g = (g * x  + y) % z;
    }

    // debug!(n, m, a, b, hs);

    let mut min_table = vec![];

    // スライド最小値
    use std::collections::VecDeque;
    for i in 0..n {
        let mut q: VecDeque<(usize,usize)> = VecDeque::new();
        let mut row_mins = vec![];
        for j in 0..m {
            let h = hs[i][j];

            while q.len() > 0 {
                let (x, y) = *q.back().unwrap();
                if h <= hs[x][y] {
                    q.pop_back();
                } else {
                    break;
                }
            }
            q.push_back((i, j));

            if j < b-1 {
                continue;
            }
            if j >= b {
                let (_,y) = *q.front().unwrap();
                if y == j-b {
                    q.pop_front();
                }
            }

            // debug!(i, j, q);
            let (x,y) = *q.front().unwrap();
            row_mins.push(hs[x][y]);
        }
        min_table.push(row_mins);
    }

    let mut ans = 0;
    for j in 0..m-b+1 {
        let mut q: VecDeque<(usize,usize)> = VecDeque::new();
        for i in 0..n {
            let h = min_table[i][j];

            while q.len() > 0 {
                let (x, y) = *q.back().unwrap();
                if h <= min_table[x][y] {
                    q.pop_back();
                } else {
                    break;
                }
            }
            q.push_back((i, j));

            if i < a-1 {
                continue;
            }
            if i >= a {
                let (x,_) = *q.front().unwrap();
                if x == i-a {
                    q.pop_front();
                }
            }

            let (x,y) = *q.front().unwrap();
            ans += min_table[x][y];

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


// ---------- begin Matrix ----------

#[allow(dead_code)]
mod matrix {
    use std::ops::Add;
    use std::ops::Mul;
    pub trait SemiRing: Add<Output = Self> + Mul<Output = Self> + Copy {
        fn zero() -> Self;
        fn one() -> Self;
    }
    #[derive(Clone)]
    pub struct SquareMatrix<T: SemiRing> {
        n: usize,
        a: Vec<T>,
    }
    impl<T: SemiRing> SquareMatrix<T> {
        pub fn zero(n: usize) -> Self {
            let z = T::zero();
            SquareMatrix {
                n: n,
                a: vec![z; n * n],
            }
        }
        pub fn identity(n: usize) -> Self {
            let mut m = Self::zero(n);
            for i in 0..n {
                m.a[i * n + i] = T::one();
            }
            m
        }
        pub fn set_at(&mut self, i: usize, j: usize, v: T) {
            debug_assert!(i < self.n && j < self.n);
            self.a[i * self.n + j] = v;
        }
        pub fn get_at(&self, i: usize, j: usize) -> T {
            debug_assert!(i < self.n && j < self.n);
            self.a[i * self.n + j]
        }
        pub fn matmul(l: Self, r: Self) -> Self {
            l * r
        }
    }
    impl<T: SemiRing> Add for SquareMatrix<T> {
        type Output = Self;
        fn add(self, rhs: Self) -> Self {
            debug_assert!(self.n == rhs.n);
            let n = self.n;
            let mut c = Self::zero(n);
            for i in 0..(n * n) {
                c.a[i] = self.a[i] + rhs.a[i];
            }
            c
        }
    }
    impl<T: SemiRing> Mul for SquareMatrix<T> {
        type Output = Self;
        fn mul(self, rhs: Self) -> Self {
            debug_assert!(self.n == rhs.n);
            let n = self.n;
            let mut c = Self::zero(n);
            for i in 0..n {
                for k in 0..n {
                    let a = self.a[i * n + k];
                    for (x, y) in c.a[(i * n)..((i + 1) * n)].iter_mut().zip(rhs.a[(k * n)..((k + 1) * n)].iter()) {
                        *x = *x + a * *y;
                    }
                }
            }
            c
        }
    }
}

// ---------- end Matrix ----------
// ---------- begin ModInt ----------

//https://github.com/kenkoooo/competitive-programming-rs/blob/master/src/math/mod_int.rs
//を参考にしています
#[allow(dead_code)]
mod modint {
    pub const MOD: u32 = 1000000000 + 7;
    use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
    #[derive(Clone, Copy)]
    pub struct ModInt<T: Copy + Clone>(pub T);
    pub type Num = u32;
    impl Add<ModInt<Num>> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn add(self, other: ModInt<Num>) -> ModInt<Num> {
            let mut d = self.0 + other.0;
            if d >= MOD {
                d -= MOD;
            }
            ModInt(d)
        }
    }
    impl AddAssign<ModInt<Num>> for ModInt<Num> {
        fn add_assign(&mut self, other: ModInt<Num>) {
            *self = *self + other;
        }
    }
    impl Sub<ModInt<Num>> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn sub(self, other: ModInt<Num>) -> ModInt<Num> {
            let mut d = self.0 + MOD - other.0;
            if d >= MOD {
                d -= MOD;
            }
            ModInt(d)
        }
    }
    impl SubAssign<ModInt<Num>> for ModInt<Num> {
        fn sub_assign(&mut self, other: ModInt<Num>) {
            *self = *self - other;
        }
    }
    impl Mul<ModInt<Num>> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn mul(self, other: ModInt<Num>) -> ModInt<Num> {
            ModInt(((self.0 as u64) * (other.0 as u64) % (MOD as u64)) as u32)
        }
    }
    impl MulAssign<ModInt<Num>> for ModInt<Num> {
        fn mul_assign(&mut self, other: ModInt<Num>) {
            *self = *self * other;
        }
    }
    impl Div<Num> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn div(self, other: Num) -> ModInt<Num> {
            self * ModInt(other).pow(MOD - 2)
        }
    }
    impl Div<ModInt<Num>> for ModInt<Num> {
        type Output = ModInt<Num>;
        fn div(self, other: ModInt<Num>) -> ModInt<Num> {
            self * other.pow(MOD - 2)
        }
    }
    impl DivAssign<ModInt<Num>> for ModInt<Num> {
        fn div_assign(&mut self, other: ModInt<Num>) {
            *self = *self / other;
        }
    }
    impl Neg for ModInt<Num> {
        type Output = ModInt<Num>;
        fn neg(self) -> ModInt<Num> {
            ModInt(if self.0 == 0 { 0 } else { MOD - self.0 })
        }
    }
    impl ModInt<Num> {
        pub fn new(v: u32) -> ModInt<Num> {
            ModInt(v % MOD)
        }
        pub fn pow(self, mut n: u32) -> ModInt<Num> {
            let mut t = ModInt::new(1);
            let mut s = self;
            while n > 0 {
                if (n & 1) == 1 {
                    t *= s;
                }
                s *= s;
                n >>= 1;
            }
            t
        }
    }
    pub struct Precalc {
        n: usize,
        inv: Vec<ModInt<Num>>,
        fact: Vec<ModInt<Num>>,
        ifact: Vec<ModInt<Num>>,
    }
    impl Precalc {
        pub fn new(n: usize) -> Precalc {
            let mut inv = vec![ModInt(1); n + 1];
            let mut fact = vec![ModInt(1); n + 1];
            let mut ifact = vec![ModInt(1); n + 1];
            for i in 1..(n + 1) {
                if i > 2 {
                    inv[i] = -inv[(MOD as usize) % i] * ModInt(MOD / (i as u32));
                }
                fact[i] = ModInt(i as u32) * fact[i - 1];
                ifact[i] = inv[i] * ifact[i - 1];
            }
            Precalc {
                n: n,
                inv: inv,
                fact: fact,
                ifact: ifact,
            }
        }
        pub fn fact(self, n: usize) -> ModInt<Num> {
            self.fact[n]
        }
        pub fn inv(self, x: usize) -> ModInt<Num> {
            self.inv[x]
        }
        pub fn ifact(self, x: usize) -> ModInt<Num> {
            self.ifact[x]
        }
        pub fn comb(self, n: usize, k: usize) -> ModInt<Num> {
            if !(k <= n) {
                return ModInt(0);
            }
            self.fact[n] * self.ifact[k] * self.ifact[n - k]
        }
    }
    use std;
    impl std::fmt::Display for ModInt<Num> {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
            write!(f, "{}", self.0)
        }
    }
}

// ---------- end ModInt ----------

//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")
    };
}

// ここまで

use matrix::SquareMatrix;
use modint::ModInt;

impl matrix::SemiRing for ModInt<modint::Num> {
    fn one() -> Self {ModInt(1)}
    fn zero() -> Self {ModInt(0)}
}

fn run() {
    input! {
        n: u64,
        m: usize,
    }
    type M = SquareMatrix<ModInt<modint::Num>>;
    let mut t = M::identity(m);
    let mut s = M::zero(m);
    for i in 1..m {
        s.set_at(i - 1, i , ModInt(1));
    }
    s.set_at(m - 1, 0, ModInt(1));
    s.set_at(m - 1, m - 1, ModInt(1));
    let mut n = n;
    while n > 0 {
        if (n & 1) == 1 {
            t = t * s.clone();
        }
        s = s.clone() * s;
        n >>= 1;
    }
    let ans = t.get_at(m - 1, m - 1);
    println!("{}", ans);
}

fn main() {
    run();
}


/// square root of an int
fn sqrti(b: u64) -> u64 {
    let n = 2;
    if b < 2 {
        return b
    };
    let n1 = n - 1;
    let n2 = n;
    let n3 = n1;
    let mut c = 1;
    let mut d = (n3 + b) / n2;
    let mut e = (n3 * d + b / d.pow(n1 as u32)) / n2;
    while c != d && c != e {
        c = d;
        d = e;
        e = (n3 * e + b / e.pow(n1 as u32)) / n2;
    }
    if d < e { d }
    else { e }
}

use std::ops::Range;

/// iterator that returns `(w, h)` for rectangles of provided area
struct Rects {
    area: u64,
    w: u64,
    rw: Range<u64>,
    rh: Range<u64>,
}

impl Rects {
    pub fn new(area: u64) -> Rects {
        let q = sqrti(area);
        Rects { area, rw: 1..q, rh: 1..area, w: q }
    }
    pub fn with_limits(area: u64, rw: Range<u64>, rh: Range<u64>) -> Rects {
        let q = sqrti(area);
        let maxw = q.min(area / rh.start).min(rw.end);
        let minw = (area / rh.end).max(rw.start);
        Rects { area, rw: minw..maxw, rh, w: maxw }
    }
}

impl Iterator for Rects {
    type Item = (u64, u64);
    fn next(&mut self) -> Option<(u64, u64)> {
        while self.w >= self.rw.start {
            let w = self.w;
            self.w -= 1;
            let h = self.area / w;
            if h < self.rh.start || h > self.rh.end || h * w != self.area {
                continue;
            }
            return Some((w, h));
        }
        None
    }
}

fn solve(a: u64, b: u64) -> Option<u64> {
    if a < 1 || b < 1 {
        return None;
    }
    let area = a + b;
    Rects::new(area).flat_map(|(ow, oh)| {
        let perimeter = (ow + oh) * 2;
        Rects::with_limits(a, 1..ow, 1..oh)
            .chain(Rects::with_limits(b, 1..ow, 1..oh))
            .find(|&(iw, ih)| iw <= ow && ih <= oh)
            .and(Some(perimeter))
    }).next()
}

use std::io::{stdin, BufRead};
use std::process::{exit};
fn input() -> Result<(u64, u64), String> {
    let std = stdin();
    let mut row = String::new();
    std.lock().read_line(&mut row).map_err(|_|"Cannot read stdin")?;
    let words: Vec<&str> = row.trim().split(' ').collect();
    let a: u64 = words[0].parse().map_err(|_|"Cannot parse input")?;
    let b: u64 = words[1].parse().map_err(|_|"Cannot parse input")?;
    Ok((a, b))
}

fn main() {
    let rv = input().map(|(a,b)| solve(a, b));
    match rv {
        Ok(Some(perimeter)) => {
            println!("{}", perimeter);
        }
        Ok(None) => {
            eprintln!("Error: solution not found");
            exit(1);
        }
        Err(e) => {
            eprintln!("Error: {}", e);
            exit(1);
        }
    }
}


struct FenwickTree {
    val: Vec<i64>,
}

impl FenwickTree {
    fn new(n: usize) -> Self {
        FenwickTree {
            val: vec![0; n + 1],
        }
    }
    fn add(&mut self, mut x: usize, v: i64) {
        while let Some(p) = self.val.get_mut(x) {
            *p += v;
            x += x & (!x + 1);
        }
    }
    fn sum(&mut self, mut x: usize) -> i64 {
        assert!(x < self.val.len());
        let mut ans = 0;
        while x > 0 {
            ans += self.val[x];
            x -= x & (!x + 1);
        }
        ans
    }
}

fn sieve(n: usize) -> Vec<i64> {
    let mut is_prime = vec![true; n + 1];
    for i in 2.. {
        if i * i > n {
            break;
        }
        if is_prime[i] {
            let mut j = i * i;
            while j <= n {
                is_prime[j] = false;
                j += i;
            }
        }
    }
    let len = is_prime.iter().skip(2).filter(|p| **p).count();
    let mut prime = Vec::with_capacity(len);
    for (i, is_prime) in is_prime.into_iter().enumerate().skip(2) {
        if is_prime {
            prime.push(i as i64);
        }
    }
    prime
}

struct PrimeCountSolver {
    query: Vec<i64>,
    memo: Vec<i64>,
}

impl PrimeCountSolver {
    fn new() -> Self {
        PrimeCountSolver {
            query: vec![],
            memo: vec![],
        }
    }
    fn add(&mut self, n: i64) {
        self.query.push(n);
    }
    fn build(&mut self) {
        self.query.sort();
        self.query.dedup();
        let n = self.query.last().map_or(1, |n| *n);
        let mut m = 1;
        while (m + 1) * (m + 1) <= n {
            m += 1;
        }
        let p = sieve(m as usize);
        let bound = (n as f64).cbrt().powi(2) as i64 + 2;
        let mut stack = vec![];
        for &v in self.query.iter() {
            let k = match p.binary_search_by(|&p| (p * p).cmp(&v)) {
                Ok(k) => k + 1,
                Err(k) => k,
            };
            stack.push((v, k));
        }
        let mut query = vec![];
        while let Some((n, k)) = stack.pop() {
            if k == 0 {
                continue;
            }
            let q = p[k - 1];
            if q * q > n {
                let x = match p[..k].binary_search_by(|&p| (p * p).cmp(&n)) {
                    Ok(k) => k + 1,
                    Err(k) => k,
                };
                stack.push((n, x));
            } else if n <= bound {
                query.push((k, n));
            } else {
                stack.push((n, k - 1));
                stack.push((n / q, k - 1));
            }
        }
        query.sort();
        query.dedup();
        let m = bound as usize;
        let mut bit = FenwickTree::new(m);
        for i in 1..=m {
            bit.add(i, 1);
        }
        let mut is_prime = vec![true; m + 1];
        let mut memo = vec![0; query.len()];
        let mut pos = 0;
        for (i, p) in p.iter().enumerate() {
            let p = *p as usize;
            let mut j = p;
            while j <= m {
                if is_prime[j] {
                    bit.add(j, -1);
                }
                is_prime[j] = false;
                j += p;
            }
            while let Some(&(k, n)) = query.get(pos) {
                if k > i + 1 {
                    break;
                } else {
                    memo[pos] = bit.sum(n as usize);
                    pos += 1;
                }
            }
            if pos >= query.len() {
                break;
            }
        }
        self.memo.clear();
        self.memo.resize(self.query.len(), 0);
        let mut stack = vec![];
        for (i, &n) in self.query.iter().enumerate() {
            let k = match p.binary_search_by(|&p| (p * p).cmp(&n)) {
                Ok(k) => k + 1,
                Err(k) => k,
            };
            self.memo[i] += k as i64 - 1;
            stack.push((n, k, 1, i));
        }
        while let Some((n, k, sign, i)) = stack.pop() {
            if k == 0 {
                self.memo[i] += sign * n;
                continue;
            }
            let q = p[k - 1];
            if q * q > n {
                let x = match p[..k].binary_search_by(|p| (p * p).cmp(&n)) {
                    Ok(k) => k + 1,
                    Err(k) => k,
                };
                self.memo[i] += -sign * (k - x) as i64;
                stack.push((n, x, sign, i));
            } else if n <= bound {
                self.memo[i] += sign * memo[query.binary_search(&(k, n)).unwrap()];
            } else {
                stack.push((n, k - 1, sign, i));
                stack.push((n / q, k - 1, -sign, i));
            }
        }
    }
    fn get(&self, n: i64) -> i64 {
        self.memo[self.query.binary_search(&n).unwrap()]
    }
}

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let n: i64 = s.trim().parse().unwrap();
    let p = sieve((n as f64).sqrt() as usize + 2);
    let mut ans = 0i64;
    for p in p.iter() {
        if p.pow(3) <= n {
            ans += 1;
        } else {
            break;
        }
    }
    let mut solver = PrimeCountSolver::new();
    for (i, p) in p.iter().enumerate() {
        if p.pow(2) <= n {
            ans -= i as i64 + 1;
            solver.add(n / *p);
        }
    }
    solver.build();
    for p in p.iter() {
        if p.pow(2) <= n {
            ans += solver.get(n / *p);
        }
    }
    println!("{}", ans);
}

fn main() {
    run();
}


fn main() {
    let mut input = String::new();

    std::io::stdin().read_line(&mut input).expect("INPUT::Read line failed!");

    let number = input.trim().parse::<i32>().expect("NUMBER::Parse to i32 failed!");

    if number % 2 == 0 {
        println!("Mahmoud");
    }else {
        println!("Ehab");
    }
}


//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! min {
	($x:expr,$y:expr) => {{ let b=$y; let a=&mut$x; if b < *a {*a=b; true} else {false} }};
}
#[allow(unused_macros)] macro_rules! max {
	($x:expr,$y:expr) => {{ let b=$y; let a=&mut$x; if b > *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! v {
	([$d:expr]$($s:tt)+) => {vec![v!($($s)+);$d]};
	([]) => {Vec::new()}; ([$e:expr]) => {Vec::with_capacity($e)}; (=$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: v!([]), 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 = v!([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 vvb(&mut self, r: usize, c: Option<usize>) -> Vec<Vec<u8>> {
		let mut res = v!([r]);
		let c = c.unwrap_or(0);
		rep!{[r]
			let t = self.vb();
			assert!(c == 0 || t.len() == c);
			res.push(t);
		}
		res
	}
	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()
	}
	fn graph(&mut self, n: usize, m: usize) -> Vec<Vec<usize>> {
		let mut e = v!([n][]); rep!{[m] l!(a,b = self.u()-1); e[a].push(b); e[b].push(a); } e
	}
	fn graph_w<T: Copy+FromStr>(&mut self, n: usize, m: usize) -> Vec<Vec<(usize,T)>> where T::Err: Debug {
		let mut e = v!([n][]); rep!{[m] l!(a,b = self.u()-1); let c: T = self.p(); e[a].push((b,c)); e[b].push((a,c)); } e
	}
}
//------------------- End rusT }}}

// Field (mod prime) {{{
mod field {
	use std::ops::*;
	#[allow(dead_code)] pub const Z0: Field = Field(0);
	#[allow(dead_code)] pub const Z1: Field = Field(1);
	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 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) } }
}
#[allow(unused_imports)] use field::{Field, Field as Z, Z0, Z1};
//}}}
// Binomial Coefficient (C(n,r)) {{{
#[derive(Debug,Clone)]
struct Cnr {
	n: usize,
	pub f: Box<[Field]>,
	fi: Box<[Field]>
}
#[allow(dead_code)]
impl Cnr {
	fn new(n: usize) -> Self {
		let mut f = Vec::with_capacity(n+1);
		f.push(Z1);
		for i in 1..=n {
			f.push(f[i-1] * Field::new(i as i32));
		}
		let mut fi = vec![Z1; n+1];
		fi[n] = f[n].inv();
		for i in (0..n).rev() {
			fi[i] = fi[i+1] * Field::new(i as i32 + 1);
		}
		let f = f.into_boxed_slice();
		let fi = fi.into_boxed_slice();
		Self {n, f, fi}
	}
	fn cnr(&self, n: usize, r: usize) -> Field {
		if r > n {
			Z0
		} else {
			self.f[n] * self.fi[r] * self.fi[n-r]
		}
	}
}//}}}

fn main() {
	let mut rin = reader();
	let mut rout = writer();

	l!(n,x,p = rin.u());
	let x = x-1;
	let mut lo = 0;
	let mut hi = n;
	l!(mut lo_fix,hi_fix = 0);
	while lo < hi {
		let mid = (lo + hi) / 2;
		if mid == p {
			lo = mid + 1;
		} else if mid < p {
			lo_fix += 1;
			lo = mid + 1;
		} else {
			hi_fix += 1;
			hi = mid;
		}
	}

	let f = Cnr::new(n);
	let sol = f.cnr(x, lo_fix) * f.f[lo_fix] * f.cnr(n-1-x, hi_fix) * f.f[hi_fix] * f.f[n - hi_fix - lo_fix - 1];
	writeln!(rout, "{}", sol).ok();
}


#[allow(unused_imports)]
use std::cmp::{min,max};
use std::io::{BufWriter, stdin, stdout, Write};

#[derive(Default)]
struct Scanner {
    buffer: Vec<String>
}
impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

fn main() {
    let mut scan = Scanner::default();
    let out = &mut BufWriter::new(stdout());

	let n = 4;
    let mut p = (0..n).map(|_| scan.next::<u64>()).collect::<Vec<u64>>();
    p.sort();
    p.dedup();

    writeln!(out, "{}", n - p.len()).expect("fail");
}


use std::io::{self};

#[derive(Copy, Clone)]
struct Div3 {
    remain0: i64,
    remain1: i64,
    remain2: i64,
}

fn main() {
    let mut m = vec![Div3{remain0: 0, remain1: 0, remain2: 0}; 10000005].into_boxed_slice();
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).expect("???");

    let x = buffer.trim().split(' ').map(|o| o.parse::<i64>().unwrap()).collect::<Vec<i64>>();
    let d = (x[2] - x[1] + 1) / 3;
    let moder: i64 = 1e9 as i64 + 7;

    let mut nums = Div3{
        remain0: d,
        remain1: d,
        remain2: d,
    };

    if (x[2] - x[1] + 1) % 3 > 0 {
        let t = {if (x[2] - x[1] + 1) % 3 == 2 {1} else {0}};
        if x[1] % 3 == 0 {
            nums.remain0 = nums.remain0 + 1;
            nums.remain1 = nums.remain1 + t;
        } else if x[1] % 3 == 1 {
            nums.remain1 = nums.remain1 + 1;
            nums.remain2 = nums.remain2 + t;
        } else {
            nums.remain2 = nums.remain2 + 1;
            nums.remain0 = nums.remain0 + t;
        }
    }

    m[1] = nums.clone();

    for i in 2..x[0]+1 {
        let it = i as usize;
        m[it].remain0 = ((m[it - 1].remain0 * nums.remain0) % moder + (m[it - 1].remain1 * nums.remain2) % moder + (m[it - 1].remain2 * nums.remain1) % moder) % moder;
        m[it].remain1 = ((m[it - 1].remain1 * nums.remain0) % moder + (m[it - 1].remain0 * nums.remain1) % moder + (m[it - 1].remain2 * nums.remain2) % moder) % moder;
        m[it].remain2 = ((m[it - 1].remain2 * nums.remain0) % moder + (m[it - 1].remain1 * nums.remain1) % moder + (m[it - 1].remain0 * nums.remain2) % moder) % moder;
    }

    println!("{}", m[x[0] as usize].remain0 % moder);
}


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

fn main() {
    let n: usize = get_line().trim().parse().unwrap();

    let mut w: Vec<i32> = get_vec();

    w.sort();

    let mut ans = None;

    for i in 0..2 * n {
        for j in i + 1..2 * n {
            let mut v = w.clone();
            v.remove(j);
            v.remove(i);
            let cur = v.into_iter().fold((0, false), |acc, x| {
                (if acc.1 {
                    acc.0 + x
                } else {
                    acc.0 - x
                },
                !acc.1)
            }).0;

            match ans {
                Some(x) if x <= cur => (),
                _ => ans = Some(cur),
            };
        }
    }

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


// ---------- begin ModInt ----------
const MOD: u32 = 1_000_000_007;

#[derive(Clone, Copy)]
struct ModInt(u32);

use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Neg};

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

impl AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + MOD - rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

impl Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> Self::Output {
        ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)
    }
}

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

impl Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> Self::Output {
        ModInt(if self.0 == 0 {0} else {MOD - self.0})
    }
}

#[allow(dead_code)]
impl ModInt {
    pub fn new(n: u32) -> ModInt {
        ModInt(n % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        self.pow(MOD - 2)
    }
    pub fn comb(n: u32, k: u32) -> ModInt {
        if k > n {
            return ModInt::zero();
        }
        let k = std::cmp::min(k, n - k);
        let mut nu = ModInt::one();
        let mut de = ModInt::one();
        for i in 0..k {
            nu *= ModInt(n - i);
            de *= ModInt(i + 1);
        }
        nu * de.inv()
    }
}

#[allow(dead_code)]
struct Precalc {
    inv: Vec<ModInt>,
    fact: Vec<ModInt>,
    ifact: Vec<ModInt>,
}

#[allow(dead_code)]
impl Precalc {
    pub fn new(n: usize) -> Precalc {
        let mut inv = vec![ModInt::one(); n + 1];
        let mut fact = vec![ModInt::one(); n + 1];
        let mut ifact = vec![ModInt::one(); n + 1];
        for i in 2..(n + 1) {
            inv[i] = -inv[MOD as usize % i] * ModInt(MOD / i as u32);
            fact[i] = fact[i - 1] * ModInt(i as u32);
            ifact[i] = ifact[i - 1] * inv[i];
        }
        Precalc {
            inv: inv,
            fact: fact,
            ifact: ifact,
        }
    }
    pub fn inv(&self, n: usize) -> ModInt {
        self.inv[n]
    }
    pub fn fact(&self, n: usize) -> ModInt {
        self.fact[n]
    }
    pub fn ifact(&self, n: usize) -> ModInt {
        self.ifact[n]
    }
    pub fn comb(&self, n: usize, k: usize) -> ModInt {
        if k > n {
            return ModInt::zero();
        }
        self.fact[n] * self.ifact[k] * self.ifact[n - k]
    }
}
// ---------- end ModInt ----------

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let mut n: u64 = it.next().unwrap().parse().unwrap();
    let k: usize = it.next().unwrap().parse().unwrap();
    let pc = Precalc::new(50);
    let mut ans = ModInt::one();
    let mut d = 2u64;
    while d * d <= n {
        if n % d == 0 {
            let mut c = 0;
            while n % d == 0 {
                c += 1;
                n /= d;
            }
            let mut dp = vec![ModInt::zero(); c + 1];
            dp[c] = ModInt::one();
            for _ in 0..k {
                let mut next = vec![ModInt::zero(); c + 1];
                for i in 0..=c {
                    next[i] += dp[i] * pc.inv(i + 1);
                }
                for i in (0..c).rev() {
                    next[i] = next[i] + next[i + 1];
                }
                dp = next;
            }
            let mut s = ModInt::zero();
            let mut f = 1u64;
            for i in 0..=c {
                s += ModInt((f % MOD as u64) as u32) * dp[i];
                f *= d;
            }
            ans *= s;
        }
        d += 1;
    }
    if n > 1 {
        let p = pc.inv(2).pow(k as u32);
        ans *= (ModInt::one() - p) + ModInt((n % MOD as u64) as u32) * p;
    }
    println!("{}", ans.0);
}

fn main() {
    run();
}


use std::io::{stdin, Read, StdinLock};
use std::str::FromStr;
use std::iter::FromIterator;

#[allow(unused_macros)]
macro_rules! vecs {
    ($init:expr; $($dim:expr);*) => {
        vecs!($($dim);* => $init)
    };
    ($head:expr; $($tail:expr);* => $init:expr) => {
        vec![vecs!($($tail);* => $init); $head]
    };
    ($head:expr => $init:expr) => {
        vec![$init; $head]
    };
}

fn main() {
    let cin = stdin();
    let mut scan = Scanner::new(cin.lock());
    let n = scan.read::<usize>();
    let k = scan.read::<usize>();
    let d = scan.read::<usize>();
    let mut env = Env {k: k, d: d, memo: vecs![None;n+1;2]};
    env.memo[0][1] = Some(1.into());
    println!("{}", env.need(n));
}

struct Env {
    k: usize,
    d: usize,
    memo: Vec<Vec<Option<Co>>>
}

impl Env {
    fn need(&mut self, n: usize) -> Co {
        if let Some(d) = self.memo[n][0] {
            return d;
        }
        let mut sum = Co(0);
        for i in 1..self.k+1 {
            if n>=i {
                if i>=self.d {sum += self.all(n-i);}
                else {sum += self.need(n-i);}
            }
        }
        self.memo[n][0] = Some(sum);
        sum
    }

    fn all(&mut self, n: usize) -> Co {
        if let Some(d) = self.memo[n][1] {
            return d;
        }
        let mut sum = Co(0);
        for i in 1..self.k + 1 {
            if n>=i {sum += self.all(n-i);}
        }
        self.memo[n][1] = Some(sum);
        sum
    }
}

#[allow(dead_code)]
const M: i64 = 1_000_000_007;

// region modulo
#[allow(dead_code)]
use std::ops::*;

#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Co (pub i64);

#[allow(dead_code)]
impl Co {
    pub fn pow(self, mut n: i64) -> Self {
        let mut a = self;
        let mut res = Co(1);
        while n > 0 {
            if n & 1 == 1 {
                res *= a;
            }
            a = a * a;
            n >>= 1;
        }
        res
    }
}

#[allow(dead_code)]
impl std::fmt::Display for Co {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[allow(dead_code)]
impl From<i32> for Co {
    fn from(value: i32) -> Self {
        Co((value as i64 % M + M) % M)
    }
}
#[allow(dead_code)]
impl From<i64> for Co {
    fn from(value: i64) -> Self {
        Co((value as i64 % M + M) % M)
    }
}
#[allow(dead_code)]
impl From<usize> for Co {
    fn from(value: usize) -> Self {
        Co((value as i64 % M + M) % M)
    }
}
#[allow(dead_code)]
impl AddAssign for Co {
    fn add_assign(&mut self, other: Self) {
        *self = self.add(other);
    }
}
#[allow(dead_code)]
impl Add for Co {
    type Output = Self;
    fn add(self, other: Self) -> Self {
        Co::from((self.0).add(other.0))
    }
}
#[allow(dead_code)]
impl SubAssign for Co {
    fn sub_assign(&mut self, other: Self) {
        *self = self.sub(other);
    }
}
#[allow(dead_code)]
impl Sub for Co {
    type Output = Self;
    fn sub(self, other: Self) -> Self {
        Co::from((self.0).sub(other.0))
    }
}
#[allow(dead_code)]
impl MulAssign for Co {
    fn mul_assign(&mut self, other: Self) {
        *self = self.mul(other);
    }
}
#[allow(dead_code)]
impl Mul for Co {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        Co::from((self.0).mul(other.0))
    }
}
#[allow(dead_code)]
impl DivAssign for Co {
    fn div_assign(&mut self, other: Self) {
        *self = self.div(other);
    }
}
#[allow(dead_code)]
impl Div for Co {
    type Output = Self;
    fn div(self, rhs: Self) -> Self {
        self * rhs.pow((M - 2) as i64)
    }
}
// endregion

// region template
#[allow(dead_code)]
fn iu(i: isize) -> usize { i as usize }

#[allow(dead_code)]
fn ui(i: usize) -> isize { i as isize }

#[allow(dead_code, deprecated)]
fn join<T: std::fmt::Display>(slice: &[T], sep: &str) -> String {
    let strings = slice.iter().map(|t| format!("{}", t)).collect::<Vec<_>>();
    strings.connect(sep)
}

#[allow(dead_code)]
fn arr<'a, S, T>(n: usize, mut f: S) -> Vec<T> where S: FnMut(usize) -> T + 'a {
    (0..n).map(|i| f(i)).collect::<Vec<T>>()
}

#[allow(dead_code)]
fn alt<S, T>(v: Vec<S>) -> T where T: FromIterator<S> {
    v.into_iter().collect::<T>()
}

#[allow(dead_code)]
fn dup<S, T>(v: &[S]) -> T where T: FromIterator<S>, S: Clone {
    v.iter().cloned().collect::<T>()
}

struct Scanner<'a> {
    cin: StdinLock<'a>,
}

#[allow(dead_code)]
impl<'a> Scanner<'a> {
    fn new(cin: StdinLock<'a>) -> Scanner<'a> {
        Scanner { cin: cin }
    }

    fn read1<T: FromStr>(&mut self) -> Option<T> {
        let token = self.cin.by_ref().bytes().map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect::<String>();
        token.parse::<T>().ok()
    }

    fn read<T: FromStr>(&mut self) -> T {
        self.read1().unwrap()
    }

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

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


//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: u64,
    }
    if n <= 2 {
        println!("1");
        return;
    }
    let mut m = 4;
    let mut d = 1;
    while m + 1 < n {
        m = 2 * (m + 1) - d;
        d ^= 1;
    }
    if m == n || m + 1 == n {
        println!("1");
    } else {
        println!("0");
    }
}

fn main() {
    run();
}


fn main() {
    let n:i64 = {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line);
        line.trim().parse().unwrap()
    };

    if n % 2 == 0 {
        println!("{:?}", n / 2);
    } else {
        println!("{:?}", n / 2 - n);
    }
}


use std::io;
use std::cmp;

fn readstring() -> String {
    read_string_from_buffer(&io::stdin())
}

fn readint() -> i32 {
    read_int_from_buffer(&io::stdin())
}

fn read_string_from_buffer(buf: &io::Stdin) -> String {
    let mut input_text = String::new();
    buf.read_line(&mut input_text)
        .expect("failed to read from stdin");
    input_text.trim_right().to_string()
}

fn read_int_from_buffer(buf: &io::Stdin) -> i32 {
    read_string_from_buffer(buf)
        .parse::<i32>()
        .expect("couldn't parse data to an integer")
}

fn read_line_of_integers() -> Vec<i32> {
    readstring()
        .split_whitespace()
        .map(|x| x.parse::<i32>().unwrap())
        .collect()
}

fn read_line_of_longs() -> Vec<i64> {
    readstring()
        .split_whitespace()
        .map(|x| x.parse::<i64>().unwrap())
        .collect()
}

fn h(par: &mut Vec<i32>, d: &mut Vec<i32>, i: i32) -> i32 {
    if i == 1 {
        return -1;
    }
    let p = par[i as usize - 2];
    if d[i as usize - 2] == 0 {
        d[i as usize - 2] = h(par, d, p) + 1
    }
    d[i as usize - 2]
}

fn main() {
    let v = read_line_of_integers();
    let (a, b) = (cmp::min(v[0], v[1]), cmp::max(v[0], v[1]));
    if a + v[2] <= b {
        println!("{}", 2 * (a + v[2]));
    } else {
        println!("{}", 2 * b + ((v[2] - (b - a)) / 2) * 2);
    }
}


pub fn main() {
    let mut input = io::Input::new();

    let _n = input.next::<i32>();
    let s = input.next::<String>();

    let mut count = 0;

    for xxx in s.split(|c| c != 'x') {
        if xxx.len() > 2 {
            count += xxx.len() - 2;
        }
    }

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

#[allow(unused)]
pub mod io {

    const BUFFER_SIZE: usize = 8192;

    use std::collections::VecDeque;
    use std::str::FromStr;
    use std::io;
    use std::io::Read;

    type AsciiStr = Vec<u8>;

    pub struct Input {
        token_buffer: VecDeque<String>,
        remaining: String,
    }

    impl Input {

        pub fn new() -> Input {
            Input {
                token_buffer: VecDeque::with_capacity(100),
                remaining: String::new(),
            }
        }

        pub fn next<T: FromStr>(&mut self) -> T
            where T::Err: ::std::fmt::Debug
        {
            self.fill_buffer();
            self.token_buffer.pop_front().unwrap().parse().unwrap()
        }

        pub fn next_ascii_string(&mut self) -> AsciiStr {
            self.fill_buffer();
            Vec::from(self.token_buffer.pop_front().unwrap().as_bytes())
        }

        fn fill_buffer(&mut self) {
            while self.token_buffer.is_empty() {
                let mut minibuffer = [0u8; BUFFER_SIZE];
                let size = io::stdin().read(&mut minibuffer[..]).unwrap();

                self.remaining += &String::from_utf8_lossy(&minibuffer[..size]);

                if self.remaining.trim().len() > 0 {
                    for token in self.remaining.trim().split_whitespace() {
                        self.token_buffer.push_back(String::from(token))
                    }

                    if size > 0 && ! self.remaining.ends_with(|c: char|char::is_ascii_whitespace(&c)) {
                        self.remaining = self.token_buffer.pop_back().unwrap();
                    } else {
                        self.remaining.clear();
                    }

                } else if size == 0 {
                    panic!("EOF");
                }
            }
        }
    }
}


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 is_prime(x: usize) -> bool {
    for i in 2..=((x as f64).sqrt() as usize) {
        if x % i == 0 {
            return false;
        }
    }
    return true;
}

fn next_prime(x: usize) -> usize {
    let mut aux = x + 1;
    while !is_prime(aux) {
        aux += 1;
    }
    aux
}

fn _main() {
    let mut scan = Scan::new();
    let n: usize = scan.next();
    let m: usize = scan.next();
    let result = next_prime(n) == m;
    println!("{}", if result { "YES" } else { "NO" });
}

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


//spnauti-rust
#[allow(unused_macros)]
macro_rules! a {
    ($c: tt, $x: expr, $y: expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
use std::io::*;
use std::str::*;
use std::fmt::Debug;
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).unwrap();
        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 p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}

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

    let (n,d) = (input.i(), input.i());
    let sum = d - input.vp::<i32>(n as usize)
        .into_iter().sum::<i32>();
    println!("{}", if sum >= 10 * (n - 1) {
        sum / 5
    } else {
        -1
    });
}


// ---------- begin input macro ----------
// reference: 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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
// ---------- end input macro ----------

fn run() {
    input! {
        t: usize,
        ask: [(u64, u64); t],
    }
    for (n, k) in ask {
        const MOD: u64 = 1_000_000_007;
        let mut ans = 1;
        for _ in 0..k {
            ans = ans * n % MOD;
        }
        println!("{}", ans);
    }
}

fn main() {
    run();
}


#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(dead_code)]
#![allow(unused_labels)]

use std::cmp::*;
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

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

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

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

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

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

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

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

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

use std::io::*;
use std::str::FromStr;
use std::char::*;
macro_rules! debug {($($a:expr),*) => {eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);}}

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

use std::f64;

fn min<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { a }
    else { b }
}

fn max<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { b }
    else { a }
}

const MAX:usize = 30;
const INF:i64 = std::i64::MAX;
const MOD:i64 = 1e9 as i64 + 7;

struct Graph {
    e: Vec<Vec<usize>>,
    v: Vec<usize>,
    u: Vec<usize>,
    f: Vec<bool>,
    c: i64,
    flag: bool,
    vc: Vec<i64>,
}

impl Graph {
    fn new(n:usize) -> Self {
        Graph {
            e: vec![vec![];n],
            v: vec![],
            u: vec![n;n],
            f: vec![false;n],
            c: 0,
            flag: true,
            vc: vec![0;n],
        }
    }

    fn dfs(&mut self, crt: usize) {
        self.f[crt] = true;
        self.c = self.e[crt].len() as i64;
        if self.c != 2 {
            self.flag = false;
        }

        for i in 0..self.e[crt].len() {
            let v = self.e[crt][i];
            if self.f[v] { continue; }
            self.dfs(v);
        }
    }
}

fn binary_search(a: &Vec<i64>) -> usize {
    let mut left = -1;
    let mut right = a.len() as i64;

    while right - left > 1 {
        let mid:usize = ((right+left)/2) as usize;
        //debug!(left,mid,right);
        if is_ok(mid) { right = mid as i64; }
        else { left = mid as i64; }
    }
    right as usize
}

fn is_ok(key: usize) -> bool {
    true
}

fn neighbors(tree: &BTreeSet<usize>, val: usize) -> (Option<&usize>, Option<&usize>) {
    use std::ops::Bound::*;

    let mut before = tree.range((Unbounded, Excluded(val)));
    let mut after = tree.range((Excluded(val), Unbounded));

    (before.next_back(), after.next())
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}

const MAX_A:i64 = 1e16 as i64;

fn gcd(a:i64, b:i64) -> i64 {
    if b==0 {return a;}
    gcd(b, a%b)
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (let _ = write!(out,$($format)*););
    }

    input! {
        n: usize,
        a: [i64;n]
    }

    let mut ans = 0;
    let i = 0;
    if (a[i]==1 && a[i+1]==2) || (a[i]==2 && a[i+1]==1) {
        ans += 3;
    }
    else if (a[i]==1 && a[i+1]==3) || (a[i]==3 && a[i+1]==1) {
        ans += 4;
    }
    else {
        puts!("Infinite\n");
        return;
    }

    for i in 1..n-1 {
        if a[i]==1 && a[i+1]==2 {
            if a[i-1]==3 { ans += 2; }
            else { ans += 3; }
        }
        else if a[i]==2 && a[i+1]==1 {
            ans += 3;
        }
        else if a[i]==1 && a[i+1]==3 {
            ans += 4;
        }
        else if a[i]==3 && a[i+1]==1 {
            ans += 4;
        }
        else {
            puts!("Infinite\n");
            return;
        }
    }
    puts!("Finite\n");
    puts!("{}\n", ans);

}

/*

*/


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 mut res = 0usize;
    let n: usize = scan.next();
    let m: usize = scan.next();
    let limit: usize = n.max(m);
    for i in 0..=limit {
        for j in 0..=limit {
            if i * i + j == n && i + j * j == m {
                res += 1;
            }
        }
    }
    println!("{}", res);
}

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


use std::cmp::*;
use std::collections::*;
use std::io::*;
use std::str::*;

// scanner from https://codeforces.com/contest/1396/submission/91365784
struct Scanner {
    stdin: Stdin,
    buffer: VecDeque<String>,
}
#[allow(dead_code)]
impl Scanner {
    fn new() -> Self {
        Scanner {
            stdin: stdin(),
            buffer: VecDeque::new(),
        }
    }
    fn cin<T: FromStr>(&mut self) -> T {
        while self.buffer.is_empty() {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
        self.buffer.pop_front().unwrap().parse::<T>().ok().unwrap()
    }
    fn chars(&mut self) -> Vec<char> {
        self.cin::<String>().chars().collect()
    }
    fn vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.cin()).collect()
    }
    fn u(&mut self) -> usize {
        self.cin()
    }
    fn ll(&mut self) -> i64 {
        self.cin()
    }
    fn ull(&mut self) -> u64 {
        self.cin()
    }
    fn vecu(&mut self, n: usize) -> Vec<usize> {
        self.vec(n)
    }
    fn vecll(&mut self, n: usize) -> Vec<i64> {
        self.vec(n)
    }
}

#[derive(Clone, Debug, Default)]
struct Solver {}

//
// DSU
//

#[derive(Debug, Clone)]
struct DSU {
    v: Vec<usize>,
    n: usize,
}

impl DSU {
    fn new(size: usize) -> DSU {
        let mut v = vec![0; size];
        for i in 0..size {
            v[i] = i;
        }
        DSU { v: v, n: size }
    }

    fn find(&mut self, x: usize) -> usize {
        if self.v[x] == x {
            x
        } else {
            self.v[x] = self.find(self.v[x]);
            self.v[x]
        }
    }

    fn is_same(&mut self, x: usize, y: usize) -> bool {
        self.find(x) == self.find(y)
    }

    fn unify(&mut self, x: usize, y: usize) {
        let xx = self.find(x);
        let yy = self.find(y);
        if xx != yy {
            self.v[yy] = xx;
        }
    }
}

//
// Segment Tree
//

#[derive(Clone)]
struct SegmentTree<T> {
    v: Vec<T>,
    offset: usize,
    comb: fn(T, T) -> T,
    unit: T,
}

#[allow(dead_code)]
impl<T: Copy> SegmentTree<T> {
    fn new(n: usize, unit: T, comb: fn(T, T) -> T, vv: Option<&Vec<T>>) -> SegmentTree<T> {
        let mut x = 1;
        while x < n {
            x *= 2;
        }

        let mut v = vec![unit; x * 2];
        if let Some(vv) = vv {
            for i in 0..n {
                v[x + i] = (*vv)[i];
            }
            for i in (0..x).rev() {
                v[i] = comb(v[i * 2], v[i * 2 + 1]);
            }
        }

        SegmentTree {
            v: v,
            offset: x,
            comb,
            unit: unit,
        }
    }

    fn update(&mut self, pos: usize, val: T) {
        let mut p = self.offset + pos;
        self.v[p] = val;
        while p != 1 {
            p /= 2;
            self.v[p] = (self.comb)(self.v[p * 2], self.v[p * 2 + 1]);
        }
    }

    fn get(&self, pos: usize) -> T {
        self.v[self.offset + pos]
    }

    fn query_range_all(&self) -> T {
        self.query_range(0, self.offset)
    }

    fn query_range(&self, begin: usize, end: usize) -> T {
        self.query_range_sub(begin, end, 1, 0, self.offset)
    }

    // v[node] は 区間 l .. r-1 の計算結果を持っている
    fn query_range_sub(&self, begin: usize, end: usize, node: usize, l: usize, r: usize) -> T {
        if end <= l || r <= begin {
            return self.unit.clone();
        } else if begin <= l && r <= end {
            return self.v[node].clone();
        } else {
            let lval = self.query_range_sub(begin, end, node * 2, l, (l + r) / 2);
            let rval = self.query_range_sub(begin, end, node * 2 + 1, (l + r) / 2, r);
            return (self.comb)(lval, rval);
        }
    }
}

impl Solver {
    fn solve(&mut self, scan: &mut Scanner, out: &mut BufWriter<Stdout>) {
        //1416d

        let n = scan.u();
        let m = scan.u();
        let q = scan.u();
        let p = scan.vecu(n);

        let mut edges = Vec::with_capacity(m);
        for _ in 0..m {
            let x = scan.u() - 1;
            let y = scan.u() - 1;
            edges.push((x, y));
        }

        let mut vq = Vec::with_capacity(q);
        let mut vq1 = Vec::with_capacity(q); // vertex : そのグループ内の最大のpを0にする
        let mut vq2 = Vec::with_capacity(q); // edge : (edge_id, Some(r_vertex_id)) このクエリを処理するときに e_vertex_id 以降を切り離す

        let mut eid_to_q2id = vec![q; m];
        for _ in 0..q {
            let x = scan.u();
            let y = scan.u();
            vq.push(x);

            if x == 1 {
                vq1.push(y - 1);
            } else {
                eid_to_q2id[y - 1] = vq2.len();
                vq2.push((y - 1, None));
            }
        }

        /*
           エッジ削除のクエリを逆順にして、このクエリはどのグループとどのグループをくっつけるか、をDSUを使って調べる。
           x-yにエッジを追加 = (xのroot)の子として(yのroot)を追加
           x-yのエッジを削除 = (xのroot)から(yのroot)を切り離す

        */
        let mut eidq2id: Vec<(usize, usize)> = eid_to_q2id.into_iter().enumerate().collect(); // (edge_id, query2_id)
        eidq2id.sort_by_key(|x| q - x.1);

        let mut dsu = DSU::new(n);
        let mut child = vec![Vec::new(); n];
        for (edge_id, q2id) in eidq2id {
            let e = edges[edge_id];
            if !dsu.is_same(e.0, e.1) {
                let e0 = dsu.find(e.0);
                let e1 = dsu.find(e.1);
                dsu.unify(e0, e1);

                child[e0].push(e1);
                if q2id != q {
                    vq2[q2id].1 = Some(e1);
                }
            }
        }
        /*
           頂点の順番を並び替える。
           各rootからdfsで通った順にする。
           (xのroot)から(yのroot)を切り離す は、 (yのroot)の手前で分割する と同じになる
        */
        let mut pos_to_vid = Vec::with_capacity(n);
        fn dfs(vid: usize, pos_to_vid: &mut Vec<usize>, child: &Vec<Vec<usize>>) {
            pos_to_vid.push(vid);
            for &child_vid in &child[vid] {
                dfs(child_vid, pos_to_vid, child);
            }
        }

        let mut partitions = BTreeSet::new();
        partitions.insert(0);
        for i in 0..n {
            if i == dsu.find(i) {
                dfs(i, &mut pos_to_vid, &child);
            }
            partitions.insert(pos_to_vid.len());
        }

        //
        let mut vid_to_pos = vec![0; n];
        let mut v = vec![(0, 0); n];
        for pos in 0..n {
            let vid = pos_to_vid[pos];
            v[pos] = (p[vid], vid);
            vid_to_pos[vid] = pos;
        }
        let mut s = SegmentTree::new(n, (0usize, 0usize), |l, r| max(l, r), Some(&v));

        vq1.reverse();
        vq2.reverse();
        for i in 0..q {
            // for pos in 0..n {
            //     if partitions.contains(&pos) {
            //         print!("|");
            //     }
            //     let (val, vid) = s.v[s.offset + pos];
            //     print!("({} {}) ", val, vid + 1);
            // }
            // println!("");

            if vq[i] == 1 {
                let vid = vq1.pop().unwrap();
                let pos = vid_to_pos[vid];
                let lpos = partitions.range(..=pos).next_back().unwrap();
                let rpos = partitions.range(pos + 1..).next().unwrap();
                let (val2, vid2) = s.query_range(*lpos, *rpos);
                //println!("range pos{} -> {}..{}  val,vid={},{}", pos, *lpos, *rpos, val2, vid2 );
                writeln!(out, "{}", val2).ok();
                s.update(vid_to_pos[vid2], (0, vid2));
            } else {
                if let Some((_, Some(vid))) = vq2.pop() {
                    partitions.insert(vid_to_pos[vid]);
                }
            }
        }
    }
}

fn solve() {
    let mut scan = Scanner::new();
    let out = &mut BufWriter::new(stdout());

    let testcase = 1;
    //let testcase: usize = scan.cin();
    for _ in 0..testcase {
        let mut s: Solver = Default::default();
        s.solve(&mut scan, out);
    }
}

fn main() {
    let th = std::thread::Builder::new().stack_size(64 * 1024 * 1024);
    th.spawn(|| solve()).unwrap().join().unwrap()
}


use std::io::BufRead;

fn read_problem<R: BufRead>(br: R) -> Vec<usize> {
    let mut lines = br.lines();

    let node_ct: usize = str::parse(&lines.next().unwrap().unwrap()).unwrap();
    let mut nodes = Vec::<usize>::with_capacity(node_ct);
    nodes.extend(lines.next().unwrap().unwrap().split_whitespace()
                 .map(str::parse::<usize>)
                 .map(|n| n.unwrap()-1));
    assert!(nodes.len() == node_ct);
    assert!(lines.next().is_none());
    nodes
}

fn gcd(mut a: u64, mut b: u64) -> u64 {
    if a == 0 || b == 0 {
        return a | b;
    }
    let shift = (a|b).trailing_zeros();
    a >>= a.trailing_zeros();
    while b != 0 {
        b >>= b.trailing_zeros();
        if a > b {
            std::mem::swap(&mut a, &mut b);
        }
        b -= a;
    }
    return a << shift;
}

fn solve(nodes: Vec<usize>) -> u64 {
    let mut state = nodes.iter().map(|_| false).collect::<Vec<_>>();
    let mut solution = 1u64;

    // state is (cycle#,index); cycle# starts at 1; 0 is uninitialized
    for start in 0..state.len() {
        if state[start] {
            continue;
        }
        let mut index = start;
        let mut len = 0u64;
        while !state[index] {
            state[index] = true;
            index = nodes[index];
            len += 1;
        }
        if index != start {
            return 0;
        }
        if len&1 == 0 {
            len >>= 1;
        }
        solution = solution/gcd(solution,len) * len;
    }

    solution
}

fn main() {
    let stdin = std::io::stdin();
    let nodes = read_problem(stdin.lock());
    let sol = solve(nodes);
    if sol == 0 {
        println!("-1");
    } else {
        println!("{}", sol);
    }
}


use std::io::{self, Stdin};
use std::str::{self, FromStr};
use std::error::Error;

fn exec() {
    let mut sc = Scanner::new();
    let a: u64 = sc.ne();
    let b: u64 = sc.ne();
    let mut cnt = 0;
    for i in 0..64 {
        let k = (1 << i) - 1;
        for j in 0..i - 1 {
            let aim = k ^ (1 << j);
            // println!("{:b}", aim);
            if a <= aim && aim <= b {
                cnt += 1;
            }
        }
    }
    println!("{}", cnt);
}

fn main() {
    const STACK: usize = 16 * 1024 * 1024;
    let _ = std::thread::Builder::new()
        .stack_size(STACK)
        .spawn(|| { exec(); })
        .unwrap()
        .join()
        .unwrap();
}

#[allow(dead_code)]
struct Scanner {
    stdin: Stdin,
    id: usize,
    buf: Vec<u8>,
}

#[allow(dead_code)]
impl Scanner {
    fn new() -> Scanner {
        Scanner {
            stdin: io::stdin(),
            id: 0,
            buf: Vec::new(),
        }
    }
    fn next_line(&mut self) -> Option<String> {
        let mut res = String::new();
        match self.stdin.read_line(&mut res) {
            Ok(0) => None,
            Ok(_) => Some(res),
            Err(why) => panic!("error in read_line: {}", why.description()),
        }
    }
    fn next<T: FromStr>(&mut self) -> Option<T> {
        while self.buf.len() == 0 {
            self.buf = match self.next_line() {
                Some(r) => {
                    self.id = 0;
                    r.trim().as_bytes().to_owned()
                }
                None => return None,
            };
        }
        let l = self.id;
        assert!(self.buf[l] != b' ');
        let n = self.buf.len();
        let mut r = l;
        while r < n && self.buf[r] != b' ' {
            r += 1;
        }
        let res = match str::from_utf8(&self.buf[l..r]).ok().unwrap().parse::<T>() {
            Ok(s) => Some(s),
            Err(_) => {
                panic!("parse error, {:?}",
                       String::from_utf8(self.buf[l..r].to_owned()))
            }
        };
        while r < n && self.buf[r] == b' ' {
            r += 1;
        }
        if r == n {
            self.buf.clear();
        } else {
            self.id = r;
        }
        res
    }
    fn ne<T: FromStr>(&mut self) -> T {
        self.next::<T>().unwrap()
    }
}


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

pub struct Scanner<R> {
    reader: R,
    buffer: Vec<String>,
}

impl<R: io::BufRead> Scanner<R> {
    pub fn new(reader: R) -> Self {
        Self {
            reader,
            buffer: vec![],
        }
    }

    pub fn token<T: str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            self.reader.read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

fn is_prime(n: i64) -> bool {
    let mut d = 2;
    while d * d <= n {
        if n % d == 0 {
            return false;
        }
        d += 1;
    }
    true
}

fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
    let t: u32 = scan.token();
    for _ in 0..t {
        let a: i64 = scan.token();
        let b: i64 = scan.token();
        if a - b == 1 && is_prime(a + b) {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());
    solve(&mut scan, &mut out);
}


fn main() {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("input: read line failed");

    let vec = input.trim().split_whitespace().map(|item| {
        item.parse::<i32>().unwrap()
    }).collect::<Vec<i32>>();

    if vec[0] > vec[1] + vec[2] {
        println!("+");
    } else if vec[0] + vec[2] < vec[1] {
        println!("-");
    } else if vec[0] == vec[1] && vec[2] == 0 {
        println!("0");
    } else {
        println!("?");
    }
}