fn main() {
    let mut line1 = String::new();
    let mut line2 = String::new();
    std::io::stdin().read_line(&mut line1).unwrap();
    std::io::stdin().read_line(&mut line2).unwrap();
    let rev = line2.chars().rev().collect::<String>();
    println!("{}", if rev.trim() == line1.trim() { "YES" } else { "NO"});
}

use std::io;

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

    let mut second_input = String::new();
    io::stdin().read_line(&mut second_input);

    first_input = first_input.trim().parse().unwrap();
    second_input = second_input.trim().parse().unwrap();

    let second_input: String = second_input.chars().rev().collect();

    if first_input.eq(&second_input) {
        println!("YES");
    } else {
        println!("NO");
    }
}

use std::io;

fn main() {
    let mut buf1 = String::new();
    io::stdin().read_line(&mut buf1).unwrap();
    let buf1_rev = buf1.trim().chars().rev().collect::<String>();

    let mut buf2 = String::new();
    io::stdin().read_line(&mut buf2).unwrap();
    if buf2.trim() == buf1_rev {
        println!("YES");
        return;
    }
    println!("NO");
}

use std::io;

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

    let mut t = String::new();
    io::stdin().read_line(&mut t).unwrap();
    let t: String = t.chars().rev().collect();

    if s.trim() == t.trim() {
        println!("YES");
    } else {
        println!("NO");
    }
}

use std::io;

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

fn main() {

    let line1 = read_line();
    let line2 = read_line();
    let correct = line1.len() == line2.len() && line1.trim().chars().rev().zip(line2.trim().chars()).all(|(a, b)| a == b);

    print!("{}", if correct { "YES" } else { "NO" });
}

use std::io::*;

fn read<T: std::str::FromStr>(i: &mut StdinLock) -> T {
    let mut s = String::new();
    i.by_ref().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn main() {
    // initialize stdin
    let sin = std::io::stdin();
    let mut sin = sin.lock();
    let sin = &mut sin;

    let mut from: String = read(sin);
    let mut to: String = read(sin);

    let mut from = from.as_str().chars().rev();
    let mut to = to.as_str().chars();

    if from.zip(to).map(|x| x.0 != x.1).filter(|x| *x).count() == 0 {
        println!("YES")
    } else {
        println!("NO");
    }
}

fn main(){
    let mut line=String::new();
    let mut translated=String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line=line.trim().chars().rev().collect();
    std::io::stdin().read_line(&mut translated).unwrap();
    print!("{}",if translated.trim()==line{"YES"}else{"NO"});
}

fn main() {
    let word = get_input();
    let their_rev = get_input();
    let is_correct = their_rev == word.chars().rev().collect::<String>();
    println!("{}", if is_correct { "YES" } else { "NO" });

}

fn get_input() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("Failed");
    buffer.trim().to_owned()
}

fn get_input_usize() -> usize {
    get_input().parse().unwrap()
}

// https://codeforces.com/problemset/problem/41/A
use std::io;

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

    io::stdin()
        .read_line(&mut s)
        .unwrap();

    let s: String = s.trim().chars().rev().collect();

    let mut t = String::new();

    io::stdin()
        .read_line(&mut t)
        .unwrap();

    let t = t.trim();

    if s == t {
        println!("YES");
    } else {
        println!("NO");
    }

}

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

fn get_input() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("Failed");
    buffer
}

fn main() -> io::Result<()> {
    let mut input = get_input().trim().to_string();

    let mut input2 = get_input().trim().to_string();

    let res: String = input.chars().rev().collect();

    if input2 == res {
        println!("YES");
    } else {
        println!("NO");
    }

    Ok(())
}

use std::io;

fn main() {
    let mut s1 = String::new();
    let mut s2 = String::new();
    io::stdin().read_line(&mut s1).unwrap();
    io::stdin().read_line(&mut s2).unwrap();
    s1 = s1.trim().to_string();
    s2 = s2.trim().to_string();
    let n = s1.len();
    let mut flag = true;
    for i in 0..n {
        let c1 = s1.chars().nth(i);
        let c2 = s2.chars().nth(n-1-i);
        if c1 != c2 {
            flag = false;
        }
    }
    if flag {
        println!("YES");
    } else {
        println!("NO");
    }
}

fn main() {
    let first_string = read_line();
    let second_string = read_line();

    if second_string == first_string.chars().rev().collect::<String>() {
        println!("YES");
    } else {
        println!("NO");
    }

}

fn read_line() -> String {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Ошибка чтения");

    input.trim().to_string()
}

use std::str::FromStr;

fn read_str() -> String {
    let mut buffer: String = String::new();
    std::io::stdin().read_line(&mut buffer).expect("Error");
    buffer.trim().to_string()
}

fn main() {
    let (s, t): (String, String) = (read_str(), read_str());
    if s.chars().rev().collect::<String>() == t { println!("YES"); }
    else { println!("NO"); }
}

// http://codeforces.com/problemset/problem/41/A

use std::io::{Read, Write, stdin, stdout};

pub struct Scanner<U: Sized + Read> {
    pub buffer: Vec<String>,
    pub reader: U,
}
impl<U: Sized + Read> Scanner<U> {
    pub fn next_line<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();
        //     self.reader.read_to_string(&mut input).expect("Failed read");
        //     self.buffer = input.lines().rev().map(String::from).collect();
        // }
        if self.buffer.is_empty() {
            let mut input = String::new();
            self.reader.read_to_string(&mut input).expect("Failed read");
            self.buffer = input.lines().rev().map(String::from).collect();
        }
        self.buffer
            .pop()
            .unwrap()
            .parse()
            .ok()
            .expect("Failed parse")
    }

    pub fn new(reader: U) -> Self {
        Scanner {
            buffer: vec![],
            reader,
        }
    }
}

pub fn solution_of_p41a(input: &mut dyn Read, out: &mut dyn Write) {
    let mut scanner = Scanner::new(input);
    let s1 = scanner.next_line::<String>();
    let s2 = scanner.next_line::<String>();

    if is_translation(s1, s2) {
        write!(out, "YES").ok();
    } else {
        write!(out, "NO").ok();
    }
}

fn is_translation(s1: String, s2: String) -> bool {
    if s1.len() != s2.len() {
        return false;
    }
    let l = s1.len();
    for i in 0..l {
        if s1[i..=i] != s2[l - i - 1..=l - i - 1] {
            return false;
        }
    }
    true
}

fn main() {
    solution_of_p41a(&mut stdin(), &mut stdout());
}

use std::io;
use std::io::Stdin;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn main() {
    let stdin = io::stdin();
    let mut s = String::new();
    let mut t = String::new();
    read_line(&stdin, &mut s);
    read_line(&stdin, &mut t);
    let mut c_s = s.trim().chars();
    let mut c_t = t.trim().chars();
    let mut is_translation = false;
    loop {
        let x_s = c_s.next();
        let x_t = c_t.next_back();
        if x_s.is_none() && x_t.is_none() {
            is_translation = true;
            break;
        } else if x_s.is_some() && x_t.is_some() {
            let u_x_s = x_s.unwrap();
            let u_x_t = x_t.unwrap();
            if u_x_s == u_x_t {
                // Do nothing ...
            } else {
                break;
            }
        } else {
            break;
        }
    }
    if is_translation {
        println!("YES");
    } else {
        println!("NO");
    }
}

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

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

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

fn main() {
    input! {
        s : String,
        t : String,
    };
    let s: Vec<char> = s.chars().collect();
    let t: Vec<char> = t.chars().rev().collect();
    let n = s.len();
    for i in 0..n {
        if s.get(i) != t.get(i) {
            println!("NO");
            return;
        }
    }
    println!("YES");
}

fn readln() -> String {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();

    line
}

fn main() {
    let s = readln();
    let t = readln();

    let s = String::from(s.trim());
    let t:String = String::from(t.trim()).chars().rev().collect();

    println!("{}", if s == t {"YES"} else {"NO"});
}

use std::io;

fn main() {
	let mut word = String::new();
	io::stdin().read_line(&mut word).unwrap();
	let word = word.trim();

	let mut translation = String::new();
	io::stdin().read_line(&mut translation).unwrap();
	let translation = translation.trim();

	if translation == word.chars().rev().collect::<String>() {
		println!("YES");
	} else {
		println!("NO");
	}
}

#![allow(non_snake_case, unused_imports)]

// Input 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)*} }; }
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)*} }; }
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, [ $t:tt ]) => { { let len = read_value!($next, usize); (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>() } }; ($next:expr, chars) => { read_value!($next, String).chars().collect::<Vec<char>>() }; ($next:expr, bytes) => { read_value!($next, String).into_bytes() }; ($next:expr, usize1) => { read_value!($next, usize) - 1 }; ($next:expr, $t:ty) => { $next().parse::<$t>().expect("Parse error") }; }

// Module
use std::cmp::{min,max};
use std::collections::{HashSet,HashMap,VecDeque,BinaryHeap};

// Functions

// Main
fn main(){

    input!{
        S: chars,
        T: chars
    }

    let mut ans = "YES";
    for i in 0..S.len(){
        if S[i] != T[T.len()-1-i]{
            ans = "NO";
            break;
        }
    }

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

use std::io;

fn main() {
    let mut first = String::new();
    io::stdin().read_line(&mut first).unwrap();
    first = first.trim().to_string();
    let mut second = String::new();
    io::stdin().read_line(&mut second).unwrap();
    second = second.trim().chars().rev().collect();

    if first.contains(&second) {
        println!("YES");
    } else {
        println!("NO");
    }
}

use std::io;

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

fn main() {
    let s = read_line();
    let t = read_line().chars().rev().collect::<String>();

    if s == t {
        println!("YES");
    } else {
        println!("NO");
    }

}

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 a = scan.next::<String>();
	let b = scan.next::<String>();
    let c = a.chars().rev().collect::<String>();

    writeln!(out, "{}", if b == c { "YES" } else { "NO" }).expect("fail");
}

fn main() {
    // The input text need to be translated
    let mut s = String::new();
    let mut t = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    std::io::stdin().read_line(&mut t).unwrap();

    let vs: Vec<char> = s.trim().chars().collect();
    let vt: Vec<char> = t.trim().chars().collect();

    let mut b: bool = true;
    if vs.len() != vt.len() {
        b = false;
    } else {
        // Check duplicate characters
        let mut p: usize = 0;
        let mut q: usize = vt.len() - 1;
        loop {
            if vs[p] != vt[q] {
                b = false;
                break;
            }

            if p >= vs.len() || q <= 0 {
                break;
            }

            p += 1;
            q -= 1;
        }
    }

    // Display the result
    if b {
        println!("YES");
    } else {
        println!("NO");
    }
}

//! http://codeforces.com/contest/41/problem/A

#[macro_export]
macro_rules! scanln {
  ($($var:ident : $ty:path),+) => {
    $(let $var: $ty;)+
    {
      use std::io;
      let mut __buf = String::new();
      io::stdin().read_line(&mut __buf).unwrap();
      let mut eles = __buf.split_whitespace();
      $($var = Scan::scan(&mut eles);)+
    }
  }
}

pub trait Scan {
  fn scan<'a, I>(eles: &mut I) -> Self where I: Iterator<Item=&'a str>;
}

macro_rules! impl_scan_single {
  ($ty:ty) => {
    impl Scan for $ty {
      fn scan<'a, I>(eles: &mut I) -> Self where I: Iterator<Item=&'a str> {
        let next = eles.next().unwrap();
        match next.parse() {
          Ok(res) => res,
          Err(_) => panic!()
        }
      }
    }
  }
}

impl_scan_single!(u8);
impl_scan_single!(u16);
impl_scan_single!(u32);
impl_scan_single!(u64);
impl_scan_single!(usize);
impl_scan_single!(i8);
impl_scan_single!(i16);
impl_scan_single!(i32);
impl_scan_single!(i64);
impl_scan_single!(isize);
impl_scan_single!(String);

const __IMPL_SCAN_FOR_VEC: () = {
  use std::str::FromStr;
  impl<T> Scan for Vec<T> where T: FromStr {
    fn scan<'a, I>(eles: &mut I) -> Self where I: Iterator<Item=&'a str> {
      eles.map(|str| match str.parse() {
        Ok(res) => res,
        Err(_) => panic!()
      }).collect()
    }
  }
};

// -----------------------------------------------------------------------------

fn main() {
  scanln!(s: String);
  scanln!(t: String);
  let v: String = t.chars().rev().collect();
  println!("{}",
    if &s == &v {
      "YES"
    } else {
      "NO"
    }
  );
}

#[allow(unused)] use std::io::*;
#[allow(unused)] use std::collections::*;
#[allow(unused)] use std::mem::*;
#[allow(unused)] use std::num::*;
#[allow(unused)] use std::cmp::*;
#[allow(unused)] fn strarr() -> Vec<String> {
    let mut inp = String::new();
    stdin().read_line(&mut inp).ok();
    inp.split(' ').map(|x| x.trim()).filter(|x| x.len() != 0).map(|x| x.to_string()).collect() }
#[allow(unused)] macro_rules! scan { ($($x:ty), +) => {{
    let s = strarr(); let mut cnt : usize = 0;
    fn next<T>(cnt: &mut usize, p: &Vec<String>) -> T
        where T:std::str::FromStr
        { *cnt += 1; p[*cnt-1].parse().ok().unwrap() }
    ($(next::<$x>(&mut cnt, &s)), +)
    }}; }
#[allow(unused)] macro_rules! arr { ($n:expr, $T:ty) => {{
    let mut s = strarr(); let mut v = Vec::new();
    for i in 0..$n { v.push(s[i as usize].parse::<$T>().unwrap()); } v
    }}; }

///////////////////////////////////////////////////////////////////////////////

fn main()
{
    let s = scan!(String);
    let t = scan!(String);
    println!("{}", if s.chars().rev().collect::<Vec<char>>() == t.chars().collect::<Vec<char>>() { "YES" } else { "NO" });
}

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

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

    io::stdin().read_line(&mut s).expect("failed to read");
    io::stdin().read_line(&mut t).expect("failed to read");

    s = s.trim().to_string();
    t = t.trim().to_string();

    if s.len() != t.len() {
        print!("NO");
        io::stdout().flush().expect("failed to flush");
        return;
    }
    for i in 0..(s.len()) {
        let char_s = &s[i..(i + 1)];
        let char_t = &t[(t.len() - i - 1)..(t.len() - i)];
        if char_s != char_t {
            print!("NO");
            io::stdout().flush().expect("failed to flush");
            return;
        }
    }

    print!("YES");
    io::stdout().flush().expect("failed to flush");
}

use std::io;

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

fn main() {
    let (t, s) = (input(), input());
    if t == s.chars().rev().collect::<String>() {
        println!("YES");
    } else {
        println!("NO");
    }
}

//spnauti-rust
#[allow(unused_imports)]
use std::io::{self,Read};

struct WordReader {
    it : std::vec::IntoIter<String>,
}
#[allow(dead_code)]
impl WordReader {
    fn new<T : Read>(mut reader : T) -> WordReader {
        let mut s = String::new();
        reader.read_to_string(&mut s).unwrap();
        WordReader { it : s
            .split_ascii_whitespace()
            .map(String::from).collect::<Vec<_>>()
            .into_iter()
        }
    }
    fn from_stdin() -> WordReader {
        WordReader::new(std::io::stdin())
    }
    fn s(&mut self) -> String {
        self.it.next().unwrap()
    }
    fn ab(&mut self) -> Vec<u8> {
        self.it.next().unwrap().into_bytes()
    }
    fn i(&mut self) -> i32 {
        self.it.next().unwrap().parse().unwrap()
    }
}

fn main() {
    let mut input = WordReader::from_stdin();
    if input.s() == input.s().chars().rev().collect::<String>() {
        println!("YES");
    } else {
        println!("NO");
    }
}

fn main() {
    let mut s1 = String::new();
    std::io::stdin().read_line(&mut s1);
    let s1 = s1.trim();

    let mut s2 = String::new();
    std::io::stdin().read_line(&mut s2);
    let s2 = s2.trim();

    let s1_reversed: String = s1.chars().rev().collect();
    if s1_reversed.eq(s2) {
        println!("YES");
    } else {
        println!("NO");
    }
}

use std::io;

fn main() {

    let mut input = String::new();
    io::stdin().read_line(&mut input);

    let vector: Vec<&str> = input.split("\n").collect();
    let second_vector: String = vector[1].chars().rev().collect();

    if vector[0].to_string().eq(&second_vector) {
        println!("YES");
    } else {
        println!("NO");
    }

}

use std::io;

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

    let vector: Vec<&str> = input.split("\r\n").collect();
    let first_vector = vector[0].to_string();
    let second_vector: String = vector[1].trim().chars().rev().collect();

    //println!("{:?}", vector);

    if first_vector.eq(&second_vector) {
        println!("YES");
    } else {
        println!("NO");
    }
}

use std::io;

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

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

    if x.len() <= 100 && !x.contains(" ") {
        let v: Vec<&str> = x.split("\n").collect();

        let mut z: String = String::from("");
        let mut index = 0;
        let mut a: &str = "";

        for y in v {
            if index == 0 {
                z = y.chars().rev().collect();
                index += 1;
            } else {
                a = y;
            }
        }

        if !z.eq_ignore_ascii_case(a) {
            println!("YES");
        } else {
            println!("NO");
        }

    }

}

use std::io;

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

    let vector: Vec<&str> = input.split("\r").collect();
    let first_vector = vector[0].to_string();
    let second_vector: String = vector[1].trim_start().chars().rev().collect();

    if first_vector.eq(&second_vector) {
        println!("YES");
    } else {
        println!("NO");
    }
}

use std::io;

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

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

    if x.len() <= 100 && !x.contains(" ") {
        let v: Vec<&str> = x.split("\n").collect();

        let mut z: String = String::from("");
        let mut index = 0;
        let mut a: &str = "";

        for y in v {
            if index == 0 {
                z = y.chars().rev().collect();
                index += 1;
            } else {
                a = y;
            }
        }

        let g = z.as_str();

        if !z.eq_ignore_ascii_case(a) && g.eq_ignore_ascii_case(a) {
                println!("YES");
        } else {
            println!("NO");
        }

    }

}

use std::io;

fn main() {

    let mut string = String::new();
    io::stdin().read_line(&mut string);

    let vector: Vec<&str> = string.split("\n").collect();
    let second_vector: String = vector[1].chars().rev().collect();

    if vector[0].to_string().eq(&second_vector) {
        println!("YES");
    } else {
        println!("NO {} - {}", vector[0], second_vector);
    }

}

use std::io;

fn main() {

    let mut string = String::new();
    io::stdin().read_line(&mut string);

    let vector: Vec<&str> = string.split("\n").collect();
    let second_vector: String = vector[1].chars().rev().collect();

    if vector[0].to_string().eq(&second_vector) {
        println!("YES");
    } else {
        println!("NO");
    }

}

use std::io;

fn main() {

    let mut input = String::new();
    io::stdin().read_line(&mut input);

    let vector: Vec<&str> = input.split("\n").collect();
    let second_vector: String = vector[1].trim().chars().rev().collect();

    if vector[0].trim().to_string().eq(&second_vector) {
        println!("YES");
    } else {
        println!("NO");
    }

}

use std::io;

fn main() {

    let mut string = String::new();
    io::stdin().read_line(&mut string);

    let vector: Vec<&str> = string.split("\n").collect();

    if vector[1].chars().eq(vector[0].chars().rev()) {
        println!("YES");
    } else {
        println!("NO");
    }

}

use std::io;

fn main() {

    let mut input = String::new();
    io::stdin().read_line(&mut input);

    let vector: Vec<&str> = input.split("\n").collect();
    let first_vector = vector[0].to_string();
    let second_vector: String = vector[1].trim().chars().rev().collect();

    if first_vector.eq(&second_vector) {
        println!("YES");
    } else {
        println!("NO");
    }

    println!("{:?}", vector);

    println!("1. {}", first_vector);
    println!("2. {}", second_vector);
}

use std::io;

fn main() {

    let mut string = String::new();
    io::stdin().read_line(&mut string);

    let vector: Vec<&str> = string.split("\n").collect();
    let second_vector: String = vector[1].chars().rev().collect();

    if vector[0].to_string().eq(&second_vector) {
        println!("YES");
    } else {
        println!("NO {} - {}", vector[0], vector[1]);
    }

    println!("{:?}", vector);
}


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

    let mut input = input.trim().split(' ');
    let mut shoes = [i32::default();2];
    shoes[0] = input.next().unwrap().parse::<i32>().unwrap();
    shoes[1] = input.next().unwrap().parse::<i32>().unwrap();

    if shoes[0] > shoes[1] {
        shoes.swap(0, 1);
    }

    let fashion = shoes[0];
    let normal = (shoes[1] - fashion) / 2;

    println!("{} {}", fashion, normal);

}

use std::cmp::{max, min};
use std::io::stdin;

pub fn main() {
    let (red, blue) = {
        let mut buf = String::new();
        stdin().read_line(&mut buf).unwrap();
        let a: Vec<i32> = buf
            .trim()
            .split_ascii_whitespace()
            .map(|c| c.parse().unwrap())
            .collect();
        (a[0], a[1])
    };
    let hip_pairs = min(red, blue);
    let normal_pairs = (max(red, blue) - hip_pairs) / 2;
    println!("{} {}", hip_pairs, normal_pairs);
}

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

fn main() {
    let input = input_pair();
    let (r, b) = (input[0], input[1]);
    let s = r.min(b);
    let l = (r.max(b) - s) / 2;
    println!("{} {}", s, l);
}

type Pair = (u8, u8);
fn input_pair() -> Pair {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    let buf: Vec<u8> = buf.trim().split_whitespace().map(|elem| elem.parse().unwrap()).collect();
    (buf[0], buf[1])
}

fn main() {
    let (r, b) = input_pair();
    println!("{} {}", r.min(b), (r.max(b) - r.min(b)) / 2);
}

//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 }
    }};
}
struct WordReader {
    it : std::vec::IntoIter<String>,
}
#[allow(dead_code)]
impl WordReader {
    fn new<T: std::io::Read>(mut reader: T) -> WordReader {
        let mut s = String::new();
        reader.read_to_string(&mut s).unwrap();
        WordReader {
            it : s.split_ascii_whitespace().map(String::from)
            .collect::<Vec<_>>().into_iter()
        }
    }
    fn from_stdin() -> WordReader {
        WordReader::new(std::io::stdin())
    }
    fn s(&mut self) -> String {
        self.it.next().unwrap()
    }
    fn ab(&mut self) -> Vec<u8> {
        self.it.next().unwrap().into_bytes()
    }
    fn i(&mut self) -> i32 {
        self.it.next().unwrap().parse().unwrap()
    }
    fn ai(&mut self, n: usize) -> Vec<i32> {
        let mut a = Vec::with_capacity(n);
        for _ in 0..n { a.push(self.i()); }
        a
    }
}

fn main() {
    let mut input = WordReader::from_stdin();
    let a = input.i();
    let b = input.i();
    let min = std::cmp::min(a, b);
    println!("{} {}", min, (a + b - 2 * min) / 2);
}

macro_rules! readln {
    () => {{
        use std::io;

        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();
        buf.trim().to_string()
    }};
    ( $t:ty ) => {{
        let input = readln!();
        input.parse::<$t>().unwrap()
    }};
    ( $( $t:ty ),+ ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        (
            $(
                input.next().unwrap().parse::<$t>().unwrap(),
            )+
        )
    }}
}

macro_rules! readvec {
    ( $t:ty ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        let mut result = Vec::new();
        for elem in input {
            result.push(elem.parse::<$t>().unwrap());
        }
        result
    }}
}

fn main() {
    let (a,b) = readln!(i32,i32);
    println!("{} {}",std::cmp::min(a,b),(a+b-std::cmp::min(a,b)*2)/2);
}

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

fn main() {
    let stdin = io::stdin();
    let mut iterator = stdin.lock().lines();
    let line: String;
    let numbers: Vec<i32>;
    let (min, max): (i32, i32);

    line = iterator.next().unwrap().unwrap();
    numbers = line
        .split_whitespace()
        .map(|n| n.parse().unwrap())
        .collect();

    match numbers.iter().min() {
        Some(number) => min = *number,
        None => min = 0,
    }
    match numbers.iter().max() {
        Some(number) => max = *number,
        None => max = 0,
    }

    println!("{} {}", min, (max-min)/2);
}

use std::io::stdin;
fn main() {
	let mut s = String::new();
	stdin().read_line(&mut s).unwrap();
	let a: Vec<i64> = s
		.split_whitespace()
		.map(|x| x.parse().unwrap())
		.collect();
	println!("{} {}", std::cmp::min(a[0], a[1]), (a[0] - a[1]).abs()/2)
}

// {{{ by shik

use std::io;

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

#[allow(unused_macros)]
macro_rules! R {
    ( $ty:ty, ... ) => {
        gets().split_whitespace().map(|x| x.parse::<$ty>().unwrap()).collect::<Vec<_>>()
    };
    ( $($ty:ty),* ) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        ( $(it.next().unwrap().parse::<$ty>().unwrap(),)* )
    }}
}

#[allow(unused_macros)]
macro_rules! W {
    ( $x:expr ) => {{
        println!("{}", $x);
    }};
    ( $x:expr, $($xs:expr),* ) => {{
        print!("{} ", $x);
        W!($($xs),*);
    }}
}

#[allow(unused_macros)]
macro_rules! join {
    ($x:expr, $($xs:expr),*; $sep:expr) => { concat!($x, $($sep, $xs),*) }
}

#[allow(unused_macros)]
macro_rules! dump {
    ($($x:expr),*) => {
        eprintln!(join!($(concat!(stringify!($x), " = {:?}")),*; ", "), $($x),*);
    }
}

// }}}

use std::cmp;

fn main() {

    let (a, b) = R!(usize, usize);

    println!("{} {}", cmp::min(a, b), (cmp::max(a, b) - cmp::min(a, b)) / 2);

}

use std::error::Error;
use std::io;

fn get_line() -> io::Result<String> {
	let mut buffer = String::new();
	io::stdin().read_line(&mut buffer)?;
	Ok(buffer)
}

fn main() -> Result<(), Box<dyn Error>> {
	let input = get_line()?
		.split_whitespace()
		.map(|s| s.parse::<u32>())
		.collect::<Result<Vec<_>, _>>()?;
	let diff = input[0].min(input[1]);
	let same = (input[0].max(input[1]) - diff) / 2;
	print!("{} {}", diff, same);
	Ok(())
}

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 main() {
    input! {
        red_socks: u32,
        blue_socks: u32,
    }

    let x = std::cmp::min(red_socks, blue_socks);
    let y = ((red_socks - x) + (blue_socks - x)) / 2;

    println!("{} {}", x, y)
}

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

fn main() {
    let reader = io::stdin();

    let parts:Vec<i8> =
            reader.lock()
            .lines().next().unwrap().unwrap()
            .split_whitespace()
            .filter(|s| !s.is_empty())
            .map(|s| s.parse::<i8>().unwrap())
            .collect();

    let a:i8 = parts[0];
    let b:i8 = parts[1];

    println!("{} {}", cmp::min(a, b), (a-b).abs() / 2 );

}

// https://codeforces.com/problemset/problem/581/A
use std::io;

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

    io::stdin()
        .read_line(&mut line)
        .unwrap();

    let words: Vec<i64> =
        line
        .split_whitespace()
        .map(|x| x.parse().unwrap())
        .collect();

    let a = words[0];
    let b = words[1];

    println!("{} {}", std::cmp::min(a,b), i64::abs((a-b)/2));
}

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

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    let arr : Vec<i32> = s.split_whitespace().map(|s| s.parse().unwrap()).collect();
    let (a, b, x) = (arr[0], arr[1], cmp::min(arr[0], arr[1]));
    println!("{} {}", x, (a + b - 2 * x) / 2);
}

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 a: usize = scan.next();
    let b: usize = scan.next();
    let result1 = a.min(b);
    let result2 = (a.max(b) - result1) / 2;
    println!("{} {}", result1, result2);
}

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

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

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s)
        .expect("failed to read l2");

    let values = s
        .split_whitespace()
        .map(|x| x.parse::<i32>())
        .collect::<Result<Vec<i32>, _>>()
        .unwrap();

    assert!(values.len() == 2);
    let a = values[0];
    let b = values[1];

    let min = cmp::min(a,b);
    let rest_same_color_pairs = (cmp::max(a,b) - min) / 2;

    println!("{} {}", min, rest_same_color_pairs);
}

use std::io;

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

fn read_line_vec() -> Vec<i64> {
    return read_line().split(' ')
        .map(|s| s.parse().unwrap())
        .collect();
}

fn read_line_pair() -> (i64, i64) {
    let vec = read_line_vec();
    return (vec[0], vec[1]);
}

fn main() {

    let (a, b) = read_line_pair();

    let p1 = std::cmp::min(a, b);
    let p2 = ((a + b) - p1 - p1) / 2;

    println!("{} {}", p1, p2);

}


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

fn read_line() -> String {
    let mut buf = String::new();
    stdin().read_line(&mut buf).expect("Failed to read a line");
    buf
}

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

fn read_vector<T>() -> Vec<T>
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    read_line().trim().split_whitespace().map(|x| x.parse::<T>().unwrap()).collect()
}

fn calculate_min_max_pairs(n: u64, m: u64) -> (u64, u64) {
    let get_pair_count = |x| x * (x - 1) / 2;
    let max_count = get_pair_count(n - m + 1);
    let (d, r) = (n / m, n % m);
    let min_count = (m - r) * get_pair_count(d) + r * get_pair_count(d + 1);
    (min_count, max_count)
}

fn main() {
    let (n, m) = {
        let v = read_vector::<u64>();
        (v[0], v[1])
    };
    let result = calculate_min_max_pairs(n, m);
    println!("{} {}", result.0, result.1);
}

//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 mut bout = BufWriter::new(stdout());

    let f = |n,x| x * n * (n - 1) / 2;
    let n: i64 = input.p();
    let m: i64 = input.p();
    let r = n % m;
    writeln!(bout, "{} {}", f(n/m, m-r) + f(n/m+1, r), f(n-m+1, 1)).ok();
}

#[allow(unused_imports)]
use std::cmp::{max,min};
#[allow(unused_imports)]
use std::collections::HashMap;

#[allow(unused_macros)]
macro_rules! readln {
    () => {{
        use std::io;

        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();
        buf.trim().to_string()
    }};
    ( $t:ty ) => {{
        let input = readln!();
        input.parse::<$t>().unwrap()
    }};
    ( $( $t:ty ),+ ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        (
            $(
                input.next().unwrap().parse::<$t>().unwrap(),
            )+
        )
    }}
}

#[allow(unused_macros)]
macro_rules! readvec {
    ( $t:ty ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        let mut result = Vec::new();
        for elem in input {
            result.push(elem.parse::<$t>().unwrap());
        }
        result
    }}
}

fn foo(x : i32) -> i64 {
    let x : i64 = x as i64;
    return (x*(x-1))/2;
}

fn main() {
    let (n,m) = readln!(i32,i32);
    let a1 = foo(n-m+1);
    let r = n%m;
    let q = n/m;
    let a2 = r as i64*foo(q+1) + (m-r) as i64 *foo(q);
    println!("{} {}",a2,a1);
}

fn c2 (x:i64) -> i64 { let y=x as i64; y * (y-1)/2 }

fn main() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut ints = s.split_whitespace().map(|x| x.parse::<i64>().unwrap());
    let n = ints.next().unwrap();
    let t = ints.next().unwrap();
    if n == t {
        println!("0 0");
    } else {
        let max = c2(n - t + 1);
        let a = n/t;
        let b = n%t;
        let min = b*c2(a+1)+(t-b)*c2(a);
        println!("{} {}",min, max);
  }

}

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: u64 = scan.next();
    let m: u64 = scan.next();
    let maxcalc = (n-m+1) * (n-m) / 2;
    let minval1 = n/m + 1;
    let minval2 = n/m;
    let minn1 = n%m;
    let minn2 = m - minn1;
    let mincalc = (minval1*(minval1-1)/2)*minn1
        + (minval2*(minval2-1)/2)*minn2;
    println!("{} {}", mincalc, maxcalc);
}

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

fn solve() {
    let (n, m): (i64, i64) = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        let mut ws = buf.split_whitespace();
        let n = ws.next().unwrap().parse().unwrap();
        let m = ws.next().unwrap().parse().unwrap();
        (n, m)
    };

    let min = {
        let a = n / m;
        let b = n - a * m;
        (a + 1) * a / 2 * b + a * (a - 1) / 2 * (m - b)
    };

    let max = {
        let t = n - (m - 1);
        t * (t - 1) / 2
    };

    println!("{} {}", min, max);
}

fn main() {
    // let t: u32 = {
    //     let mut buf = String::new();
    //     std::io::stdin().read_line(&mut buf).unwrap();
    //     buf.trim_end().parse().unwrap()
    // };

    // for _ in 0..t {}
    solve();
}

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: u64 = scan.next();
    let m: u64 = scan.next();
    if n == m {
        println!("{} {}", m, m);
        return;
    }
    let maxcalc = (n-m+1) * (n-m) / 2;
    let minval1 = n/m + 1;
    let minval2 = n/m;
    let minn1 = n%m;
    let minn2 = m - minn1;
    let mincalc = (minval1*(minval1-1)/2)*minn1
        + (minval2*(minval2-1)/2)*minn2;
    println!("{} {}", mincalc, maxcalc);
}

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


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
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")
    };
}

/// Verified by https://atcoder.jp/contests/arc093/submissions/3968098
mod mod_int {
    use std::ops::*;
    pub trait Mod: Copy { fn m() -> i64; }
    #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
    pub struct ModInt<M> { pub x: i64, phantom: ::std::marker::PhantomData<M> }
    impl<M: Mod> ModInt<M> {
        // x >= 0
        pub fn new(x: i64) -> Self { ModInt::new_internal(x % M::m()) }
        fn new_internal(x: i64) -> Self {
            ModInt { x: x, phantom: ::std::marker::PhantomData }
        }
        pub fn pow(self, mut e: i64) -> Self {
            debug_assert!(e >= 0);
            let mut sum = ModInt::new_internal(1);
            let mut cur = self;
            while e > 0 {
                if e % 2 != 0 { sum *= cur; }
                cur *= cur;
                e /= 2;
            }
            sum
        }
        #[allow(dead_code)]
        pub fn inv(self) -> Self { self.pow(M::m() - 2) }
    }
    impl<M: Mod, T: Into<ModInt<M>>> Add<T> for ModInt<M> {
        type Output = Self;
        fn add(self, other: T) -> Self {
            let other = other.into();
            let mut sum = self.x + other.x;
            if sum >= M::m() { sum -= M::m(); }
            ModInt::new_internal(sum)
        }
    }
    impl<M: Mod, T: Into<ModInt<M>>> Sub<T> for ModInt<M> {
        type Output = Self;
        fn sub(self, other: T) -> Self {
            let other = other.into();
            let mut sum = self.x - other.x;
            if sum < 0 { sum += M::m(); }
            ModInt::new_internal(sum)
        }
    }
    impl<M: Mod, T: Into<ModInt<M>>> Mul<T> for ModInt<M> {
        type Output = Self;
        fn mul(self, other: T) -> Self { ModInt::new(self.x * other.into().x % M::m()) }
    }
    impl<M: Mod, T: Into<ModInt<M>>> AddAssign<T> for ModInt<M> {
        fn add_assign(&mut self, other: T) { *self = *self + other; }
    }
    impl<M: Mod, T: Into<ModInt<M>>> SubAssign<T> for ModInt<M> {
        fn sub_assign(&mut self, other: T) { *self = *self - other; }
    }
    impl<M: Mod, T: Into<ModInt<M>>> MulAssign<T> for ModInt<M> {
        fn mul_assign(&mut self, other: T) { *self = *self * other; }
    }
    impl<M: Mod> Neg for ModInt<M> {
        type Output = Self;
        fn neg(self) -> Self { ModInt::new(0) - self }
    }
    impl<M> ::std::fmt::Display for ModInt<M> {
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
            self.x.fmt(f)
        }
    }
    impl<M> ::std::fmt::Debug for ModInt<M> {
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
            self.x.fmt(f)
        }
    }
    impl<M: Mod> From<i64> for ModInt<M> {
        fn from(x: i64) -> Self { Self::new(x) }
    }
} // mod mod_int

macro_rules! define_mod {
    ($struct_name: ident, $modulo: expr) => {
        #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
        struct $struct_name {}
        impl mod_int::Mod for $struct_name { fn m() -> i64 { $modulo } }
    }
}
const MOD: i64 = 998244353;
define_mod!(P, MOD);
type ModInt = mod_int::ModInt<P>;

/// FFT (in-place, verified as NTT only)
/// R: Ring + Copy
/// Verified by: https://codeforces.com/contest/1096/submission/47672373
mod fft {
    use std::ops::*;
    /// n should be a power of 2. zeta is a primitive n-th root of unity.
    /// one is unity
    /// Note that the result should be multiplied by 1/sqrt(n).
    pub fn transform<R>(f: &mut [R], zeta: R, one: R)
        where R: Copy +
        Add<Output = R> +
        Sub<Output = R> +
        Mul<Output = R> {
        let n = f.len();
        assert!(n.is_power_of_two());
        {
            let mut i = 0;
            for j in 1 .. n - 1 {
                let mut k = n >> 1;
                loop {
                    i ^= k;
                    if k <= i { break; }
                    k >>= 1;
                }
                if j < i { f.swap(i, j); }
            }
        }
        let mut zetapow = Vec::new();
        {
            let mut m = 1;
            let mut cur = zeta;
            while m < n {
                zetapow.push(cur);
                cur = cur * cur;
                m *= 2;
            }
        }
        let mut m = 1;
        while m < n {
            let base = zetapow.pop().unwrap();
            let mut r = 0;
            while r < n {
                let mut w = one;
                for s in r .. r + m {
                    let u = f[s];
                    let d = f[s + m] * w;
                    f[s] = u + d;
                    f[s + m] = u - d;
                    w = w * base;
                }
                r += 2 * m;
            }
            m *= 2;
        }
    }
}

use fft::*;

// Depends on ModInt.rs
fn fact_init(w: usize) -> (Vec<ModInt>, Vec<ModInt>) {
    let mut fac = vec![ModInt::new(1); w];
    let mut invfac = vec![0.into(); w];
    for i in 1 .. w {
        fac[i] = fac[i - 1] * i as i64;
    }
    invfac[w - 1] = fac[w - 1].inv();
    for i in (0 .. w - 1).rev() {
        invfac[i] = invfac[i + 1] * (i as i64 + 1);
    }
    (fac, invfac)
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (write!(out,$($format)*).unwrap());
    }
    input! {
        n: usize,
        k: usize,
        l: i64,
    }
    const N: usize = 4096;
    let (fac, invfac) = fact_init(N);

    let mut p = vec![ModInt::new(0); N];
    let mut q = vec![ModInt::new(0); N];
    p[1] = ModInt::new(2);
    p[2] = -ModInt::new(2);
    q[0] = ModInt::new(1);
    q[1] = -ModInt::new(2);
    q[2] = ModInt::new(2);

    let zeta = ModInt::new(3).pow((MOD - 1) / N as i64);
    transform(&mut p, zeta, ModInt::new(1));
    transform(&mut q, zeta, ModInt::new(1));

    let mut ans = vec![ModInt::new(0); N];
    let mut coef = vec![ModInt::new(0); N];
    for i in k..n + 1 {
        coef[i] = fac[n] * invfac[n - i] * invfac[i];
    }
    for j in 0..N {
        let mut pp = p[j].pow(k as i64);
        let mut qp = q[j].pow((n - k) as i64);
        let mut qinv = q[j].inv();
        for i in k..n + 1 {
            let coef = coef[i];
            ans[j] += pp * qp * coef;
            pp *= p[j];
            qp *= qinv;
        }
    }
    transform(&mut ans, zeta.inv(), ModInt::new(1));
    // eprintln!("ans = {:?}", &ans[0..10]);
    let mut tot = ModInt::new(0);
    for i in 0..2 * n + 1 {
        tot += ans[i] * ModInt::new((i + 1) as i64).inv();
    }
    tot *= ModInt::new(N as i64).inv();
    puts!("{}\n", tot * l);
}

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

// ---------- begin ModInt ----------
const MOD: u32 = 998_244_353;

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

impl std::ops::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 std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl std::ops::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 std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

impl std::ops::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 std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, rhs: ModInt) {
        *self = *self * rhs;
    }
}

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

/*
impl std::fmt::Display for ModInt {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", 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 n: usize = it.next().unwrap().parse().unwrap();
    let k: usize = it.next().unwrap().parse().unwrap();
    let l: u32 = it.next().unwrap().parse().unwrap();
    let pc = Precalc::new(2 * n + 1);
    let mut dp = vec![ModInt::zero(); 2 * n + 1];
    dp[0] = ModInt::one();
    for i in 0..n {
        for j in (0..=(2 * i)).rev() {
            let p = dp[j];
            dp[j + 2] -= ModInt(2) * p;
            dp[j + 1] += ModInt(2) * p;
            dp[j] = ModInt(0);
        }
    }
    let mut ans = ModInt::zero();
    for i in (k..=n).rev() {
        let mut eval = ModInt::zero();
        for j in 0..=(2 * n) {
            eval += dp[j] * pc.inv(j + 1)
        }
        ans += pc.comb(n, i) * eval;
        let f = ModInt(2).inv();
        let mut next = vec![ModInt::zero(); 2 * n + 1];
        for j in (2..=(2 * n)).rev() {
            let v = dp[j];
            dp[j - 1] += v;
            next[j - 2] = -v * f;
        }
        dp = next;
        for j in (0..=(2 * (n - 1))).rev() {
            let v = dp[j];
            dp[j + 2] += ModInt(2) * v;
            dp[j + 1] -= ModInt(2) * v;
        }
    }
    ans *= ModInt(l);
    println!("{}", ans.0);
}

fn main() {
    run();
}


use std::io;

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

    let a: Vec<u32> = {
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();
        input.split_whitespace().map(|k| k.parse().unwrap()).collect()
    };

    let ans = n % 2 == 1 && a.first().unwrap() % 2 == 1 && a.last().unwrap() % 2 == 1;

    if ans {
        println!("Yes");
    } else {
        println!("No");
    }
}

#![allow(unused_imports)]
use std::io::{self, BufRead};
use std::cmp::*;
use std::collections::*;

macro_rules! scan_to_vec {
    ($count:expr, $t:ty) => ({
        let mut result = Vec::new();
        let stdin = io::stdin();
        let mut handle = stdin.lock();

        for _ in 0..$count {
            let mut buffer = String::new();
            handle.read_line(&mut buffer)
                .expect("scan_to_vec: failed at `handle.read_line`.");
            result.push(buffer.trim().parse::<$t>()
                .expect("scan_to_vec: failed at `parse::<$t>`."));
        }
        result
    })
}

macro_rules! scan_line_to_vec {
    ($t:ty) => ({
        let mut result = Vec::new();
        let stdin = io::stdin();
        let mut handle = stdin.lock();
        let mut buffer = String::new();
        handle.read_line(&mut buffer)
            .expect("scan_line_to_vec: failed at `handle.read_line`.");

        for s in buffer.split_whitespace() {
            result.push(s.parse::<$t>()
                .expect("scan_line_to_vec: failed at `parse::<$t>`."));
        }
        result
    })
}

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>`.")
            },
        )+)
    })
}

trait Ext {
    fn is_odd(&self) -> bool;
    fn is_even(&self) -> bool;
}

impl Ext for i32 {
    #[inline]
    fn is_odd(&self) -> bool {
        self % 2 != 0
    }

    #[inline]
    fn is_even(&self) -> bool {
        self % 2 == 0
    }
}

fn main() {
    let (n,) = scan_line!(usize);
    let array = scan_line_to_vec!(i32);

    let mut result = true;
    result &= array[0].is_odd();
    result &= array[n - 1].is_odd();
    result &= (array.len() as i32).is_odd();

    if result {
        println!("YES")
    } else {
        println!("NO")
    }
}

#![allow(unused_imports)]
use std::io::{self, BufRead};
use std::cmp::*;
use std::collections::*;

macro_rules! scan_to_vec {
    ($count:expr, $t:ty) => ({
        let mut result = Vec::new();
        let stdin = io::stdin();
        let mut handle = stdin.lock();

        for _ in 0..$count {
            let mut buffer = String::new();
            handle.read_line(&mut buffer)
                .expect("scan_to_vec: failed at `handle.read_line`.");
            result.push(buffer.trim().parse::<$t>()
                .expect("scan_to_vec: failed at `parse::<$t>`."));
        }
        result
    })
}

macro_rules! scan_line_to_vec {
    ($t:ty) => ({
        let mut result = Vec::new();
        let stdin = io::stdin();
        let mut handle = stdin.lock();
        let mut buffer = String::new();
        handle.read_line(&mut buffer)
            .expect("scan_line_to_vec: failed at `handle.read_line`.");

        for s in buffer.split_whitespace() {
            result.push(s.parse::<$t>()
                .expect("scan_line_to_vec: failed at `parse::<$t>`."));
        }
        result
    })
}

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>`.")
            },
        )+)
    })
}

trait Ext {
    fn is_odd(&self) -> bool;
    fn is_even(&self) -> bool;
}

impl Ext for i32 {
    #[inline]
    fn is_odd(&self) -> bool {
        self % 2 != 0
    }

    #[inline]
    fn is_even(&self) -> bool {
        self % 2 == 0
    }
}

fn main() {
    let (n,) = scan_line!(usize);
    let array = scan_line_to_vec!(i32);

    let mut result = true;

    let mut i = 0;
    let mut segment_count = 0;
    let mut count_evens = 0;

    while i < (n - 1) {
        if array[i].is_odd() && array[i+1].is_odd() {
            segment_count += 1;
        } else if array[i].is_odd() && array[i+1].is_even() {
            count_evens += 1;
        } else if array[i].is_even() && array[i+1].is_even() {
            count_evens += 1;
        } else if array[i].is_even() && array[i+1].is_odd() {
            if count_evens.is_odd() {
                count_evens = 0;
                segment_count += 1;
                i += 1;
            } else {
                result = false;
                break;
            }
        }
        i += 1;
    }

    if i == n - 1 && array[n - 1].is_odd() {
        segment_count += 1;
    } else if i == n - 1 {
        result = false;
    }

    if segment_count.is_even() {
        result = false;
    }

    if result {
        println!("YES")
    } else {
        println!("NO")
    }
}


//spnauti-rust
use std::io::*;
use std::str::*;
use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::*;
#[allow(unused_imports)] use std::collections::*;

#[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 }
    }};
}
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 u(&mut self) ->  usize { self.p()                }
    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 vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}

#[allow(dead_code)]
fn build_counting_hashmap<K: Eq + std::hash::Hash, T>(i: T) -> HashMap<K,usize>
    where T: Iterator<Item = K> {
    let mut m = HashMap::new();
    for k in i {
        let n = 1 + if let Some(&n) = m.get(&k) { n } else { 0 };
        m.insert(k, n);
    }
    m
}

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

    let s = "aeiou13579";
    let sol = input.sl().chars().filter(|&c| s.chars().any(|a| a == c)).count();
    println!("{}", sol);
}

#[allow(unused_imports)]
use std::cmp::{max,min};
#[allow(unused_imports)]
use std::collections::{HashMap,HashSet,VecDeque};

#[allow(unused_macros)]
macro_rules! readln {
    () => {{
        use std::io;

        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();
        buf.trim().to_string()
    }};
    ( $t:ty ) => {{
        let input = readln!();
        input.parse::<$t>().unwrap()
    }};
    ( $( $t:ty ),+ ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        (
            $(
                input.next().unwrap().parse::<$t>().unwrap(),
            )+
        )
    }}
}

#[allow(unused_macros)]
macro_rules! readvec {
    ( $t:ty ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        let mut result = Vec::new();
        for elem in input {
            result.push(elem.parse::<$t>().unwrap());
        }
        result
    }}
}

fn is_vowel(z: char)->bool {
  let s = "aeoiu";
  return s.chars().any(|x|x==z);
}

fn is_odd(z: char)->bool {
  let s = "13579";
  return s.chars().any(|x|x==z);
}

fn main() {
let s = readln!();
println!("{}",s.chars().filter(|&x| is_vowel(x) || is_odd(x)).count());
}

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_vowel(ch: char) -> bool {
    return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
}

fn _main() {
    let mut scan = Scan::new();
    let mut result = 0usize;
    for ch in scan.next::<String>().chars() {
        if is_vowel(ch) || ch.to_digit(10).unwrap_or(2) % 2 == 1 {
            result += 1;
        }
    }
    println!("{}", result);
}

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

fn read_line() -> Option<String> {
    let stdin = std::io::stdin();
    let mut line = String::new();
    if stdin.read_line(&mut line).unwrap_or(0) > 0 {
        Some(line.trim().into())
    } else {
        None
    }
}

fn main() {
    fn should_flip(c: char) -> bool {
        (
            (c.is_digit(10) && (c as u8 - '0' as u8) % 2 == 1) ||
            (['a', 'e', 'i', 'o', 'u'].iter().find(|&&a| a == c).is_some())
        )
    }
    let flips = read_line()
        .expect("should have line")
        .chars()
        .fold(0, |acc, c| if should_flip(c) { acc + 1 } else { acc });
    println!("{}", flips);
}

#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
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, [graph1; $len:expr]) => {{
        let mut g = vec![vec![]; $len];
        let ab = read_value!($next, [(usize1, usize1)]);
        for (a, b) in ab {
            g[a].push(b);
            g[b].push(a);
        }
        g
    }};
    ($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);
        read_value!($next, [$t; len])
    }};
    ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error"));
}

#[allow(unused)]
macro_rules! debug {
    ($($format:tt)*) => (write!(std::io::stderr(), $($format)*).unwrap());
}
#[allow(unused)]
macro_rules! debugln {
    ($($format:tt)*) => (writeln!(std::io::stderr(), $($format)*).unwrap());
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (let _ = write!(out,$($format)*););
    }
    input! {
        s: chars,
    }
    let c = s.iter().filter(|&&c| {
        if c <= '9' {
            (c as u8 - b'0') % 2 == 1
        } else {
            ['a', 'e', 'i', 'o', 'u'].iter().find(|&&x| x == c).is_some()
        }
    }).count();
    puts!("{}\n", c);
}

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

fn read_line() -> Option<String> {
    let stdin = std::io::stdin();
    let mut line = String::new();
    if stdin.read_line(&mut line).unwrap_or(0) > 0 {
        Some(line.trim().into())
    } else {
        None
    }
}

fn main() {
    fn should_flip(c: char) -> bool {
        (
            (c.is_digit(10) && (c as u8 - '0' as u8) % 2 == 0) ||
            (['a', 'e', 'i', 'o', 'u'].iter().find(|&&a| a == c).is_some())
        )
    }
    let flips = read_line()
        .expect("should have line")
        .chars()
        .fold(0, |acc, c| if should_flip(c) { acc + 1 } else { acc });
    println!("{}", flips);
}


#[allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::HashSet;

struct Reader {}

impl Reader {
    #[allow(unused)]
    fn read_string() -> String {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string).unwrap();
        string.trim().to_string()
    }

    #[allow(unused)]
    fn read_tokens() -> Vec::<String> {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string).unwrap();
        let mut v = Vec::new();
        for value in string.split_whitespace() {
            v.push(value.to_string());
        }
        v
    }
}

//mod math;

pub fn generate_simple_numbers(max_value: u64) -> Vec<u64> {
    let mut src = vec![true; max_value as usize + 1];
    let mut dst = Vec::new();

    for i in 2 .. max_value as usize + 1 {
        if src[i] {
            let mut ind = i * i;
            while ind <= max_value as usize {
                src[ind] = false;
                ind += i;
            }
            dst.push(i as u64);
        }
    }
    dst
}

fn main() {
    let n = Reader::read_string().parse::<i64>().unwrap();
    let simple_numbers = generate_simple_numbers(3000);
    let mut ans = 0_u64;
    for i in 1..=n {
        let mut number = i as u64;
        let mut map = std::collections::BTreeSet::<u64>::new();
        for value in simple_numbers.iter() {
            if *value > number {
                break;
            }
            while number % *value == 0 {
                map.insert(*value);
                number /= *value;
            }
        }
        if map.len() == 2 {
            ans += 1;
        }
    }
    println!("{}", ans);
}

fn sieve_of_eratosthene(n: usize) -> Vec<bool> {
    let mut is_prime = vec![true; std::cmp::max(n, 2)];

    is_prime[0] = false;
    is_prime[1] = false;

    let mut i = 2;
    loop {
        while i < n && !is_prime[i] {
            i += 1;
        }

        let cur_prime = i;

        let mut q = 2;
        while q * cur_prime < n {
            is_prime[q * cur_prime] = false;
            q += 1;
        }

        i += 1;
        if i >= n {
            return is_prime;
        }
    }
}

fn primes(is_prime: &Vec<bool>) -> Vec<usize> {
    let mut primes = Vec::new();
    for i in 0..is_prime.len() {
        if is_prime[i] {
            primes.push(i);
        }
    }

    primes
}

fn is_number_good(prime: &Vec<usize>, n: usize) -> bool {
    let mut firstmult = 0;

    for i in 0..prime.len() {
        if n % prime[i] == 0 {
            firstmult = prime[i];
            break;
        }
    }

    let mut secmult = 0;
    for i in 0..prime.len() {
        if n % prime[i] == 0 && prime[i] != firstmult {
            secmult = prime[i];
            break;
        }
    }

    if secmult == 0 {
        return false;
    }

    for i in 0..prime.len() {
        if n % prime[i] == 0 && prime[i] != firstmult && prime[i] != secmult {
                return false
            }
    }

    true
}
fn main() {
    let mut str = String::new();

    std::io::stdin().read_line(&mut str).unwrap();

    let n = str.trim().parse::<usize>().unwrap();

    let is_prime = sieve_of_eratosthene(n);

    let mut c = 0;
    for i in 2..=n {
        if is_number_good(&primes(&is_prime), i) {
            c += 1;
        }
    }

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

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 count_prime_factors(n: i32) -> i32 {
    let mut count = 0;
    let mut factor = 2;
    let mut n = n;
    while factor * factor <= n {
        let mut expo = 0;
        while n % factor == 0 {
            n /= factor;
            expo += 1;
        }
        if expo >= 1 {
            count += 1;
        }
        factor += 1;
    }
    if n > 1 {
        count += 1;
    }
    count
}

fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
    let n: i32 = scan.token();
    let mut ans = 0;
    for i in 1..=n {
        let count = count_prime_factors(i);
        if count == 2 {
            ans += 1;
        }
    }
    writeln!(out, "{}", ans).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);
}

//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_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),* = $i:ident.$f:ident $a:tt) => {
        $( let $v = $i.$f$a; )*
    };
    ($($v:ident),*:$t:ty = $i:ident.$f:ident $a:tt) => {
        $( let $v:$t = $i.$f$a; )*
    };
}
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 ii(&mut self, n: usize) -> impl Iterator<Item=i32> {
        self.ip(n).into_iter()
    }
    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.u();
    let mut p = vec![0; n + 1];
    let mut sol = 0;
    for i in 2..=n {
        if p[i] == 0 {
            let mut j = i;
            while j <= n {
                p[j] += 1;
                j += i;
            }
        } else if p[i] == 2 {
            sol += 1;
        }
    }
    println!("{}", sol);
}

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 next_n<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.next::<T>()).collect()
    }
}

fn _main() {
    let mut scan = Scan::new();
    let n: usize = scan.next();
    let mut count = [0; 3001];
    let mut result = 0usize;
    let mut i = 2usize;
    while i <= n {
        if count[i] == 0 {
            let mut j = 2;
            while i * j <= n {
                count[i * j] += 1;
                j += 1;
            }
        }
        i += 1;
    }
    for i in 2..=n {
        if count[i] == 2 {
            result += 1;
        }
    }
    println!("{}", result);
}

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

#[allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::HashSet;

struct Reader {}

impl Reader {
    #[allow(unused)]
    fn read_string() -> String {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string).unwrap();
        string.trim().to_string()
    }

    #[allow(unused)]
    fn read_tokens() -> Vec::<String> {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string).unwrap();
        let mut v = Vec::new();
        for value in string.split_whitespace() {
            v.push(value.to_string());
        }
        v
    }
}

//mod math;

fn generate_simple_numbers(max_value: i64) -> Vec<i64> {
    let mut src = vec![true; max_value as usize + 1];
    let mut dst = Vec::new();

    for i in 2 .. max_value as usize + 1 {
        if src[i] {
            let mut ind = i * i;
            while ind <= max_value as usize {
                src[ind] = false;
                ind += i;
            }
        }
    }
    for i in 2 .. max_value as usize + 1 {
        if src[i] {
            dst.push(i as i64);
        }
    }
    dst
}

fn main() {

    let n = Reader::read_string().parse::<i64>().unwrap();
    let simple_numbers = generate_simple_numbers(3000);
    let mut ans = 0_i64;
    for i in 1..=n {
        let mut number = i;
        let mut map = std::collections::BTreeSet::<i64>::new();
        for value in simple_numbers.iter() {
            if *value > number {
                break;
            }
            while number % *value == 0 {
                map.insert(*value);
                number /= *value;
            }
        }
        if map.len() == 2 {
            ans += 1;
        }
    }
    println!("{}", ans);
}

#[allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::HashSet;

struct Reader {}

impl Reader {
    #[allow(unused)]
    fn read_string() -> String {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string).unwrap();
        string.trim().to_string()
    }

    #[allow(unused)]
    fn read_tokens() -> Vec::<String> {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string).unwrap();
        let mut v = Vec::new();
        for value in string.split_whitespace() {
            v.push(value.to_string());
        }
        v
    }
}

//mod math;

fn generate_simple_numbers(max_value: i64) -> Vec<i64> {
    let mut src = vec![true; max_value as usize + 1];
    let mut dst = Vec::new();

    for i in 2 .. max_value as usize + 1 {
        if src[i] {
            let mut ind = i * i;
            while ind <= max_value as usize {
                src[ind] = false;
                ind += i;
            }
        }
    }
    for i in 2 .. max_value as usize + 1 {
        if src[i] {
            dst.push(i as i64);
        }
    }
    dst
}

fn main() {

    let n = Reader::read_string().parse::<i64>().unwrap();
    let simple_numbers = generate_simple_numbers(3000);
    let mut ans = 0_i64;
    for i in 1..=n {
        let mut number = i;
        let mut map = std::collections::HashMap::<i64, i32>::new();
        for value in simple_numbers.iter() {
            if *value > number {
                break;
            }
            while number % *value == 0 {
                map.insert(*value, 1);
                number /= *value;
            }
        }
        if map.len() == 2 {
            ans += 1;
        }
    }
    println!("{}", ans);
}

#[allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::HashSet;

struct Reader {}

impl Reader {
    #[allow(unused)]
    fn read_string() -> String {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string).unwrap();
        string.trim().to_string()
    }

    #[allow(unused)]
    fn read_tokens() -> Vec::<String> {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string).unwrap();
        let mut v = Vec::new();
        for value in string.split_whitespace() {
            v.push(value.to_string());
        }
        v
    }
}

//mod math;

fn generate_simple_numbers(max_value: i64) -> Vec<i64> {
    let mut src = vec![true; max_value as usize + 1];
    let mut dst = Vec::new();

    for i in 2 .. max_value as usize + 1 {
        if src[i] {
            let mut ind = i * i;
            while ind <= max_value as usize {
                src[ind] = false;
                ind += i;
            }
        }
    }
    for i in 2 .. max_value as usize + 1 {
        if src[i] {
            dst.push(i as i64);
        }
    }
    dst
}

fn main() {

    let n = Reader::read_string().parse::<i64>().unwrap();
    let simple_numbers = generate_simple_numbers(3000);
    let mut ans = 0_i64;
    for i in 1..=n {
        let mut number = i;
        let mut map = std::collections::HashMap::<i64, i32>::new();
        for value in simple_numbers.iter() {
            while number % *value == 0 {
                map.insert(*value, 1);
                number /= *value;
            }
        }
        if map.len() == 2 {
            ans += 1;
        }
    }
    println!("{}", ans);
}

fn sieve_of_eratosthene(n: usize) -> Vec<bool> {
    let mut is_prime = vec![true; std::cmp::max(n, 2)];

    is_prime[0] = false;
    is_prime[1] = false;

    let mut i = 2;
    loop {
        while i < n && !is_prime[i] {
            i += 1;
        }

        let cur_prime = i;

        let mut q = 2;
        while q * cur_prime < n {
            is_prime[q * cur_prime] = false;
            q += 1;
        }

        i += 1;
        if i >= n {
            return is_prime;
        }
    }
}

fn primes(is_prime: &Vec<bool>) -> Vec<usize> {
    let mut primes = Vec::new();
    for i in 0..is_prime.len() {
        if is_prime[i] {
            primes.push(i);
        }
    }

    primes
}

fn is_number_good(prime: &Vec<usize>, n: usize) -> bool {
    let mut firstmultiplier = 0;

    for i in 0..prime.len() {
        if n % prime[i] == 0 {
            firstmultiplier = prime[i];
        }
    }

    for i in 0..prime.len() {
        if n % prime[i] == 0 && prime[i] != firstmultiplier {
            return true;
        }
    }

    false
}

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

    std::io::stdin().read_line(&mut str).unwrap();

    let n = str.trim().parse::<usize>().unwrap();

    let is_prime = sieve_of_eratosthene(n);

    let mut c = 0;
    for i in 2..n {
        if is_number_good(&primes(&is_prime), i) {
            c += 1;
        }
    }

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

fn sieve_of_eratosthene(n: usize) -> Vec<bool> {
    let mut is_prime = vec![true; std::cmp::max(n, 2)];

    is_prime[0] = false;
    is_prime[1] = false;

    let mut i = 2;
    loop {
        while i < n && !is_prime[i] {
            i += 1;
        }

        let cur_prime = i;

        let mut q = 2;
        while q * cur_prime < n {
            is_prime[q * cur_prime] = false;
            q += 1;
        }

        i += 1;
        if i >= n {
            return is_prime;
        }
    }
}

fn primes(is_prime: &Vec<bool>) -> Vec<usize> {
    let mut primes = Vec::new();
    for i in 0..is_prime.len() {
        if is_prime[i] {
            primes.push(i);
        }
    }

    primes
}

fn is_number_good(prime: &Vec<usize>, n: usize) -> bool {
    let mut firstmultiplier = 0;

    for i in 0..prime.len() {
        if n % prime[i] == 0 {
            firstmultiplier = prime[i];
        }
    }

    for i in 0..prime.len() {
        if n % prime[i] == 0 && prime[i] != firstmultiplier {
            return true;
        }
    }

    false
}

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

    std::io::stdin().read_line(&mut str).unwrap();

    let n = str.trim().parse::<usize>().unwrap();

    let is_prime = sieve_of_eratosthene(n);

    let mut c = 0;
    for i in 2..=n {
        if is_number_good(&primes(&is_prime), i) {
            c += 1;
        }
    }

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


use std::io;

struct Prime {
    a: Vec<bool>,
    al: usize,
    t: Vec<usize>,
}

#[allow(dead_code)]
impl Prime {
    fn new(n: usize) -> Self {
        let mut t = vec![2; 1];
        let s = (n as f64).sqrt().round() as usize + 3;
        let mut a = vec![true; s];
        a[0] = false;
        a[1] = false;
        for i in (4..s).step_by(2) {
            a[i] = false;
        }
        for i in (3..s).step_by(2) {
            if !a[i] {
                continue;
            }
            t.push(i);
            if i * i < s {
                for j in ((i * i)..s).step_by(i * 2) {
                    a[j] = false;
                }
            }
        }
        let al = a.len();
        Prime { a, al, t }
    }

    fn is_prime(&self, x: usize) -> bool {
        if x < self.al {
            return self.a[x];
        }

        for c in self.t.iter() {
            if x % c == 0 {
                return false;
            }
        }

        true
    }
}

#[allow(dead_code)]
fn solve() -> Vec<String> {
    let mut input = "".split_ascii_whitespace();
    let mut read = || loop {
        if let Some(word) = input.next() {
            break word;
        }
        input = {
            let mut input = "".to_owned();
            io::stdin().read_line(&mut input).unwrap();
            if input.is_empty() {
                panic!("reached EOF");
            }
            Box::leak(input.into_boxed_str()).split_ascii_whitespace()
        };
    };
    macro_rules! read(($ty:ty) => (read().parse::<$ty>().unwrap()));

    let mut rr = vec!["".to_string(); 0];

    let t = 1;
    for _ in 0..t {
        let n = read!(usize);

        let mut r = 3;
        if n > 3 && n % 2 == 0 {
            r = 2;
        } else {
            let pr = Prime::new(n);
            if pr.is_prime(n) {
                r = 1;
            } else if pr.is_prime(n - 2) {
                r = 2;
            }
        }

        rr.push(format!("{}", r));
    }

    rr
}

#[allow(dead_code)]
fn main() {
    let output = solve();
    println!("{}", output.join("\n"));
}

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

//

fn is_prime(n: u64) -> bool {
    if n <= 1 {
        return false;
    }
    for k in (2..).take_while(|k| k * k <= n) {
        if n % k == 0 {
            return false;
        }
    }
    true
}

fn run() {
    input! {
        n: u64,
    }
    let ans = if is_prime(n) {
        1
    } else if n % 2 == 0 {
        2
    } else if is_prime(n - 2) {
        2
    } else {
        3
    };
    println!("{}", ans);
}

fn main() {
    run();
}

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

fn exec() {
    let mut sc = Scanner::new();
    let n: i64 = sc.ne();
    let ans = if is_prime(n) {
        1
    } else if n & 1 == 0 || is_prime(n - 2) {
        2
    } else {
        3
    };
    println!("{}", ans);
}

fn is_prime(x: i64) -> bool {
    let mut y = 2;
    while y * y <= x {
        if x % y == 0 {
            return false;
        }
        y += 1;
    }
    x != 1
}
const DEFAULT_STACK: usize = 16 * 1024 * 1024;
fn main() {
    let builder = thread::Builder::new();
    let th = builder.stack_size(DEFAULT_STACK);
    let handle = th.spawn(|| { exec(); }).unwrap();
    let _ = handle.join();
}

#[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) => return 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"),
        };
        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::{self, Stdin};
use std::str::{self, FromStr};
use std::error::Error;
use std::thread;

fn exec() {
    let mut sc = Scanner::new();
    let n: i64 = sc.ne();
    let ans = if is_prime(n) {
        1
    } else if n & 1 == 1 {
        3
    } else {
        2
    };
    println!("{}", ans);
}

fn is_prime(x: i64) -> bool {
    let mut y = 2;
    while y * y <= x {
        if x % y == 0 {
            return false;
        }
        y += 1;
    }
    x != 1
}
const DEFAULT_STACK: usize = 16 * 1024 * 1024;
fn main() {
    let builder = thread::Builder::new();
    let th = builder.stack_size(DEFAULT_STACK);
    let handle = th.spawn(|| { exec(); }).unwrap();
    let _ = handle.join();
}

#[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) => return 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"),
        };
        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::{self, Stdin};
use std::str::{self, FromStr};
use std::error::Error;
use std::thread;

fn exec() {
    let mut sc = Scanner::new();
    let n: i64 = sc.ne();
    fn solve(n: i64) -> i64 {
        if is_prime(n) {
            return 1;
        }
        let mut x = n - 2;
        while is_prime(x) == false {
            x -= 1;
        }
        1 + solve(n - x)
    }
    println!("{}", solve(n));
}

fn is_prime(x: i64) -> bool {
    let mut y = 2;
    while y * y <= x {
        if x % y == 0 {
            return false;
        }
        y += 1;
    }
    x != 1
}
const DEFAULT_STACK: usize = 16 * 1024 * 1024;
fn main() {
    let builder = thread::Builder::new();
    let th = builder.stack_size(DEFAULT_STACK);
    let handle = th.spawn(|| { exec(); }).unwrap();
    let _ = handle.join();
}

#[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) => return 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"),
        };
        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()
    }
}