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

    friends.sort_unstable();
    println!("{}", (friends[2] - friends[1]) + (friends[1] - friends[0]));
}


/// All text input is handled through this macro
#[macro_export]
macro_rules! read(
    () => { read!("{}") };
    ($text:expr) => {{
        let value;
        scan!($text, value);
        value
    }};
    ($text:expr, $input:expr) => {{
        let value;
        scan!($input => $text, value);
        value
    }};
);

/// This macro allows to pass several variables so multiple values can be read
#[macro_export]
macro_rules! scan(
    ($text:expr, $($arg:expr),*) => {
        scan!(::std::io::stdin().bytes().map(|c| c.unwrap()) => $text, $($arg),*) ;
        format_args!($text, $($arg),*);
    };
    ($input:expr => $text:expr, $($arg:expr),*) => {{
        use ::std::io::Read;
        use ::std::str::FromStr;
        // typesafe macros :)
        let text: &'static str = $text;
        let stdin: &mut Iterator<Item = u8> = &mut ($input);

        let mut text = text.bytes();
        $(
        loop { match text.next() {
            Some(b'{') => match text.next() {
                Some(b'{') => assert_eq!(Some(b'{'), stdin.next()),
                Some(b'}') => {
                    let s: Vec<u8> = match text.next() {
                        Some(c) => stdin.take_while(|&ch| ch != c).collect(),
                        None => stdin.take_while(|ch| !b"\t\r\n ".contains(ch)).collect(),
                    };
                    let s = match ::std::str::from_utf8(&s) {
                        Ok(s) => s,
                        Err(e) => {
                            let n = e.valid_up_to();
                            if n == 0 {
                                panic!("input was not valid utf8: {:?}", s);
                            } else {
                                panic!("input was only partially valid utf8: \"{}\" followed by {:?}",
                                       ::std::str::from_utf8(&s[..n]).unwrap(), &s[n..]);
                            }
                        }
                    };
                    $arg = FromStr::from_str(s).expect(&format!("could not parse {} as target type of {}", s, stringify!($arg)));
                    break;
                }
                Some(_) => panic!("found bad curly brace"),
                None => panic!("found single open curly brace at the end of the format string"),
            },
            Some(c) => assert_eq!(Some(c), stdin.next()),
            None => panic!("Bad read! format string: did not contain {{}}"),
        } }
        )*
        for c in text {
            assert_eq!(Some(c), stdin.next());
        }
        format_args!($text, $($arg),*);
    }};
);

macro_rules! max {
    ($x:expr) => ( $x );
    ($x:expr, $($xs:expr),+) => {
        {
            use std::cmp::max;
            max($x, max!( $($xs),+ ))
        }
    };
}

macro_rules! min {
    ($x:expr) => ( $x );
    ($x:expr, $($xs:expr),+) => {
        {
            use std::cmp::min;
            min($x, min!( $($xs),+ ))
        }
    };
}

fn main() {
    let (a, b, c) : (i32, i32, i32) = (read!(), read!(), read!());
    let x: i32 = min!(a, b, c);
    let z: i32 = max!(a, b, c);
    let y: i32 = a ^ b ^ c ^ x ^ z;

    println!("{}", (x - y).abs() + (z - y).abs());
}


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

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

    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!("{}", max-min);
}


use std::io;

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

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

    assert!(values.len() == 3);
    values.sort();

    println!("{}", values[1]-values[0] + values[2]-values[1]);

}


use std::cmp;

fn max(x: i32, y: i32, z: i32) -> i32{
    cmp::max(x, cmp::max(y, z))
}
fn min(x: i32, y: i32, z: i32) -> i32{
    cmp::min(x, cmp::min(y, z))
}

fn main() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.split_whitespace().map(|x| {x.parse::<i32>().unwrap()});

    let x = it.next().unwrap();
    let y = it.next().unwrap();
    let z = it.next().unwrap();

    println!("{}", max(x, y, z) - min(x, y, z));
}


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

fn main() {
	let mut b = String::new();
	io::stdin().read_to_string(&mut b);
	let mut inp = b.split_whitespace();
	let x = inp.next().unwrap().parse::<i32>().unwrap();
	let y = inp.next().unwrap().parse::<i32>().unwrap();
	let z = inp.next().unwrap().parse::<i32>().unwrap();
	let mut ans = 2_000_000_000;
	for i in 0..105 {
		ans = cmp::min(ans, (x-i).abs()+(y-i).abs()+(z-i).abs());
	}
    print!("{}", ans);
}


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,c) = readln!(i32,i32,i32);
    let mx = std::cmp::max(a,std::cmp::max(b,c));
    let mn = std::cmp::min(a,std::cmp::min(b,c));
    println!("{}",mx-mn);
}


//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();
    let mut y = input.i();
    loop {
        y += 1;
        let s = y.to_string().into_bytes();
        let l = s.len();
        if (0..l).all(|i| (i+1..l).all(|j| s[i] != s[j])) {
            break;
        }
    }
    println!("{}", y);
}


use std::collections::HashSet;

fn main() {
    let mut text = String::new();
    std::io::stdin().read_line(&mut text).unwrap();
    let mut num = text.trim().parse::<u32>().unwrap();
    loop {
        num = num + 1;
        let mut digits = HashSet::new();
        let mut x = num;
        while x > 0 {
            digits.insert(x % 10);
            x = x / 10;
        }
        if digits.len() == 4 {
            println!("{}", num);
            return;
        }
    }
}


use std::io;

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

	'main: loop {
		year_1 += 1;
		let year_1 = year_1.to_string();
		let mut uniq = String::new();
		for num in year_1.chars() {
			if !uniq.contains(num) {
				uniq.push(num);
			} else {
				continue 'main;
			}
		}
		println!("{}", year_1);
		break;
	}

}


#[allow(unused_imports)]
use std::cmp::{min,max};
use std::collections::{*};
use std::io::{BufWriter, stdin, stdout, Write};
const BITS: usize = 19;

#[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 scanner = Scanner::default();
    let u: u64 = scanner.next();
    let mut v = u + 1;
    while v.to_string().chars().collect::<BTreeSet<char>>().len() != (v.to_string().chars().collect::<Vec<char>>()).len(){
    	v+=1;
    }
    print!["{}", v];
}


use std::collections::HashSet;
fn main() {
    let mut y: usize = read_line().parse().unwrap();

    loop {
        y += 1;
        let h: HashSet<char> = y.to_string().chars().collect();
        if h.len() == 4 {
            println!("{}", y);
            break;
        }

    }

}

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

    input.trim().to_string()
}


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

const DECIMAL_RADIX : u64 = 10;

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 parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_t<T : FromStr>(stdin : &Stdin) -> T {
    let mut line = String::new();
    read_line(stdin, &mut line);
    parse_t(&line)
}

fn little_endian_digits(n : u64, ds : &mut Vec<u64>) {
    let mut x = n;
    loop {
        let d = x % 10;
        x = x / 10;
        ds.push(d);
        if x == 0 {
            break;
        }
    }
}

fn big_endian_digits(n : u64, ds : &mut Vec<u64>) {
    little_endian_digits(n, ds);
    ds.reverse();
}

fn big_endian_digits_to_number(ds : &Vec<u64>) -> u64 {
    let mut x = 0;
    for d in ds {
        x = (x * 10) + d;
    }
    x
}

fn contains(y : u64, xs : &Vec<u64>) -> bool {
    for &x in xs {
        if y == x {
            return true;
        }
    }
    false
}

fn has_duplicates_in_prefix(digits : &Vec<u64>) -> bool {
    let mut copy_digits = digits.clone();
    // Pop the last digit, because we are only looking
    // for duplicates in prefix.
    copy_digits.pop();
    copy_digits.sort();
    for i in 1 .. copy_digits.len() {
        if copy_digits[i - 1] == copy_digits[i] {
            return true;
        }
    }
    false
}

fn find_replacement_digit(d : &Option<u64>, digits : &Vec<u64>) -> Option<u64> {
    if has_duplicates_in_prefix(digits) {
        return None;
    }
    let mut s = 0;
    match *d {
        None => (),
        Some(y) => {
            s = y + 1;
        },
    }
    for i in s .. DECIMAL_RADIX {
        if contains(i, digits) {
            // Do nothing ...
        } else {
            return Some(i);
        }
    }
    None
}

fn next_with_distinct_digits(n : u64) -> u64 {
    let mut b_e_digits = vec![];
    big_endian_digits(n, &mut b_e_digits);
    let orig_level = b_e_digits.len() - 1;
    let mut level = orig_level;
    let mut c_d_o = Some(b_e_digits[level]);
    loop {
        let r_d_o = find_replacement_digit(&c_d_o, &b_e_digits);
        match r_d_o {
            None => {
                b_e_digits.pop();
                level = level - 1;
                c_d_o = Some(b_e_digits[level]);
            },
            Some(r_d) => {
                b_e_digits[level] = r_d;
                if level < orig_level {
                    b_e_digits.push(DECIMAL_RADIX);
                }
                level = level + 1;
                c_d_o = None;
            }
        }
        if level > orig_level {
            break;
        }
    }
    big_endian_digits_to_number(&b_e_digits)
}

fn main() {
    let stdin = io::stdin();
    let n = read_t(&stdin);
    println!("{}", next_with_distinct_digits(n));
}


use std::io;

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

fn valid(n: u32) -> bool {
    let ds = n.to_string().chars().collect::<Vec<char>>();
    for i in 0..ds.len() {
        for j in i+1..ds.len() {
            if ds[i] == ds[j] {
                return false;
            }
        }
    }
    return true;
}

fn main() {
    let mut n = read_line().trim().parse::<u32>().unwrap() + 1;
    while !valid(n) {
        n += 1;
    }
    println!("{}", n);
}


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 read_int<T: FromStr>() -> T{
    read_str().parse::<T>().ok().expect("Error")
}

fn main() {
    let mut year: u16 = read_int();

    loop {
        year += 1;
        let hash: std::collections::HashSet<char> = year.to_string().chars().collect();
        if hash.len() == 4 { println!("{}", year); break; }
    }
}


fn input_split() -> 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 mut bags = input_split();
    bags.sort_unstable_by(|a, b| b.cmp(&a));

    let mut first_friend = 0;
    let mut second_friend = 0;

    for bag in bags {
        if first_friend < second_friend {
            first_friend += bag;
        } else {
            second_friend += bag;
        }
    }

    print!(
        "{}",
        if first_friend == second_friend {
            "YES"
        } else {
            "NO"
        }
    )
}


use std::io::Write;

pub struct Scanner {
  buffer: Vec<String>
}

impl Scanner {
  pub fn new() -> Scanner {
    Scanner { buffer: Vec::new() }
  }

  pub 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();
      std::io::stdin().read_line(&mut input).expect("Failed read");
      self.buffer = input.split_whitespace().rev().map(String::from).collect();
    }
  }
}

fn main() {
  let stdout = std::io::stdout();
  let mut out = std::io::BufWriter::new(stdout.lock());
  let mut scan = Scanner::new();

  let mut a: Vec<i32> = Vec::with_capacity(4);
  for _ in 0..4 {
    a.push(scan.next());
  }
  a.sort();
  let s: i32 = a.iter().sum();
  if a[3] == a[0] + a[1] + a[2] ||
     2*(a[3] + a[1]) == s ||
     2*(a[3] + a[0]) == s {
    writeln!(out, "YES").unwrap();
  } else {
    writeln!(out, "NO").unwrap();
  }
}


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

    l!(a,b,c,d = input.i());
    let mut ans = false;
    let mut f = |x: i32, y: i32| {
        if x == y {
            ans = true;
        }
    };
    f(a, b+c+d);
    f(b, a+c+d);
    f(c, a+b+d);
    f(d, a+b+c);
    f(a+b, c+d);
    f(a+c, b+d);
    f(a+d, b+c);
    if ans {
        println!("YES");
    } else {
        println!("NO");
    }
}


fn main() {
    let mut input = String::new();
    use std::io;
    use std::io::prelude::*;
    io::stdin().read_to_string(&mut input).unwrap();

    let mut it = input.split_whitespace();

    let n: u32 = it.next().unwrap().parse().unwrap();
    let a: u32 = it.next().unwrap().parse().unwrap();
    let b: u32 = it.next().unwrap().parse().unwrap();

    let oa = a - 1;
    let ob = b - 1;

    let logn = 31 - n.leading_zeros();

    let mut flag = n >> 1;
    let mut i = 0;

    let xor = oa ^ ob;

    while flag & xor == 0 {
        i += 1;
        flag >>= 1;
    }

    if flag == n >> 1 {
        println!("Final!");
    } else {
        println!("{}", logn - i)
    }
}


use std::io;

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

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

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

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

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

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

fn main() {
    let v = read_line_of_integers();
    let (n, a, b) = (v[0], v[1] - 1, v[2] - 1);

    let mut m = 1;
    let mut ans = 0;
    while a / m != b / m {
        m *= 2;
        ans += 1;
    }

    if m == n {
        println!("Final!")
    } else {
        println!("{}", ans);
    }
}


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

fn exec() {
    let mut sc = Scanner::new();
    let n: usize = sc.ne();
    let mut a = [0, 1, 2];
    let m = n % 6;
    for k in 0..m {
        let tmp = a[1];
        if k & 1 == 0 {
            a[1] = a[0];
            a[0] = tmp;
        } else {
            a[1] = a[2];
            a[2] = tmp;
        }

    }
    let k: usize = sc.ne();
    println!("{}", a[k]);
}

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

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

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


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

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

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

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

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

    // On a une permutation qui dépend de n.
    // Premières valeurs :
    // 2 1 3
    // 2 3 1
    // 3 2 1
    // 3 1 2
    // 1 3 2
    // 1 2 3

    let perm = |i, n| {
        match i {
            0 => (n + 1) % 6 / 2,
            1 => match n % 3 {
                0 => 1,
                1 => 0,
                2 => 2,
                _ => panic!("Something is WRONG."),
            },
            2 => (n + 4) % 6 / 2,
            _ => panic!("Something is WRONG."),
        }
    };

    let ans = perm(x, n);

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


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

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

fn solve() {
    let n: i64 = get();
    let x: usize = get();
    let tbl = [[0, 1, 2], [1, 0, 2], [1, 2, 0], [2, 1, 0], [2, 0, 1],
               [0, 2, 1], [0, 1, 2]];
    println!("{}", tbl[(n % 6) as usize][x]);
}

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


use std::io::{self};
use std::str::FromStr;

fn main() {
    let n: u8 = (read_num() % 6) as u8;
    let mut x: u8 = read_num() as u8;

    for y in 0..n {
        // println!(" step:{}, x:{}, is_div:{}", n - y, x, (n - y) % 2 == 0);
        if (n - y) % 2 == 0 {
            // change central and right
            x = match x {
                0 => 0,
                1 => 2,
                2 => 1,
                _ => 0,
            };
        } else {
            // change central and left
            x = match x {
                0 => 1,
                1 => 0,
                2 => 2,
                _ => 0,
            };
        }
    }

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

fn read_num() -> u32 {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).expect("Error reading data!");
    let n: u32 = FromStr::from_str(buffer.trim()).unwrap();
    n
}


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

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

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

use std::io::Write;
use std::collections::*;

type Map<K, V> = BTreeMap<K, V>;
type Set<T> = BTreeSet<T>;
type Deque<T> = VecDeque<T>;

fn calc(x: u64, y: u64) -> bool {
    let mut set = Set::new();
    let mut s = vec![];
    let mut x = x;
    while x > 0 {
        s.push(x % 2);
        x /= 2;
    }
    set.insert(s.clone());
    let fix = |s: &mut Vec<u64>| {
        while *s.last().unwrap() == 0 {
            s.pop();
        }
    };
    let mut dfs = vec![s];
    while let Some(s) = dfs.pop() {
        for &d in [0, 1].iter() {
            let mut s = s.clone();
            s.insert(0, d);
            s.reverse();
            fix(&mut s);
            if s.len() <= 60 && set.insert(s.clone()) {
                dfs.push(s);
            }
        }
    }
    let mut s = vec![];
    let mut y = y;
    while y > 0 {
        s.push(y % 2);
        y /= 2;
    }
    set.contains(&s)
}

fn run() {
    input!(x: u64, y: u64);
    if calc(x, y) {
        println!("YES");
    } else {
        println!("NO");
    }
}

fn main() {
    run();
}


//spnauti-rusT {{{
#[allow(unused_imports)]use std::{io::*,collections::*,fmt::Debug,str::{self,*},cmp::*,ops::{self,*},iter::{self,*}};
macro_rules!l{
	($($v:ident),+:$t:ty=$e:expr)=>{$(let$v:$t=$e;)+};(mut $($v:ident),+ =$e:expr)=>{$(let mut$v=$e;)+};
	(mut $($v:ident),+:$t:ty=$e:expr)=>{$(let mut$v:$t=$e;)+};($($v:ident),+ =$e:expr)=>{$(let$v=$e;)+};}
macro_rules!v{
	($(:$t:ty)?=$e:expr)=>{$e$(as$t)?};([$d:expr]$(:$t:ty)?)=>{Vec::$(<$t>::)?with_capacity($d)};
	([]$(:$t:ty)?)=>{Vec::$(<$t>::)?new()};([$d:expr]$($s:tt)+)=>{vec![v!($($s)+);$d]};}
fn rio()->(Reader,BufWriter<Stdout>){(Reader::new(),BufWriter::new(stdout()))}
struct Reader{buf:Vec<u8>,pos:usize,x:*mut Stdin,q:StdinLock<'static>}//'
#[allow(dead_code)]impl Reader{
	fn new()->Self{let x=Box::into_raw(Box::new(stdin()));let q=unsafe{&*x}.lock();Self{x,q,buf:v!([]),pos:0}}
	fn next_line(&mut self)->bool{self.buf.clear();self.pos=0;self.q.read_until(b'\n',&mut self.buf).unwrap_or(0)>0}
	fn byte(&mut self)->Option<u8>{
		if self.pos==self.buf.len(){if!self.next_line(){return None;}}self.pos+=1;Some(self.buf[self.pos-1])}
	fn vb(&mut self)->Vec<u8>{let mut s=v!([10]);let mut f=false;while let Some(c)=self.byte(){
		if!c.is_ascii_whitespace(){s.push(c);f=true;}else if f{break;}}s}
	fn p<T:FromStr>(&mut self)->T where T::Err:Debug{let w=self.vb();str::from_utf8(w.as_ref()).unwrap().parse::<T>().unwrap()}
	fn l(&mut self) ->    i64 { self.p() }
}impl Drop for Reader{fn drop(&mut self){unsafe{Box::from_raw(self.x)};}}
//----------}}}

fn main() {
	let (mut rin,mut rout) = rio();

	l!(x,y = rin.l());
	if x == y {
		writeln!(rout, "YES").unwrap();
		return;
	}
	let mut x1 = x;
	while x1 & 1 == 0 {
		x1 >>= 1;
	}
	let ys = format!("{:b}", y);
	for &x in &[x*2+1, x1] {
		let xs = format!("{:b}", x);
		let mut a = v!([2]);
		a.push(xs.chars().rev().collect());
		a.push(xs);
		for xs in a {
			if ys.splitn(2, &xs).filter(|s| s.chars().all(|c| c == '1')).count() == 2 {
				writeln!(rout, "YES").unwrap();
				return;
			}
		}
	}
	writeln!(rout, "NO").unwrap();
}


use std::ops::Sub;
use std::ops::DivAssign;
use std::ops::SubAssign;
use std::marker::PhantomData;
use std::io::Write;
use std::ops::Mul;
use std::ops::Add;
use std::ops::Rem;
use std::ops::RemAssign;
use std::fmt::Display;
use std::io::Read;
use std::ops::Div;
use std::ops::AddAssign;
use std::ops::MulAssign;

pub trait Addable: Add<Output = Self> + AddAssign + Copy {}
impl<T: Add<Output = Self> + AddAssign + Copy> Addable for T {}

pub trait AddSub: Addable + Sub<Output = Self> + SubAssign {}
impl<T: Addable + Sub<Output = Self> + SubAssign> AddSub for T {}
pub trait FromU8 {
    fn from_u8(val: u8) -> Self;
}

macro_rules! from_u8_impl {
    ($t: ident) => {
        impl FromU8 for $t {
            fn from_u8(val: u8) -> Self {
                val as $t
            }
        }
    };
}

from_u8_impl!(i128);
from_u8_impl!(i64);
from_u8_impl!(i32);
from_u8_impl!(i16);
from_u8_impl!(i8);
from_u8_impl!(isize);
from_u8_impl!(u128);
from_u8_impl!(u64);
from_u8_impl!(u32);
from_u8_impl!(u16);
from_u8_impl!(u8);
from_u8_impl!(usize);
from_u8_impl!(f32);
from_u8_impl!(f64);

pub trait Multable: Mul<Output = Self> + MulAssign + Copy {}
impl<T: Mul<Output = Self> + MulAssign + Copy> Multable for T {}

pub trait MulDiv: Multable + Div<Output = Self> + DivAssign {}
impl<T: Multable + Div<Output = Self> + DivAssign> MulDiv for T {}

pub trait MulDivRem: MulDiv + Rem<Output = Self> + RemAssign {}
impl<T: MulDiv + Rem<Output = Self> + RemAssign> MulDivRem for T {}
pub trait IsSigned {
    const SIGNED: bool;
}

pub trait Signed: IsSigned {}

pub trait Unsigned: IsSigned {}

macro_rules! unsigned_impl {
    ($t: ident) => {
        impl Unsigned for $t {}

        impl IsSigned for $t {
            const SIGNED: bool = false;
        }
    };
}

unsigned_impl!(u128);
unsigned_impl!(u64);
unsigned_impl!(u32);
unsigned_impl!(u16);
unsigned_impl!(u8);
unsigned_impl!(usize);

macro_rules! signed_impl {
    ($t: ident) => {
        impl Signed for $t {}

        impl IsSigned for $t {
            const SIGNED: bool = true;
        }
    };
}

signed_impl!(i128);
signed_impl!(i64);
signed_impl!(i32);
signed_impl!(i16);
signed_impl!(i8);
signed_impl!(isize);
signed_impl!(f64);
signed_impl!(f32);
pub trait ZeroOne {
    fn zero() -> Self;
    fn one() -> Self;
}

macro_rules! zero_one_integer_impl {
    ($t: ident) => {
        impl ZeroOne for $t {
            fn zero() -> Self {
                0
            }

            fn one() -> Self {
                1
            }
        }
    };
}

zero_one_integer_impl!(i128);
zero_one_integer_impl!(i64);
zero_one_integer_impl!(i32);
zero_one_integer_impl!(i16);
zero_one_integer_impl!(i8);
zero_one_integer_impl!(isize);
zero_one_integer_impl!(u128);
zero_one_integer_impl!(u64);
zero_one_integer_impl!(u32);
zero_one_integer_impl!(u16);
zero_one_integer_impl!(u8);
zero_one_integer_impl!(usize);

macro_rules! zero_one_float_impl {
    ($t: ident) => {
        impl ZeroOne for $t {
            fn zero() -> Self {
                0.
            }

            fn one() -> Self {
                1.
            }
        }
    };
}

zero_one_float_impl!(f32);
zero_one_float_impl!(f64);

pub struct Input<'s> {
    input: &'s mut dyn Read,
    buf: Vec<u8>,
    at: usize,
    buf_read: usize,
}

impl<'s> Input<'s> {
    const DEFAULT_BUF_SIZE: usize = 4096;

    pub fn new(input: &'s mut dyn Read) -> Self {
        Self {
            input,
            buf: vec![0; Self::DEFAULT_BUF_SIZE],
            at: 0,
            buf_read: 0,
        }
    }

    pub fn new_with_size(input: &'s mut dyn Read, buf_size: usize) -> Self {
        Self {
            input,
            buf: vec![0; buf_size],
            at: 0,
            buf_read: 0,
        }
    }

    pub fn get(&mut self) -> Option<u8> {
        if self.refill_buffer() {
            let res = self.buf[self.at];
            self.at += 1;
            Some(res)
        } else {
            None
        }
    }

    pub fn peek(&mut self) -> Option<u8> {
        if self.refill_buffer() {
            Some(self.buf[self.at])
        } else {
            None
        }
    }

    pub fn skip_whitespace(&mut self) {
        while let Some(b) = self.peek() {
            if !char::from(b).is_whitespace() {
                return;
            }
            self.get();
        }
    }

    pub fn next_token(&mut self) -> Option<Vec<u8>> {
        self.skip_whitespace();
        let mut res = Vec::new();
        while let Some(c) = self.get() {
            if char::from(c).is_whitespace() {
                break;
            }
            res.push(c);
        }
        if res.is_empty() {
            None
        } else {
            Some(res)
        }
    }

    //noinspection RsSelfConvention
    pub fn is_exhausted(&mut self) -> bool {
        self.peek().is_none()
    }

    pub fn read<T: Readable>(&mut self) -> T {
        T::read(self)
    }

    pub fn read_vec<T: Readable>(&mut self, size: usize) -> Vec<T> {
        let mut res = Vec::with_capacity(size);
        for _ in 0usize..size {
            res.push(self.read());
        }
        res
    }

    pub fn read_line(&mut self) -> String {
        let mut res = String::new();
        while let Some(c) = self.get() {
            if c == b'\n' {
                break;
            }
            if c == b'\r' {
                if self.peek() == Some(b'\n') {
                    self.get();
                }
                break;
            }
            res.push(c.into());
        }
        res
    }

    #[allow(clippy::should_implement_trait)]
    pub fn into_iter<T: Readable>(self) -> InputIterator<'s, T> {
        InputIterator {
            input: self,
            phantom: Default::default(),
        }
    }

    fn read_integer<T: IsSigned + ZeroOne + FromU8 + AddSub + Multable + Display>(&mut self) -> T {
        self.skip_whitespace();
        let mut c = self.get().unwrap();
        let sgn = if c == b'-' {
            if !T::SIGNED {
                panic!("negative integer")
            }
            c = self.get().unwrap();
            true
        } else if c == b'+' {
            c = self.get().unwrap();
            false
        } else {
            false
        };
        let mut res = T::zero();
        loop {
            if !char::from(c).is_digit(10) {
                panic!(
                    "expected integer, found {}{}{}",
                    if sgn { "" } else { "-" },
                    res,
                    char::from(c)
                );
            }
            res *= T::from_u8(10);
            res += T::from_u8(c - b'0');
            match self.get() {
                None => {
                    break;
                }
                Some(ch) => {
                    if char::from(ch).is_whitespace() {
                        break;
                    } else {
                        c = ch;
                    }
                }
            }
        }
        if sgn {
            debug_assert!(T::SIGNED);
            res = T::zero() - res
        }
        res
    }

    fn read_string(&mut self) -> String {
        match self.next_token() {
            None => {
                panic!("Input exhausted");
            }
            Some(res) => unsafe { String::from_utf8_unchecked(res) },
        }
    }

    fn read_char(&mut self) -> char {
        self.skip_whitespace();
        self.get().unwrap().into()
    }

    fn read_float(&mut self) -> f64 {
        self.read_string().parse().unwrap()
    }

    fn refill_buffer(&mut self) -> bool {
        if self.at == self.buf_read {
            self.at = 0;
            self.buf_read = self.input.read(&mut self.buf).unwrap();
            self.buf_read != 0
        } else {
            true
        }
    }
}

pub trait Readable {
    fn read(input: &mut Input) -> Self;
}

impl Readable for String {
    fn read(input: &mut Input) -> Self {
        input.read_string()
    }
}

impl Readable for char {
    fn read(input: &mut Input) -> Self {
        input.read_char()
    }
}

impl Readable for f64 {
    fn read(input: &mut Input) -> Self {
        input.read_float()
    }
}

impl<T: Readable> Readable for Vec<T> {
    fn read(input: &mut Input) -> Self {
        let size = input.read();
        input.read_vec(size)
    }
}

pub struct InputIterator<'s, T: Readable> {
    input: Input<'s>,
    phantom: PhantomData<T>,
}

impl<'s, T: Readable> Iterator for InputIterator<'s, T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.input.skip_whitespace();
        self.input.peek().map(|_| self.input.read())
    }
}

macro_rules! read_integer {
    ($t:ident) => {
        impl Readable for $t {
            fn read(input: &mut Input) -> Self {
                input.read_integer()
            }
        }
    };
}

read_integer!(i8);
read_integer!(i16);
read_integer!(i32);
read_integer!(i64);
read_integer!(i128);
read_integer!(isize);
read_integer!(u8);
read_integer!(u16);
read_integer!(u32);
read_integer!(u64);
read_integer!(u128);
read_integer!(usize);

macro_rules! tuple_readable {
    ( $( $name:ident )+ ) => {
        impl<$($name: Readable), +> Readable for ($($name,)+) {
            fn read(input: &mut Input) -> Self {
                ($($name::read(input),)+)
            }
        }
    }
}

tuple_readable! {T}
tuple_readable! {T U}
tuple_readable! {T U V}
tuple_readable! {T U V X}
tuple_readable! {T U V X Y}
tuple_readable! {T U V X Y Z}
tuple_readable! {T U V X Y Z A}
tuple_readable! {T U V X Y Z A B}
tuple_readable! {T U V X Y Z A B C}
tuple_readable! {T U V X Y Z A B C D}
tuple_readable! {T U V X Y Z A B C D E}
tuple_readable! {T U V X Y Z A B C D E F}

pub struct Output {
    output: Box<dyn Write>,
    buf: Vec<u8>,
    at: usize,
    auto_flush: bool,
}

impl Output {
    const DEFAULT_BUF_SIZE: usize = 4096;

    pub fn new(output: Box<dyn Write>) -> Self {
        Self {
            output,
            buf: vec![0; Self::DEFAULT_BUF_SIZE],
            at: 0,
            auto_flush: false,
        }
    }

    pub fn new_with_auto_flush(output: Box<dyn Write>) -> Self {
        Self {
            output,
            buf: vec![0; Self::DEFAULT_BUF_SIZE],
            at: 0,
            auto_flush: true,
        }
    }

    pub fn flush(&mut self) {
        if self.at != 0 {
            self.output.write_all(&self.buf[..self.at]).unwrap();
            self.at = 0;
        }
    }

    pub fn print<T: Writable>(&mut self, s: &T) {
        s.write(self);
    }

    pub fn put(&mut self, b: u8) {
        self.buf[self.at] = b;
        self.at += 1;
        if self.at == self.buf.len() {
            self.flush();
        }
    }

    pub fn maybe_flush(&mut self) {
        if self.auto_flush {
            self.flush();
        }
    }

    pub fn print_per_line<T: Writable>(&mut self, arg: &[T]) {
        for i in arg {
            i.write(self);
            self.put(b'\n');
        }
    }

    pub fn print_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
        let mut first = true;
        for e in iter {
            if first {
                first = false;
            } else {
                self.put(b' ');
            }
            e.write(self);
        }
    }

    pub fn print_iter_ref<'a, T: 'a + Writable, I: Iterator<Item = &'a T>>(&mut self, iter: I) {
        let mut first = true;
        for e in iter {
            if first {
                first = false;
            } else {
                self.put(b' ');
            }
            e.write(self);
        }
    }
}

impl Write for Output {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        let mut start = 0usize;
        let mut rem = buf.len();
        while rem > 0 {
            let len = (self.buf.len() - self.at).min(rem);
            self.buf[self.at..self.at + len].copy_from_slice(&buf[start..start + len]);
            self.at += len;
            if self.at == self.buf.len() {
                self.flush();
            }
            start += len;
            rem -= len;
        }
        if self.auto_flush {
            self.flush();
        }
        Ok(buf.len())
    }

    fn flush(&mut self) -> std::io::Result<()> {
        self.flush();
        Ok(())
    }
}

pub trait Writable {
    fn write(&self, output: &mut Output);
}

impl Writable for &str {
    fn write(&self, output: &mut Output) {
        output.write_all(self.as_bytes()).unwrap();
    }
}

impl Writable for String {
    fn write(&self, output: &mut Output) {
        output.write_all(self.as_bytes()).unwrap();
    }
}

impl Writable for char {
    fn write(&self, output: &mut Output) {
        output.put(*self as u8);
    }
}

impl<T: Writable> Writable for [T] {
    fn write(&self, output: &mut Output) {
        output.print_iter_ref(self.iter());
    }
}

impl<T: Writable> Writable for Vec<T> {
    fn write(&self, output: &mut Output) {
        self[..].write(output);
    }
}

macro_rules! write_to_string {
    ($t:ident) => {
        impl Writable for $t {
            fn write(&self, output: &mut Output) {
                self.to_string().write(output);
            }
        }
    };
}

write_to_string!(u8);
write_to_string!(u16);
write_to_string!(u32);
write_to_string!(u64);
write_to_string!(u128);
write_to_string!(usize);
write_to_string!(i8);
write_to_string!(i16);
write_to_string!(i32);
write_to_string!(i64);
write_to_string!(i128);
write_to_string!(isize);
write_to_string!(f32);
write_to_string!(f64);

impl<T: Writable, U: Writable> Writable for (T, U) {
    fn write(&self, output: &mut Output) {
        self.0.write(output);
        output.put(b' ');
        self.1.write(output);
    }
}

impl<T: Writable, U: Writable, V: Writable> Writable for (T, U, V) {
    fn write(&self, output: &mut Output) {
        self.0.write(output);
        output.put(b' ');
        self.1.write(output);
        output.put(b' ');
        self.2.write(output);
    }
}

pub static mut OUTPUT: Option<Output> = None;

pub fn output() -> &'static mut Output {
    unsafe {
        match &mut OUTPUT {
            None => {
                panic!("Panic");
            }
            Some(output) => output,
        }
    }
}

#[macro_export]
macro_rules! out {
    ($first: expr $(,$args:expr )*) => {
        output().print(&$first);
        $(output().put(b' ');
        output().print(&$args);
        )*
    }
}

#[macro_export]
macro_rules! out_line {
    ($first: expr $(, $args:expr )* ) => {
        out!($first $(,$args)*);
        output().put(b'\n');
    };
    () => {
        output().put(b'\n');
    };
}

fn solve(input: &mut Input, _test_case: usize) {
    let x: u64 = input.read();
    let y: u64 = input.read();

    let mut x_str = format!("{:b}", x);
    let y_str = format!("{:b}", y);

    if y % 2 == 0 && x != y {
        out_line!("NO");
        return;
    }

    if y_str.contains(&x_str)
        && y.count_ones() - x.count_ones() == (y_str.len() - x_str.len()) as u32
    {
        out_line!("YES");
        return;
    }
    if y_str.contains(&x_str.chars().rev().collect::<String>())
        && y.count_ones() - x.count_ones() == (y_str.len() - x_str.len()) as u32
    {
        out_line!("YES");
        return;
    }
    while x_str.ends_with("0") {
        x_str.pop();
    }
    if y_str.contains(&x_str)
        && y.count_ones() - x.count_ones() == (y_str.len() - x_str.len()) as u32
    {
        out_line!("YES");
        return;
    }
    if y_str.contains(&x_str.chars().rev().collect::<String>())
        && y.count_ones() - x.count_ones() == (y_str.len() - x_str.len()) as u32
    {
        out_line!("YES");
        return;
    }
    out_line!("NO");
}

pub(crate) fn run(mut input: Input) -> bool {
    solve(&mut input, 1);
    output().flush();
    input.skip_whitespace();
    !input.peek().is_some()
}

fn main() {
    let mut sin = std::io::stdin();
    let input = Input::new(&mut sin);
    unsafe {
        OUTPUT = Some(Output::new(Box::new(std::io::stdout())));
    }
    run(input);
}


// -------- begin template --------

#![allow(
    dead_code, unused_imports, unused_variables,
    unused_must_use, unused_macros, unused_mut, unused_assignments
)]

use std::io::{self, Read, Write};
use std::cmp::{min, max};
use std::mem::swap;
use std::collections::{VecDeque, HashMap, HashSet, BTreeSet};

macro_rules! dbg {
    ($first_val:expr, $($val:expr),+ $(,)?) => {
        eprint!("[{}:{}] {} = {:?}",
                    file!(), line!(), stringify!($first_val), &$first_val);
        ($(eprint!(", {} = {:?}", stringify!($val), &$val)),+,);
        eprintln!();
    };
    ($first_val:expr) => {
        eprintln!("[{}:{}] {} = {:?}",
                    file!(), line!(), stringify!($first_val), &$first_val);
    };
}

enum InputSource {
    Stdin,
    FromFile(Vec<String>),
}

struct Scanner {
    buffer: Vec<String>,
    input_source: InputSource,
}

impl Scanner {
    fn new() -> Self {
        Self {
            buffer: vec![],
            input_source: InputSource::Stdin,
        }
    }

    fn new_file(filename: &str) -> Self {
        let file = std::fs::read_to_string(filename).unwrap();
        let mut lines: Vec<String> = file.lines().map(|line| String::from(line)).collect();
        lines.reverse();
        Self {
            buffer: vec![],
            input_source: InputSource::FromFile(lines),
        }
    }

    fn usize(&mut self) -> usize { self.next::<usize>() }
    fn bytes(&mut self) -> Vec<u8> { self.next::<String>().into_bytes() }
    fn chars(&mut self) -> Vec<char> { self.next::<String>().chars().collect() }
    fn string(&mut self) -> String { self.next::<String>() }
    fn i64(&mut self) -> i64 { self.next::<i64>() }
    fn f64(&mut self) -> f64 { self.next::<f64>() }
    fn i32(&mut self) -> i32 { self.next::<i32>() }
    fn f32(&mut self) -> f32 { self.next::<f32>() }

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

    fn parse_next_line(&mut self) -> bool {
        let mut input = String::new();
        match &mut self.input_source {
            InputSource::Stdin => {
                if std::io::stdin().read_line(&mut input).expect("Failed read") == 0 {
                    return false;
                }
            }
            InputSource::FromFile(lines) => match lines.pop() {
                Some(line) => input = line,
                None => return false,
            },
        }

        self.buffer = input.split_whitespace().rev().map(String::from).collect();
        return true;
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            self.parse_next_line();
        }
    }

    fn has_more_elements(&mut self) -> bool {
        loop {
            if !self.buffer.is_empty() { return true; }
            if !self.parse_next_line() { return false; }
        }
    }
}

// -------- end template --------

fn to2(x: i64) -> Vec<i64> {
    let mut res: Vec<i64> = Vec::new();
    let mut tmp = x;
    while tmp > 0 {
        res.push(tmp & 1);
        tmp >>= 1;
    }
    res.reverse();
    res
}

fn to10(d: &Vec<i64>) -> i64 {
    if d.len() > 60 {
        return 0;
    }
    let (mut exp, mut res) = (1, 0);
    for i in (0..d.len()).rev() {
        if d[i] == 1 {
            res += exp;
        }
        exp *= 2;
    }
    res
}

fn go(x: i64, d: i64) -> i64 {
    let mut a = to2(x);
    a.push(d);
    a.reverse();
    to10(&a)
}

fn solve(x: i64, y: i64) -> bool {
    let mut q: VecDeque<i64> = VecDeque::new();
    let mut vis: HashSet<i64> = HashSet::new();
    q.push_back(x);
    while let Some(cur) = q.pop_front() {
        if cur == 0 { continue; }
        if vis.contains(&cur) { continue; }
        vis.insert(cur);
        if cur == y { return true; }

        q.push_back(go(cur, 0));
        q.push_back(go(cur, 1));
    }
    false
}

fn main() {
    let stdout = io::stdout();
    let mut out = std::io::BufWriter::new(stdout.lock());
    let mut sc = Scanner::new();

    let (x, y) = (sc.i64(), sc.i64());
    writeln!(out, "{}", if solve(x, y) { "YES" } else { "NO "});
}


#[allow(unused_imports)]
use std::cmp::{max, min};
use std::{io, io::prelude::*, str};

struct IO<'a> {
    reader: io::StdinLock<'a>,
    buffer: Vec<String>,
    out: io::BufWriter<io::Stdout>,
}
impl<'a> IO<'a> {
    fn new(reader: io::StdinLock<'a>, stdout: io::Stdout) -> Self {
        Self {
            reader,
            buffer: vec![],
            out: io::BufWriter::new(stdout),
        }
    }

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

    #[allow(dead_code)]
    fn read_vec<T: str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }

    #[allow(dead_code)]
    fn read_str(&mut self) -> Vec<u8> {
        self.read::<String>().into_bytes()
    }
}

fn to_bits(mut x: u64) -> Vec<bool> {
    let mut res = vec![];
    while x > 0 {
        res.push(if x & 1 > 0 { true } else { false });
        x >>= 1;
    }
    res.reverse();
    res
}

// 10100
// 1001011111
// 1001011111

fn all_ones(a: &[bool]) -> bool {
    a.iter().all(|&x| x)
}

fn contains(src: &[bool], a: &[bool]) -> bool {
    let n = src.len();
    let m = a.len();
    if m > n {
        return false;
    }

    for i in 0..=(n - m) {
        if &src[i..i + m] == a && all_ones(&src[0..i]) && all_ones(&src[i + m..]) {
            return true;
        }
    }

    false
}

fn main() -> io::Result<()> {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut io = IO::new(stdin.lock(), stdout);

    let (x, y): (u64, u64) = (io.read(), io.read());
    let mut x = to_bits(x);
    let y = to_bits(y);

    let mut ok = x == y;
    if !ok {
        x.push(true);
        ok = contains(&y, &x) || contains(&y, &x.iter().cloned().rev().collect::<Vec<bool>>());
        x.pop();
    }
    if !ok {
        while !*x.last().unwrap() {
            x.pop();
        }
        ok = contains(&y, &x) || contains(&y, &x.iter().cloned().rev().collect::<Vec<bool>>());
    }

    if ok {
        writeln!(io.out, "YES")?;
    } else {
        writeln!(io.out, "NO")?;
    }

    Ok(())
}


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

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read_line()
        .trim()
        .split_whitespace()
        .filter_map(|i| i.parse().ok())
        .collect()
}

fn bitrev(mut x: u64) -> u64 {
    let mut y = 0u64;
    while x > 0 {
        y <<= 1;
        y |= x & 1;
        x >>= 1;
    }
    y
}

fn check(x: u64, mut y: u64) -> bool {
    let mut m = 0;
    while x & ((1 << m) - 1) < x {
        m += 1
    }
    while y > 0 {
        if y & ((1 << m) - 1) == x {
            y >>= m;
            return y & (y + 1) == 0;
        } else if y & 1 == 0 {
            return false;
        } else {
            y >>= 1;
        }
    }
    false
}

fn main() {
    let xy = read_vec::<u64>();
    let (x, y) = (xy[0], xy[1]);
    let mut xx = x;
    while xx & 1 == 0 {
        xx >>= 1
    }
    if x == y
        || check(xx, y)
        || check(bitrev(xx), y)
        || check(x * 2 + 1, y)
        || check(bitrev(x * 2 + 1), y)
    {
        println!("YES")
    } else {
        println!("NO")
    }
}


#![allow(dead_code, unused_imports)]
#[rustfmt::skip] mod num {use std::convert::{TryFrom, TryInto};use std::ops::{Add, Div, Mul, Rem, Sub};pub trait Num: Ord + Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self> + FromPrimitive + IntoPrimitive + Sized {  fn zero() -> Self;fn one() -> Self;}  pub trait FromPrimitive: Sized {  fn from_u64(x: u64) -> Option<Self>;fn from_i64(x: i64) -> Option<Self>;fn from_usize(x: usize) -> Option<Self> { Self::from_u64(x as u64) }  fn from_isize(x: isize) -> Option<Self> { Self::from_i64(x as i64) } }  pub trait IntoPrimitive {  fn as_u64(&self) -> Option<u64>;fn as_i64(&self) -> Option<i64>;fn as_usize(&self) -> Option<usize> { self.as_u64().and_then(|x| x.try_into().ok()) }  fn as_isize(&self) -> Option<isize> { self.as_i64().and_then(|x| x.try_into().ok()) } }       pub trait Integer: Num {  fn idiv(&self, x: &Self) -> Self;fn imod(&self, x: &Self) -> Self;fn iabs(&self) -> Self;}  macro_rules! generate_integer_impl_for_primitive { ($( ($ty:ty, $unsigned:tt) ),+) => { $( impl FromPrimitive for $ty { #[inline(always)] fn from_u64(x: u64) -> Option<Self> { <$ty>::try_from(x).ok() } #[inline(always)] fn from_i64(x: i64) -> Option<Self> { <$ty>::try_from(x).ok() } }  impl IntoPrimitive for $ty { #[inline(always)] fn as_u64(&self) -> Option<u64> { u64::try_from(*self).ok() } #[inline(always)] fn as_i64(&self) -> Option<i64> { i64::try_from(*self).ok() } }  impl Num for $ty { #[inline(always)] fn zero() -> Self { 0 } #[inline(always)] fn one() -> Self { 1 } }  impl Integer for $ty { #[inline(always)] fn idiv(&self, x: &Self) -> Self { self.div_euclid(*x) } #[inline(always)] fn imod(&self, x: &Self) -> Self { self.rem_euclid(*x) } generate_iabs_impl!($unsigned);} )+ };}  macro_rules! generate_iabs_impl { (true) => { #[inline(always)] fn iabs(&self) -> Self { *self } };(false) => { #[inline(always)] fn iabs(&self) -> Self { self.abs() } };}  generate_integer_impl_for_primitive!( (u8, true), (u16, true), (u32, true), (u64, true), (u128, true), (usize, true), (i8, false), (i16, false), (i32, false), (i64, false), (i128, false), (isize, false) );}
#[rustfmt::skip] mod combinatorics {use crate::{num::Integer, number_theory::mod_mulinv};pub fn next_permutation<T>(perm: &mut [T]) -> bool where T: Ord, { if perm.is_empty() { return false;}   let i = match Iterator::zip(perm.iter(), perm[1..].iter()).rposition(|(x, y)| x < y) { None => {  perm.reverse();return false;} Some(x) => x, };let j = perm .iter() .rposition(|x| &perm[i] < x) .expect("inconsistent Ord implementation");perm.swap(i, j);perm[i + 1..].reverse();true }       #[derive(Debug, Clone)]  pub struct Factorials<N> { m: N, fact: Vec<N>, fact_inv: Vec<N>, }  impl<N> Factorials<N> where N: Integer + Clone, { #[inline] fn as_n(x: usize) -> N { N::from_usize(x).expect("inconsistent Integer implementation") } #[inline] fn as_usize(x: &N) -> usize { N::as_usize(x).expect("inconsistent Integer implementation") }      #[track_caller] pub fn new(n: N, m: N) -> Self { let cap = n .as_usize() .and_then(|x| x.checked_add(1)) .expect("required capacity overflowed usize");assert!(cap > 0, "n must be non-negative");let mut fact = Vec::with_capacity(cap);fact.push(N::one());let mut cur = N::one();for i in 1..cap { cur = (cur * Self::as_n(i)).imod(&m);fact.push(cur.clone());}   let mut fact_inv = Vec::with_capacity(cap);let mut cur = mod_mulinv(fact[cap - 1].clone(), m.clone());for i in (0..cap).rev() { fact_inv.push(cur.clone());cur = (cur * Self::as_n(i)).imod(&m);} fact_inv.reverse();debug_assert_eq!(fact.len(), cap);debug_assert_eq!(fact_inv.len(), cap);Factorials { m, fact, fact_inv } }   pub fn len(&self) -> usize { self.fact.len() }    pub fn is_empty(&self) -> bool { false }   pub fn n(&self) -> N { Self::as_n(self.fact.len() - 1) }   #[track_caller] fn verify_n<'a>(&self, n: &'a N) -> &'a N { assert!( N::zero() <= *n && *n <= self.n(), "n is outside precomputed range" );n }     #[track_caller] pub fn factorial(&self, n: &N) -> N { let n = self.verify_n(n);self.fact[Self::as_usize(n)].clone() }     #[track_caller] pub fn factorial_inverse(&self, n: &N) -> N { let n = self.verify_n(n);self.fact_inv[Self::as_usize(n)].clone() }     #[track_caller] pub fn choose(&self, n: N, k: N) -> N { self.verify_n(&n);assert!(k >= N::zero(), "k is negative");if k <= n {  ((self.fact[Self::as_usize(&n)].clone() * self.fact_inv[Self::as_usize(&k)].clone()) .imod(&self.m) * self.fact_inv[Self::as_usize(&(n - k))].clone()) .imod(&self.m) } else { N::zero() } } } }
#[rustfmt::skip] mod util {   pub trait IntoVec<T, _Hack> { fn into_vec(self) -> Vec<T>;}  #[non_exhaustive] pub struct Owned;impl<I, T> IntoVec<T, Owned> for I where I: Iterator<Item = T>, { fn into_vec(self) -> Vec<T> { self.collect() } }  #[non_exhaustive] pub struct Reference;impl<'a, I, T> IntoVec<T, Reference> for I where I: Iterator<Item = &'a T>, T: Clone + 'a, { fn into_vec(self) -> Vec<T> { self.cloned().collect() } }  pub trait Argmax { fn argmax(self) -> Option<usize>;}  impl<I> Argmax for I where I: Iterator, I::Item: Ord, { fn argmax(self) -> Option<usize> { self.fold((0, None), |(i, mx), next| { if let Some((mx_i, mx_v)) = mx { if next.gt(&mx_v) { (i + 1, Some((i, next))) } else { (i + 1, Some((mx_i, mx_v))) } } else { (i + 1, Some((i, next))) } }) .1 .map(|x| x.0) } }  pub trait Sorted { fn sorted(self) -> Self;}  impl<T> Sorted for Vec<T> where T: Ord, { fn sorted(mut self) -> Self { self.sort();self } }  pub trait Choose { fn choose<T>(self, a: T, b: T) -> T;fn choose_by<T>(self, a: impl FnOnce() -> T, b: impl FnOnce() -> T) -> T;}  impl Choose for bool { fn choose<T>(self, a: T, b: T) -> T { if self { a } else { b } }  fn choose_by<T>(self, a: impl FnOnce() -> T, b: impl FnOnce() -> T) -> T { if self { a() } else { b() } } }  #[macro_export] macro_rules! p { ( $( $x:expr ),* ) => { #[cfg(any(debug_assertions, debug_print))] { dbg!( $( & $x, )* );} };}  pub fn fix<A, R>(f: &dyn Fn(&dyn Fn(A) -> R, A) -> R) -> impl Fn(A) -> R + '_ { move |arg| f(&fix(&f), arg) } }
#[rustfmt::skip] mod scanner {use std::fmt::Debug;use std::io::{stdin, BufReader, Bytes, Error as IoError, Read, Stdin};use std::str::{self, FromStr, Utf8Error};#[derive(Debug)] pub struct Scanner<R: Read> { bytes: Bytes<BufReader<R>>, buf: Vec<u8>, }  #[derive(Debug)] pub enum ScanError<T: FromStr> { Io(IoError), Parse(T::Err, String), NonUtf8(Utf8Error, Vec<u8>), }  impl Scanner<Stdin> { pub fn stdin() -> Self { Self::new(stdin()) } }  impl<R: Read> Scanner<R> { pub fn new(reader: R) -> Self { Self { bytes: BufReader::new(reader).bytes(), buf: Vec::new(), } }  pub fn read<T: FromStr>(&mut self) -> Result<T, ScanError<T>> { debug_assert!(self.buf.is_empty());for b in &mut self.bytes { let b = b.map_err(ScanError::Io)?;if b.is_ascii_whitespace() {  if self.buf.is_empty() { continue;} else { break;} } else { self.buf.push(b);} }   match str::from_utf8(&self.buf) { Err(err) => Err(ScanError::NonUtf8(err, std::mem::take(&mut self.buf))), Ok(s) => { let ret = s.parse().map_err(|err| ScanError::Parse(err, s.to_owned()));self.buf.clear();ret } } } }  #[macro_use] pub mod macros { use super::*;use std::fmt::{self, Debug};use std::io::Read;use std::marker::PhantomData;use std::num::NonZeroUsize;use std::str::FromStr;pub trait ScanCmd { type Target;type Err;fn scan_from<R: Read>(scanner: &mut Scanner<R>) -> Result<Self::Target, Self::Err>;}     pub struct UsizeM1(());impl ScanCmd for UsizeM1 { type Target = usize;type Err = ScanError<NonZeroUsize>;fn scan_from<R: Read>(scanner: &mut Scanner<R>) -> Result<Self::Target, Self::Err> { Ok(scanner.read::<NonZeroUsize>()?.get() - 1) } }   pub struct LenArray<T>(PhantomData<T>);impl<T: FromStr> ScanCmd for LenArray<T> { type Target = Vec<T>;type Err = LenArrayScanError<T>;fn scan_from<R: Read>(scanner: &mut Scanner<R>) -> Result<Self::Target, Self::Err> { let len = scanner.read::<usize>().map_err(LenArrayScanError::Len)?;let mut arr = Vec::with_capacity(len);for i in 0..len { let elem = scanner .read::<T>() .map_err(|e| LenArrayScanError::Data(i, e))?;arr.push(elem);} Ok(arr) } }  pub enum LenArrayScanError<T: FromStr> { Len(ScanError<usize>), Data(usize, ScanError<T>), }  impl<T> Debug for LenArrayScanError<T> where T: Debug + FromStr, T::Err: Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use self::LenArrayScanError::*;match self { Len(e) => f.debug_tuple("Len").field(e).finish(), Data(i, e) => f.debug_tuple("Data").field(i).field(e).finish(), } } }  #[macro_export] macro_rules! scan { (@scan 1 $scan:expr, $type:ty) => { $scan .read::<$type>() .expect(concat!("failed to read token of type ", stringify!($type))) };(@scan 2 $scan:expr, $type:ty, $n:expr) => { (0..$n) .map(|_| scan!(@scan 1 $scan, $type)) .collect::<Vec<_>>() };(@scan 3 $scan:expr, $type:ty) => { <$type as ScanCmd>::scan_from(&mut $scan) .expect(concat!("failed to read token of type ", stringify!($type))) };(@scan 4 $scan:expr, $type:ty, $n:expr) => { (0..$n) .map(|_| scan!(@scan 3 $scan, $type)) .collect::<Vec<_>>() };(@accum ($scan:expr) () -> ($($body:tt)*)) => { ($($body)*) };(@accum ($scan:expr) ($type:ty) -> ($($body:tt)*)) => { scan!(@accum ($scan) () -> ($($body)* scan!(@scan 1 $scan, $type))) };(@accum ($scan:expr) ($type:ty, $($next:tt)*) -> ($($body:tt)*)) => { scan!(@accum ($scan) ($($next)*) -> ($($body)* scan!(@scan 1 $scan, $type),)) };(@accum ($scan:expr) ($n:tt * $type:ty) -> ($($body:tt)*)) => { scan!(@accum ($scan) () -> ($($body)* scan!(@scan 2 $scan, $type, $n))) };(@accum ($scan:expr) ($n:tt * $type:ty, $($next:tt)*) -> ($($body:tt)*)) => { scan!(@accum ($scan) ($($next)*) -> ($($body)* scan!(@scan 2 $scan, $type, $n),)) };(@accum ($scan:expr) (~$type:ty) -> ($($body:tt)*)) => { scan!(@accum ($scan) () -> ($($body)* scan!(@scan 3 $scan, $type))) };(@accum ($scan:expr) (~$type:ty, $($next:tt)*) -> ($($body:tt)*)) => { scan!(@accum ($scan) ($($next)*) -> ($($body)* scan!(@scan 3 $scan, $type),)) };(@accum ($scan:expr) ($n:tt * ~$type:ty) -> ($($body:tt)*)) => { scan!(@accum ($scan) () -> ($($body)* scan!(@scan 4 $scan, $type, $n))) };(@accum ($scan:expr) ($n:tt * ~$type:ty, $($next:tt)*) -> ($($body:tt)*)) => { scan!(@accum ($scan) ($($next)*) -> ($($body)* scan!(@scan 4 $scan, $type, $n),)) };($scan:expr, $($arg:tt)+) => { scan!(@accum ($scan) ($($arg)+) -> ()) };} } }
#[rustfmt::skip] mod number_theory {use crate::num::Integer;use std::mem;pub fn gcd<N: Integer>(mut a: N, mut b: N) -> N { while b != N::zero() { mem::swap(&mut a, &mut b);b = b.imod(&a);} a.iabs() }      #[allow(clippy::many_single_char_names)] pub fn egcd<N: Integer + Clone>(a: N, b: N) -> (N, N, N) { if b == N::zero() { ( a.iabs(), if a >= N::zero() { N::one() } else { N::zero() - N::one() }, N::zero(), ) } else { let (g, s, t) = egcd(b.clone(), a.imod(&b));(g, t.clone(), s - a.idiv(&b) * t) } }       #[track_caller] pub fn mod_exp<N: Integer + Clone>(a: N, mut b: N, m: N) -> N { let zero = N::zero();let one = N::one();let two = N::one() + N::one();assert!(m > zero, "modulus must be positive");if b < zero { return mod_exp(mod_mulinv(a, m.clone()), zero - b, m);}  let mut x = N::one();let mut pwr = a;while b > N::zero() { if b.imod(&two) == one { x = (x * pwr.clone()).imod(&m);} pwr = (pwr.clone() * pwr).imod(&m);b = b.idiv(&two);} x }      #[track_caller] pub fn mod_mulinv<N: Integer + Clone>(a: N, m: N) -> N { let zero = N::zero();let one = N::one();assert!(m > zero, "modulus must be positive");let (g, s, _) = egcd(a, m.clone());assert!(g == one, "multiplicative inverse does not exist");s.imod(&m) }         #[derive(Debug, Clone)]   pub struct PrimeSieve<N> { lowest_factor: Vec<N>, primes: Vec<N>, }  impl<N> PrimeSieve<N> where N: Integer + Clone, { #[inline] fn as_n(x: usize) -> N { N::from_usize(x).expect("inconsistent Integer implementation") } #[inline] fn as_usize(x: &N) -> usize { N::as_usize(x).expect("inconsistent Integer implementation") }     #[track_caller] pub fn new(n: N) -> Self { let cap = n .as_usize() .and_then(|x| x.checked_add(1)) .expect("capacity overflowed usize");assert!(cap > 0, "n must be non-negative");let mut lowest_factor = vec![N::zero(); cap];let mut primes = vec![];for i in 2..cap { if lowest_factor[i] == N::zero() { lowest_factor[i] = Self::as_n(i);primes.push(Self::as_n(i));}    let lowest_factor_i = lowest_factor[i].clone();for (p, p_usize) in primes .iter() .map(|p| (p, Self::as_usize(p))) .take_while(|(p, p_usize)| i * p_usize < cap && p <= &&lowest_factor_i) { lowest_factor[i * p_usize] = p.clone();} }  PrimeSieve { lowest_factor, primes, } }   pub fn len(&self) -> usize { self.lowest_factor.len() }    pub fn is_empty(&self) -> bool { false }   pub fn n(&self) -> N { Self::as_n(self.lowest_factor.len() - 1) }      #[track_caller] pub fn is_prime(&self, x: &N) -> bool { assert!(*x >= N::zero(), "x must be non-negative");let n = self.n();if *x <= n { *x > N::zero() && self.lowest_factor[Self::as_usize(x)] == *x } else if *x <= n.clone() * n { for p in self.primes.iter() { if x.imod(p) == N::zero() { return false;} } true } else { panic!("unable to determine primality: x > n^2");} }       #[track_caller] pub fn lowest_factor(&self, x: &N) -> N { assert!(*x >= N::zero(), "x must be non-negative");let n = self.n();if *x <= n { self.lowest_factor[Self::as_usize(x)].clone() } else if *x <= n.clone() * n { for p in self .primes .iter() .take_while(|&p| p.clone() * p.clone() <= *x) { if x.imod(p) == N::zero() { return p.clone();} } x.clone() } else { panic!("unable to determine lowest factor: x > n^2",) } }      #[track_caller] pub fn factorize(&self, mut x: N) -> Vec<N> { let n = self.n();assert!(x > N::zero(), "cannot factorize non-positive numbers");assert!(x <= n.clone() * n.clone(), "unable to factorize: x > n^2",);let mut factors = Vec::new();let x2 = x.clone();let mut primes = self .primes .iter() .take_while(|&p| p.clone() * p.clone() <= x2);while x > N::one() { if x <= n { let f = &self.lowest_factor[Self::as_usize(&x)];factors.push(f.clone());x = x.idiv(f);} else if let Some(p) = primes.next() { while x.imod(p) == N::zero() { factors.push(p.clone());x = x.idiv(p);} } else {  factors.push(x);break;} } factors } } }
#[rustfmt::skip] mod writer {use std::fmt::Display;use std::io::{stdout, BufWriter, Error as IoError, Stdout, Write};#[derive(Debug)] pub struct Writer<W: Write> { writer: BufWriter<W>, }  #[derive(Debug, Clone)] pub struct Format<'a> {  separator: &'a str,  ending: &'a str, }  impl<'a> Format<'a> { pub fn separator(self, separator: &'a str) -> Self { Self { separator, ..self } }  pub fn ending(self, ending: &'a str) -> Self { Self { ending, ..self } } }  impl Default for Format<'_> { fn default() -> Self { Format { separator: " ", ending: "\n", } } }  impl Writer<Stdout> { pub fn stdout() -> Self { Self::new(stdout()) } }  impl<W: Write> Writer<W> { pub fn new(writer: W) -> Self { Self { writer: BufWriter::new(writer), } }  pub fn write<M, T: Writable<M>>(&mut self, val: T) -> Result<(), IoError> { self.write_with(val, &Format::default()) }  pub fn write_with<M, T: Writable<M>>(&mut self, val: T, fmt: &Format) -> Result<(), IoError> { val.write_to(&mut self.writer, fmt) }  pub fn flush(&mut self) -> Result<(), IoError> { self.writer.flush() } }  pub trait Writable<Mode> { fn write_to<W: Write>(self, w: &mut W, fmt: &Format) -> Result<(), IoError>;}  #[non_exhaustive] pub struct Single;impl<T: Display> Writable<Single> for T { fn write_to<W: Write>(self, w: &mut W, fmt: &Format) -> Result<(), IoError> { write!(w, "{}{}", self, fmt.ending) } }  #[non_exhaustive] pub struct Many;impl<I> Writable<Many> for I where I: Iterator, I::Item: Display, { fn write_to<W: Write>(mut self, w: &mut W, fmt: &Format) -> Result<(), IoError> { if let Some(x) = self.next() { write!(w, "{}", x)?;} else {  return Ok(());}  for x in self { write!(w, "{}{}", fmt.separator, x)?;} write!(w, "{}", fmt.ending) } }  #[non_exhaustive] pub struct Slice;impl<T: Display> Writable<Slice> for &[T] { fn write_to<W: Write>(self, w: &mut W, fmt: &Format) -> Result<(), IoError> { self.iter().write_to(w, fmt) } }  #[macro_export]   macro_rules! out { ($writer:expr, $val:expr) => { $writer.write($val).expect("failed to write token");};($writer:expr, $val:expr, $($builder_name:ident = $value:expr),+) => { let mut fmt = Format::default();$( fmt = fmt.$builder_name($value);)+ $writer.write_with($val, &fmt).expect("failed to write token");};} }
#[rustfmt::skip] mod prefix_sum {use std::{ fmt::{self, Debug, Formatter}, marker::PhantomData, ops::{Add, Bound, Range, RangeBounds, Sub}, };#[derive(Clone)] pub struct PrefixOp<T, F, I> { fwd: F, inv: Option<I>, marker: PhantomData<fn(&T, &T) -> T>, }  impl<T, F> PrefixOp<T, F, ()> where F: Fn(&T, &T) -> T, {  pub fn new(op: F) -> Self { PrefixOp { fwd: op, inv: None, marker: PhantomData, } } }  impl<T, F, I> PrefixOp<T, F, I> where F: Fn(&T, &T) -> T, I: Fn(&T, &T) -> T, {     pub fn new_invertible(op: F, inverse: I) -> Self { PrefixOp { fwd: op, inv: Some(inverse), marker: PhantomData, } } }  impl<T, F, I> PrefixOp<T, F, I> where F: Fn(&T, &T) -> T, I: Clone, {  pub fn build(&self, mut arr: Vec<T>) -> PrefixArray<T, F, I> { for i in 1..arr.len() { arr[i] = (self.fwd)(&arr[i - 1], &arr[i]);} PrefixArray { pref: arr, fwd: PhantomData, inv: self.inv.clone(), } } }        #[derive(Clone)] pub struct PrefixArray<T, F, I> { pref: Vec<T>,   fwd: PhantomData<F>, inv: Option<I>, }  impl<T, F, I> PrefixArray<T, F, I> {  pub fn len(&self) -> usize { self.pref.len() }   pub fn is_empty(&self) -> bool { self.pref.is_empty() }   #[track_caller] fn verify_range_bounds(&self, range: impl RangeBounds<usize>) -> Range<usize> { let start = match range.start_bound() { Bound::Unbounded => 0, Bound::Included(&x) => x, Bound::Excluded(&x) => x + 1, };let end = match range.end_bound() { Bound::Unbounded => self.len(), Bound::Included(&x) => x + 1, Bound::Excluded(&x) => x, };assert!( start < end, "range inverted: start >= end ({} >= {})", start, end );assert!( end <= self.len(), "range out of bounds: end > len ({} > {})", end, self.len() );Range { start, end } }     #[track_caller] pub fn query_prefix(&self, range: impl RangeBounds<usize>) -> T where T: Clone, { let Range { start, end } = self.verify_range_bounds(range);assert!(start == 0, "query start bound is non-zero: {} > 0", start);self.pref[end - 1].clone() } }  impl<T, F, I> PrefixArray<T, F, I> where I: Fn(&T, &T) -> T, {  #[track_caller] pub fn query(&self, range: impl RangeBounds<usize>) -> T where T: Clone, { let Range { start, end } = self.verify_range_bounds(range);if start == 0 { self.pref[end - 1].clone() } else { (self .inv .as_ref() .expect("range query is not supported on non-invertible operation"))( &self.pref[end - 1], &self.pref[start - 1], ) } } }  impl<T, F, I> Debug for PrefixOp<T, F, I> where T: Debug, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("PrefixOp").finish_non_exhaustive() } }  impl<T, F, I> Debug for PrefixArray<T, F, I> where T: Debug, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("PrefixArray") .field("pref", &self.pref) .finish_non_exhaustive() } }  type NextFn<T> = fn(&T, &T) -> T;pub struct PrefixSum<T>(PhantomData<T>);impl<T> PrefixSum<T> where T: Add<Output = T> + Sub<Output = T> + Clone, {  pub fn op() -> PrefixOp<T, NextFn<T>, NextFn<T>> { PrefixOp::new_invertible(|a, b| a.clone() + b.clone(), |b, a| b.clone() - a.clone()) }   pub fn build(arr: Vec<T>) -> PrefixArray<T, NextFn<T>, NextFn<T>> { Self::op().build(arr) } } }
#[rustfmt::skip] mod rng {use std::ops::{Bound, RangeBounds};#[derive(Debug, Clone)] pub struct Rng { state: u64, }  impl Rng {    pub fn new(seed: u64) -> Rng { assert!(seed > 0, "xorshift generator cannot be seeded with 0");Rng { state: seed } }     const RDSEED_ITER_LIMIT: i64 = 50_000;#[cfg(target_arch = "x86_64")] pub fn hardware() -> Rng { use std::arch::x86_64::_rdseed64_step;unsafe fn rdseed64(limit: i64) -> u64 { let mut seed = 0;let mut iters = 0;while _rdseed64_step(&mut seed) != 1 { iters += 1;assert!( iters <= limit, "rdseed iteration limit ({}) exceeded, something has gone very wrong", limit );} seed }  assert!(is_x86_feature_detected!("rdseed"), "rdseed not supported");unsafe { Rng::new(rdseed64(Self::RDSEED_ITER_LIMIT)) } }     #[cfg(target_arch = "x86")] pub fn hardware() -> Rng { use std::arch::x86::_rdseed32_step;unsafe fn rdseed32(limit: i64) -> u32 { let mut seed = 0;let mut iters = 0;while _rdseed32_step(&mut seed) != 1 { iters += 1;assert!( iters <= limit, "rdseed iteration limit ({}) exceeded, something has gone very wrong", limit );} seed }  assert!(is_x86_feature_detected!("rdseed"), "rdseed not supported");unsafe { Rng::new( (rdseed32(Self::RDSEED_ITER_LIMIT) as u64) << 32 | rdseed32(Self::RDSEED_ITER_LIMIT) as u64, ) } }   #[allow(clippy::should_implement_trait)] pub fn next(&mut self) -> u64 { self.state ^= self.state >> 12;self.state ^= self.state << 25;self.state ^= self.state >> 27;self.state.wrapping_mul(0x2545f4914f6cdd1d) }   pub fn gen<T>(&mut self) -> T where T: Generatable<Standard>, { self.gen_dist(&Standard::default()) }   pub fn gen_dist<T, D>(&mut self, dist: &D) -> T where T: Generatable<D>, { T::generate(self, dist) } }   pub trait Generatable<D> { fn generate(rng: &mut Rng, dist: &D) -> Self;}       #[derive(Debug, Clone, Default)] pub struct Standard(());impl Generatable<Standard> for u64 { fn generate(rng: &mut Rng, _dist: &Standard) -> u64 { rng.next() } }  impl Generatable<Standard> for f64 { fn generate(rng: &mut Rng, _dist: &Standard) -> f64 { let bits = rng.next();let float = (1023 << 52) + (bits & ((1 << 52) - 1));f64::from_bits(float) - 1.0 } }  impl Generatable<Standard> for bool { fn generate(rng: &mut Rng, _dist: &Standard) -> bool { rng.next() & 1 > 0 } }  macro_rules! generate_standard_impl_by_cast { ($( $source:ty => $target:ty ),+) => { $( impl Generatable<Standard> for $target { fn generate(rng: &mut Rng, _dist: &Standard) -> $target { rng.gen::<$source>() as $target } } )+ };}  generate_standard_impl_by_cast!(f64 => f32, u64 => u32, u64 => u16, u64 => u8, u64 => i64, i64 => i32, i64 => i16, i64 => i8);#[derive(Debug, Clone)] pub struct UniformInt { min: u64, max: u64, mask: u64, }  impl UniformInt {    pub fn new(range: impl RangeBounds<u64>) -> UniformInt { let min = match range.start_bound() { Bound::Included(&x) => x, Bound::Excluded(&x) => x.checked_add(1).expect("minimum overflowed u64"), Bound::Unbounded => 0, };let max = match range.end_bound() { Bound::Included(&x) => x, Bound::Excluded(&x) => x.checked_sub(1).expect("minimum underflowed u64"), Bound::Unbounded => u64::MAX, };assert!(min <= max, "range empty: min > max ({} > {})", min, max);if max - min == u64::MAX { UniformInt { min, max, mask: !0 } } else { let len = max - min + 1;let bit_len = 0u64.leading_zeros() - len.leading_zeros();UniformInt { min, max, mask: if bit_len == 0u64.leading_zeros() { !0 } else { (1 << bit_len) - 1 }, } } } }  impl Generatable<UniformInt> for u64 { fn generate(rng: &mut Rng, dist: &UniformInt) -> Self { loop { let x = rng.next() & dist.mask;if x <= dist.max - dist.min { return dist.min + x;} } } }   pub trait Shuffle {  fn shuffle(&mut self, rng: &mut Rng);}  impl<T> Shuffle for [T] {    fn shuffle(&mut self, rng: &mut Rng) { for i in (1..self.len()).rev() { let j: u64 = rng.gen_dist(&UniformInt::new(0..=i as u64));self.swap(i, j as usize);} } } }

use std::collections::HashSet;

use combinatorics::{next_permutation, Factorials};
use number_theory::{egcd, gcd, mod_exp, mod_mulinv, PrimeSieve};
use prefix_sum::{PrefixOp, PrefixSum};
use rng::{Rng, Shuffle, UniformInt};
use scanner::{
    macros::{LenArray, ScanCmd, UsizeM1},
    Scanner,
};
use util::{fix, Argmax, Choose, IntoVec, Sorted};
use writer::{Format, Writer};

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

    let (x, y) = scan!(sc, u64, u64);
    let target = format!("{:b}", y);

    let mut visited = HashSet::new();
    let mut current = Vec::new();
    current.push(format!("{:b}", x));

    for _ in 0..140 {
        let mut next_cur = Vec::new();
        for s in current {
            if s == target {
                out!(wr, "YES");
                return;
            }
            for d in ['0', '1'] {
                let mut next = s.clone();
                next.push(d);
                next = next.chars().rev().skip_while(|c| *c == '0').collect();
                if !visited.contains(&next) {
                    visited.insert(next.clone());
                    next_cur.push(next);
                }
            }
        }
        current = next_cur;
        if current.is_empty() {
            break;
        }
    }

    out!(wr, "NO");
}


use std::collections::{HashSet, VecDeque};
use std::io::stdin;

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

pub fn flip(mut num: u64) -> u64 {
    let mut result: u64 = 0;
    while num > 0 {
        result = (result << 1) | (num & 1);
        num >>= 1;
    }
    result
}

pub fn add_one(num: u64) -> u64 {
    flip((num << 1) | 1)
}

pub fn main() {
    let mut scanner = Scanner::default();
    let a: u64 = scanner.next();
    let b: u64 = scanner.next();
    let mut visited: HashSet<u64> = HashSet::new();
    let mut queue: VecDeque<u64> = VecDeque::new();
    queue.push_back(a);
    visited.insert(a);
    let mut current: u64 = a;
    while !queue.is_empty() {
        current = queue.pop_front().unwrap();
        if current == b {
            break;
        }
        if current < b {
            let added: u64 = add_one(current);
            if !visited.contains(&added) {
                visited.insert(added);
                queue.push_back(added);
            }
        }
        let flipped: u64 = flip(current);
        if !visited.contains(&flipped) {
            visited.insert(flipped);
            queue.push_back(flipped);
        }
    }
    println!("{}", if current == b { "YES" } else { "NO" });
}


use std::io;

fn main() {
    let mut s = String::new();
    for _i in 0..2 {
        s.clear();
        io::stdin().read_line(&mut s).unwrap();
    }
    s = s.trim().to_string();
    s = s.to_lowercase();
    let mut flag = [false; 26];
    for c in s.chars() {
        flag[((c as i32) - ('a' as i32)) as usize] = true;
    }
    for i in 0..26 {
        if flag[i as usize] == false {
            println!("NO");
            ::std::process::exit(0);
        }
    }
    println!("YES");
}


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 n: usize = read_line().parse().unwrap();
    let line = read_line().to_lowercase();

    let set: std::collections::HashSet<char> = line.chars().collect();

    println!("{}", if set.len() == 26 { "YES" } else { "NO" });

}


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

fn main() {
  use std::io;
  let mut buf = String::new();
  io::stdin().read_line(&mut buf);
  buf.clear();
  io::stdin().read_line(&mut buf);
  let bytes = buf.trim().as_bytes();
  let mut seen = vec![false; 26];
  for &byte in bytes {
    seen[(byte.to_lowercase() - b'a') as usize] = true;
  }
  println!("{}", if seen.iter().all(|&b| b) { "YES" } else { "NO" });
}

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

pub trait CharExt: Copy {
  fn is_digit(self, radix: u32) -> bool;
  fn to_digit(self, radix: u32) -> Option<u32>;
  fn is_alphabetic(self) -> bool;
  fn is_lowercase(self) -> bool;
  fn is_uppercase(self) -> bool;
  fn is_whitespace(self) -> bool;
  fn is_alphanumeric(self) -> bool;
  fn to_lowercase(self) -> Self;
  fn to_uppercase(self) -> Self;
}

macro_rules! impl_u8 {
  ($meth:ident($($arg:ident : $ty:ty),*) -> $ret:ty) => {
    fn $meth(self, $($arg : $ty),*) -> $ret {
      let c = self as char;
      c.$meth($($arg),*)
    }
  }
}

impl CharExt for u8 {
  impl_u8!(is_digit(radix: u32) -> bool);
  impl_u8!(to_digit(radix: u32) -> Option<u32>);
  impl_u8!(is_alphabetic() -> bool);
  impl_u8!(is_lowercase() -> bool);
  impl_u8!(is_uppercase() -> bool);
  impl_u8!(is_whitespace() -> bool);
  impl_u8!(is_alphanumeric() -> bool);
  fn to_lowercase(self) -> Self {
    let c = self as char;
    c.to_lowercase()
      .next()
      .map(|c| c as u8)
      .unwrap_or(self)
  }
  fn to_uppercase(self) -> Self {
    let c = self as char;
    c.to_uppercase()
      .next()
      .map(|c| c as u8)
      .unwrap_or(self)
  }
}


use std::collections::BTreeSet;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

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 parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_t<T : FromStr>(stdin : &Stdin) -> T {
    let mut line = String::new();
    read_line(stdin, &mut line);
    parse_t(&line)
}

const NUM_LETTERS : usize = 26;

fn is_pangram(s : &String) -> bool {
    let t = s.trim().to_lowercase();
    let mut distinct_chars = BTreeSet::new();
    for c in t.chars() {
        distinct_chars.insert(c);
    }
    distinct_chars.len() == NUM_LETTERS
}

fn main() {
    let stdin = io::stdin();
    let _ : u64 = read_t(&stdin);
    let mut s = String::new();
    read_line(&stdin, &mut s);
    if is_pangram(&s) {
        println!("YES");
    } else {
        println!("NO");
    }
}


// {{{ 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::ascii::AsciiExt;
use std::collections::HashSet;

fn main() {
    R!(usize);
    if gets().chars().map(|c| c.to_ascii_lowercase()).collect::<HashSet<char>>().len() == 26 {
        println!("YES");
    } else {
        println!("NO");
    }
}


use std::collections::HashSet;

fn get_int() -> usize {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.trim().parse::<usize>().ok().unwrap()
}

fn get_input(limit: usize) -> HashSet<char> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.chars()
        .take(limit)
        .map(|x| x.to_ascii_lowercase())
        .filter(|x| x.is_alphabetic())
        .collect()
}

fn main() {
    let n = get_int();
    let input = get_input(n);
    println!("{}", if input.len() == 26 { "YES" } else { "NO" });
}


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

use std::cell::RefCell;
use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::fmt::{Debug, Formatter, Write as FmtWrite};
use std::io::*;
use std::mem::{replace, swap};
use std::ops::*;
use std::rc::Rc;

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

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

#[allow(dead_code)]
fn reads<T: std::str::FromStr>(i: &mut StdinLock) -> Vec<T> {
    let mut s = String::new();
    i.by_ref().read_line(&mut s).ok();
    s.trim()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

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

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

impl<T: Iterator> IteratorExt for T {}

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

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

    // #################################

    let _n: u32 = read!(u32);
    let input: String = rl();

    let mut set = HashSet::new();

    for c in input.to_lowercase().as_str().chars() {
        set.insert(c);
    }

    let ans = if set.len() == 26 { "YES" } else { "NO" };

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


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

fn main() {
    let stdin = io::stdin();
    let _n: i32;
    let mut iterator = stdin.lock().lines();
    let mut line: String;

    line = iterator.next().unwrap().unwrap();
    _n = line.parse().unwrap();
    line = iterator.next().unwrap().unwrap();
    let unique = line
        .to_lowercase()
        .chars()
        .collect::<Vec<char>>()
        .iter().cloned().collect::<HashSet<_>>();

    if unique.len() as i32 == 26 {
        println!("YES");
    } else {
        println!("NO");
    }
}


// {{{ 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 (n, m, a, b) = R!(usize, usize, usize, usize);
    println!("{}", cmp::min(n*a, cmp::min((n%m)*a + (n/m)*b, (n+m-1)/m*b)));
}


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

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

  let x: Vec<i32> = s.trim()
    .split_whitespace()
    .map(|x| x.parse().unwrap())
    .collect();

  let n = x[0];
  let m = x[1];
  let a = x[2];
  let b = x[3];

  if m * a <= b {
    println!("{}", a*n);
  } else {
    if m > n {
      println!("{}", min(b, a*n));
    } else {
      if a*(n%m) < b {
        println!("{}", b*(n/m)+a*(n%m));
      } else {
        println!("{}", b*(n/m+1));
      }
    }
  }
}


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 (n,m,a,b) = readln!(i32,i32,i32,i32);
    let r1 = n*a;
    let r2 = b*((n+m-1)/m);
    let r3 = b*(n/m) + a*(n%m);
    println!("{}", std::cmp::min(r1,std::cmp::min(r2,r3)));
}


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

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

  let x: Vec<i32> = s.trim()
    .split_whitespace()
    .map(|x| x.parse().unwrap())
    .collect();

  let n = x[0];
  let m = x[1];
  let a = x[2];
  let b = x[3];

  let ans =
  min(  a*n,
  min(  b*(n/m + 1),
        b*(n/m) + a*(n%m)
  ));

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


fn solve() {
    let (n, m, a, b) = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        let v: Vec<i32> = buf.split_whitespace().map(|x| x.parse().unwrap()).collect();
        (v[0], v[1], v[2], v[3])
    };

    let mut ans = 0;
    if b < m * a {
        let d = n / m;
        ans += d * b;
        if b < a * (n - d * m) {
            ans += b;
        } else {
            ans += (n - d * m) * a;
        }
    } else {
        ans += n * a;
    }
    println!("{}", ans);
}

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

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


//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 n = input.i();
    let m = input.i();
    let a = input.i();
    let b = input.i();
    let p = n / m;
    let q = n % m;
    let val = [a*n, a*q+b*p, b*(p+1)];
    let sol = val.iter().min().unwrap();
    println!("{}", sol);
}


fn input_split() -> Vec<u32> {
    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 (n, m, a, b) = {
        let temp = input_split();
        (temp[0], temp[1], temp[2], temp[3])
    };

    if m * a > b {
        println!("{}", (n / m) * b + b.min((n % m) * a));
    } else {
        println!("{}", n * a);
    }
}


// use rand::Rng;

use std::collections::*;
use std::io;

fn trim_newline(s: &mut String) {
    if s.ends_with('\n') {
        s.pop();
        if s.ends_with('\r') {
            s.pop();
        }
    }
}
macro_rules! parse_input {
    ($t:ident) => {{
        let mut input_line = String::new();
        io::stdin().read_line(&mut input_line).unwrap();
        trim_newline(&mut input_line);
        input_line.parse::<$t>().unwrap()
    }};
}

macro_rules! split_input {
    ($t:ident) => {{
        parse_input!(String)
            .split(" ")
            .map(|z| z.parse::<$t>().unwrap())
            .collect::<Vec<$t>>()
    }};
}

fn main() {
    let a = split_input!(u64);
    let n = a[0];
    let single = a[2];
    let group = a[3];
    let group_count = a[1];
    let mut best = single * n;
    best = std::cmp::min(best, ((n + (group_count - 1)) / group_count) * group);
    let other = n / group_count * group;
    let rem = n % group_count;
    best = std::cmp::min(other + rem * single, best);

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


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

// Input macros.
// Original by tanakh: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

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

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

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

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

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

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

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

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

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

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

#[allow(unused_macros)]
macro_rules! read_line {
    ($t:tt) => {
        {
            let mut s = String::new();
            std::io::stdin().read_line(&mut s).unwrap();
            s.trim_right().parse::<$t>().unwrap()
        }
    }
}

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

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

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

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

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

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

// ===

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

fn not_consequtive3(n: usize) -> Vec<i64> {
    let mut dp = dvec![0; n+1, 5];
    dp[1] = vec![1, 0, 1, 0];
    dp[2] = vec![1, 1, 1, 1];
    for i in 2..n {
        for j in 0..4 {
            let base = dp[i][j];
            for next in 0..2 {
                let nj = j+4*next;
                if nj == 7 || nj == 0 {
                    continue;
                }
                let nj = ifv!(j == 0, 2*next, nj/2);
                dp[i+1][nj] += base;
                dp[i+1][nj] %= MOD;
            }
        }
    }
    dp.into_iter().map(|row| row.into_iter().fold(0, |acc,x| (acc+x)%MOD)).collect::<Vec<_>>()
}

fn solve(h: usize, w: usize) -> i64 {
    if w == 1 {
        return 2;
    }
    let dp = not_consequtive3(w+10);
    // debug!(dp);
    (dp[h] + dp[w] + MOD - 2) % MOD
}

fn main() {
    input! {
        n: usize, m: usize
    };
    let h = min(n, m);
    let w = max(n, m);
    println!("{}", solve(h, w));
}