use std::io;
use std::io::Read;
use std::collections::HashMap;

fn main() {
    let mut stdin = String::new();
    io::stdin().read_to_string(&mut stdin).unwrap();
    let mut stdin = stdin.split_whitespace();
    let mut get = || stdin.next().unwrap();
    macro_rules! get {
        ($t:ty) => (get().parse::<$t>().unwrap());
    }

    let n = get!(usize);
    let need = get!(u64);

    let mut costs = vec![0; n];

    for i in 0..n {
        costs[i] = get!(u64);
    }

    fn search(costs: &Vec<u64>, need: u64, memo: &mut HashMap<u64,u64>) -> u64 {
        if let Some(p) = memo.get(&need) {
            return *p;
        }
        let mut best_payment = 0;
        for i in 0..costs.len() {
            let liters = 1 << i;
            if liters < need {
                let bottles = need / liters;
                let remains = need-bottles*liters;
                let payment = bottles*costs[i];
                let payment = if remains > 0 {
                    payment+search(costs, remains, memo)
                } else {
                    payment
                };
                if payment < best_payment || best_payment == 0 {
                    best_payment = payment;
                }
            } else {
                let payment = costs[i];
                if payment < best_payment || best_payment == 0 {
                    best_payment = payment;
                }
            }
        }
        memo.insert(need, best_payment);
        best_payment
    }
    let best_payment = search(&costs, need, &mut HashMap::new());
    println!("{}", best_payment);
}


use std::mem;
use std::io;
use std::string;
use std::cmp::*;
use std::collections::*;

fn load() -> Vec<i64> {
    let mut line = String::new();
    io::stdin().read_line(&mut line).expect("Failed to read line");
    let vec: Vec<&str> = line.split(" ").collect();
    let mut data : Vec<i64> = Vec::new();
    for i in vec {
        let el : i64 = i.trim().parse().unwrap();
        data.push(el);
    }
    data
}

fn main() {
    let s = load();
    let (a,b)=(s[0],s[1]);
    println!("{}", (if min(a,b)%2==0 {"Malvika"}else{"Akshat"}));
}
// min, max
// HashSet, insert, contains
// Vec, len, sort


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

fn get_pair() -> (i32, i32) {
    let mut input = String::new();

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

    let v = input.trim()
            .split_whitespace()
            .map(|s| i32::from_str(s).unwrap())
            .collect::<Vec<_>>();

    (v[0], v[1])
}

fn main() {
    let (mut n, mut m) = get_pair();

    let mut curr = "Malvika";
    while n * m  != 0 {
        n -= 1;
        m -=1 ;

        if curr == "Akshat" {
            curr = "Malvika";
        } else {
            curr = "Akshat";
        }
    }

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


use std::io;

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

fn main() {
  let (n, m) = rt!(i32, i32);

  let x = std::cmp::min(n, m);

  if x % 2 == 0 {
    println!("Malvika");
  } else {
    println!("Akshat");
  }
}


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

fn main() {
    let players = ["Malvika", "Akshat"];
    let (n, m) = input_split();
    println!("{}", players[n.min(m) % 2]);
}


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

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

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

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

    let n = words[0];
    let m = words[1];

    let minima = std::cmp::min(n,m);

    if minima%2 == 0 {
        println!("Malvika");
    } else {
        println!("Akshat");
    }
}


use std::io::*;

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

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

    let inputs: Vec<u8> = reads(sin);
    let m = inputs[0];
    let n = inputs[1];

    let x = std::cmp::min(m, n);

    let winner = if x % 2 == 0 { "Malvika" } else { "Akshat" };

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


// {{{ 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) = R!(u32, u32);
    println!("{}", if cmp::min(n, m) % 2 == 0 { "Malvika" } else { "Akshat" });
}


use std::io::stdin;

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

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

    let ejemaximo = std::cmp::min(line[0], line[1]);

    println!(
        "{}",
        if ejemaximo % 2 == 0 {
            "Malvika"
        } else {
            "Akshat"
        }
    );
}


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

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

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

}

fn _main() {
    let mut scan = Scan::new();
    let n: usize = scan.next();
    let mut sum = 1usize;
    let mut lastsum = 1usize;
    let mut level = 1usize;
    while sum <= n {
        level += 1;
        lastsum += level;
        sum += lastsum;
    }
    println!("{}", level - 1);
}

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


/*input
3
*/
fn main() {
    let mut input = format!("");
    std::io::stdin().read_line(&mut input).expect("");
    let mut input_num: i16 = input.trim().parse::<i16>().unwrap();
    let mut substractor: i16 = 0;
    let mut iter: i16 = 0;
    while input_num > 0 {
        iter = iter + 1;
        substractor = substractor + iter;
        input_num = input_num - substractor;
        if input_num < 0 {
            iter = iter - 1;
        }
    }
    println!("{}", iter);
}


fn main() {
    let mut n: u16 = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim().parse().unwrap()
    };
    let (mut level, mut level_blocks) = (1, 1);
    while level_blocks <= n {
        n -= level_blocks;
        level += 1;
        level_blocks = level * (level + 1) / 2;
    }
    println!("{}", level - 1);
}


#![allow(unused_imports)]
use std::mem;
use std::io;
use std::string;
use std::cmp::*;
use std::collections::*;

fn load() -> Vec<i64> {
    let mut line = String::new();
    io::stdin().read_line(&mut line).expect("Failed to read line");
    let vec: Vec<&str> = line.split(" ").collect();
    let mut data : Vec<i64> = Vec::new();
    for i in vec {
        let el : i64 = i.trim().parse().unwrap();
        data.push(el);
    }
    data
}
fn maxv(v : &Vec<i64>) -> i64{
    let mut s=v[0];
    for i in v {s=max(s,*i);}
    return s;
}
fn minv(v : &Vec<i64>) -> i64{
    let mut s=v[0];
    for i in v {s=min(s,*i);}
    return s;
}

fn main() {
    let s = load()[0];
    let mut num = 0;
    let mut sum = 0;
    let mut last = 0;
    for i in 1..s+1 {
        num+=i;
        sum+=num;
        if sum > s {break;}
        last = i;
    }
    println!("{}", last);
}
// min, max
// HashSet, insert, contains
// Vec, len, sort
// primitive retype: i as f64


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

// }}}

fn main() {

    let (n, ) = R!(usize);
    let mut c = 0;
    let mut v = 0;

    for i in 1.. {
        c += i;
        if c + v <= n {
            v += c;
        } else {
            println!("{}", i - 1);
            break;
        }
    }
}


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

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

use std::io::Write;

fn good(mut a: u32) -> bool {
    let mut sum = 0;
    while a != 0 {
        sum += a % 10;
        a /= 10;
    }
    return sum == 10;
}

fn solve(writer: &mut std::io::BufWriter<std::io::Stdout>) {
    let mut k = parse_line!(usize);
    let mut result = 0;
    while k > 0 {
        result += 1;
        if good(result) {
            k -= 1;
        }
    }
    writeln!(writer, "{}", result).unwrap();
}

fn main() {
    let mut writer = std::io::BufWriter::new(std::io::stdout());
    let tests = 1; // parse_line!(usize);
    for _ in 0..tests {
        solve(&mut writer);
    }
}


#[allow(unused_imports)]
use std::io::{stdin, Read, StdinLock};
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::str::FromStr;
#[allow(unused_imports)]
use std::collections::{HashSet, HashMap, BinaryHeap, VecDeque};
#[allow(unused_imports)]
use std::vec::Vec;

#[allow(dead_code)]
const INF: i32 = 1000_000_000;
#[allow(dead_code)]
const INFLL: i64 = 1000_000_000_000_000_000;
#[allow(dead_code)]
const EPS: f64 = 1.0e-10;
#[allow(dead_code)]
const MOD: i32 = 1000_000_007;
#[allow(dead_code)]
const MODLL: i64 = 1000_000_007;

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

#[allow(dead_code)]
impl<'a> Scanner<'a> {
    fn new(cin: StdinLock<'a>) -> Scanner<'a> {
        Scanner {cin: cin}
    }
    fn read1<T: FromStr>(&mut self) -> Option<T> {
        let token = self.cin.by_ref().bytes().map(|c| c.unwrap() as char)
                    .skip_while(|c| c.is_whitespace())
                    .take_while(|c| !c.is_whitespace())
                    .collect::<String>();
        token.parse::<T>().ok()
    }
    fn read<T: FromStr>(&mut self) -> T {
        self.read1().unwrap()
    }
}

fn main() {
    let cin = stdin();
    let cin = cin.lock();
    let mut sc = Scanner::new(cin);

    let k: usize = sc.read();
    let mut cnt = 0;
    for i in 0..1000_000_00 {
        let mut sum = 0;
        let mut x = i;
        while x > 0 {
            sum += x % 10;
            x /= 10;
        }
        if sum == 10 {
            cnt += 1;
        }

        if cnt == k {
            println!("{}", i);
            break;
        }
    }
}


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

fn main() {
    let n: i32 = read_line().unwrap().parse().unwrap();
    fn sum_digits(mut n: i64) -> i32 {
        let mut sum = 0;
        while n > 0 {
            sum += (n % 10) as i32;
            n /= 10;
        }
        sum
    }
    let mut a = 19;
    let mut m = 0;
    loop {
        let sum = sum_digits(a);
        if sum == 10 {
            m += 1;
            if m == n {
                println!("{}", a);
                break;
            }
        }
        if sum >= 10 {
            a += 10 - a % 10;
        } else {
            a += 1;
        }
    }
}


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

#[allow(unused_macros)]
macro_rules! a {
    ($c: tt, $x: expr, $y: expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
struct WordReader<'a> { it : SplitAsciiWhitespace<'a>, }
#[allow(dead_code)]
impl<'a> WordReader<'a> {
    fn new<T: Read>(b: &mut String, mut r: T) -> WordReader {
        b.clear();
        r.read_to_string(b).unwrap();
        WordReader { it: b.split_ascii_whitespace() }
    }
    fn from_stdin(b: &mut String) -> WordReader {
        WordReader::new(b, stdin())
    }
    fn sl(&mut self) ->  &str { self.it.next().unwrap() }
    fn bs(&mut self) -> &[u8] { self.sl().as_bytes()    }
    fn s(&mut self) -> String { String::from(self.sl()) }
    fn i(&mut self) ->    i32 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn vi(&mut self, n: usize) -> Vec<i32> {
        self.vp::<i32>(n)
    }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}

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

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

    let k = input.u();
    let sol = (1..).filter(|&a| {
        let mut b = a;
        let mut s = 0;
        while b > 0 {
            s += b % 10;
            b /= 10;
        }
        s == 10
    }).nth(k - 1).unwrap();
    println!("{}", sol);
}


#![allow(unused_imports, unused_macros, dead_code)]
use std::f64::*;
use std::cmp::*;
use std::collections::*;

macro_rules! dump{
    ($($a:expr),*) => {
        println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

const INF: i64 = 0x3f3f3f3f3f3f3f3f;
const MOD: i64 = 1000000007;
const NOTHING: usize = std::usize::MAX;
const DX: [usize; 4] = [1, 0, std::usize::MAX, 0];
const DY: [usize; 4] = [0, 1, 0, std::usize::MAX];

fn main() {
    let mut k: u64 = readln();
    let mut i = 0;
    while k > 0 {
        i += 1;
        let mut x = i;
        let mut s = 0;
        while x > 0 {
            s += x % 10;
            x /= 10;
        }
        if s == 10 {
            k -= 1;
        }
    }
    println!("{}", i);
}

trait Read {
    fn read(s: &str) -> Self;
}

fn readln<T: Read>() -> T {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    T::read(buf.trim_right())
}

macro_rules! read_impl{
    ($($t:ty)*) => ($(
        impl Read for $t {
            fn read(s: &str) -> $t{
                s.parse().unwrap()
            }
        }
    )*)
}
read_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }

impl Read for String {
    fn read(s: &str) -> Self {
        s.to_string()
    }
}

impl Read for Vec<char> {
    fn read(s: &str) -> Self {
        s.chars().collect()
    }
}

impl<T: Read> Read for Vec<T> {
    fn read(s: &str) -> Self {
        s.split_whitespace().map(T::read).collect()
    }
}

impl<A: Read, B: Read> Read for (A, B) {
    fn read(s: &str) -> Self {
        let tokens: Vec<_> = s.split_whitespace().collect();
        (A::read(tokens[0]), B::read(tokens[1]))
    }
}

impl<A: Read, B: Read, C: Read> Read for (A, B, C) {
    fn read(s: &str) -> Self {
        let tokens: Vec<_> = s.split_whitespace().collect();
        (A::read(tokens[0]), B::read(tokens[1]), C::read(tokens[2]))
    }
}

impl<A: Read, B: Read, C: Read, D: Read> Read for (A, B, C, D) {
    fn read(s: &str) -> Self {
        let tokens: Vec<_> = s.split_whitespace().collect();
        (A::read(tokens[0]), B::read(tokens[1]), C::read(tokens[2]), D::read(tokens[3]))
    }
}


use std::io::stdin;

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

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

    if arr[1..].iter().min().unwrap() >= &arr[0] {
        println!("Yes");
    } else {
        println!("No");
    }
}


use std::io;

macro_rules! parse_line
{
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        io::stdin().read_line(&mut a_str).expect("read error");

        let mut a_iter = a_str.split_whitespace();
        (
            $(
                a_iter.next().unwrap().parse::<$t>().expect("parse error"),
            )+
        )
    })
}

fn main()
{
    let (n, m, k) = parse_line!(i32, i32, i32);

    if n <= m && n <= k
    {
        println!("Yes");
    }
    else
    {
        println!("No");
    }
}


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

fn main() {
    let mut input_line = String::new();
    io::stdin().read_line(&mut input_line).expect("input error");
    let parsed = input_line.split_whitespace().map(|x| x.parse::<i32>().expect("parse error"));
    let inputs: Vec<i32> = parsed.collect();
    let (n, m, k) = (inputs[0], inputs[1], inputs[2]);
    if n <= cmp::min(m, k) {
        println!("Yes");
    } else {
        println!("No");
    }
}


macro_rules! parse {
    () => {{
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap(); // don't do this
        s.trim().parse().unwrap() // don't do this
    }};
}

fn main() {
    let s: String = parse!();
    let input: Vec<usize> = s.split_whitespace().map(|f| f.trim()).map(|s| s.parse().unwrap()).collect();
    let participants = input[0];
    let pens = input[1];
    let notebooks = input[2];
    if participants > pens || participants > notebooks{
        println!("No");
    }else {
        println!("Yes");
    }
}


fn read_string() -> String {
    let mut string: String = String::new();
    std::io::stdin().read_line(&mut string)
        .ok()
        .expect("Ошибка чтения ввода");
    return string;
}

fn main() {
    let data = read_string();
    let mut iter = data.split_whitespace();
    let n = iter.next().unwrap().parse::<i32>().expect("Ошибка");
    let m = iter.next().unwrap().parse::<i32>().expect("Ошибка");
    let k = iter.next().unwrap().parse::<i32>().expect("Ошибка");
    if n <= m && n <= k{
        println!("{}", "YES");
    }else {
        println!("{}", "NO");
    }
}


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

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

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

fn _main() {
    let mut scan = Scan::new();
    let n: usize = scan.next();
    let m: usize = scan.next();
    let k: usize = scan.next();
    println!("{}", if m >= n && k >= n { "Yes" } else { "No" });
}

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


fn main() {
    let mut no = String::new();
    std::io::stdin().read_line(&mut no)
        .expect("Error  input");
    let input = no.trim().split(' ').collect::<Vec<_>>();
    let n: usize = input[0].parse().unwrap();
    let m: usize = input[1].parse().unwrap();
    let k: usize = input[2].parse().unwrap();

    let out = match n <= m && n <= k { true => "YES", _ => "No"};

    print!("{}", out);
}


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

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

    l!(a,b,c = input.i());
    if a <= b.min(c) {
        println!("Yes");
    } else {
        println!("No");
    }
}


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

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

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

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

fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
    let p1: i32 = scan.token();
    let p2: i32 = scan.token();
    let p3: i32 = scan.token();
    let p4: i32 = scan.token();
    let a: i32 = scan.token();
    let b: i32 = scan.token();
    let ans = 0.max(b.min(p1.min(p2).min(p3).min(p4) - 1) - a.max(0) + 1);
    writeln!(out, "{}", ans).ok();
}

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


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

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

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

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

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

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

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

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

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

impl std::fmt::Display for ModInt {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::str::FromStr for ModInt {
    type Err = std::num::ParseIntError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let val = s.parse::<u32>()?;
        Ok(ModInt::new(val))
    }
}

#[allow(dead_code)]
impl ModInt {
    pub fn new(n: u32) -> ModInt {
        ModInt(n % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        assert!(self.0 > 0);
        self.pow(MOD - 2)
    }
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
#[allow(dead_code)]
struct Precalc {
    inv: Vec<ModInt>,
    fact: Vec<ModInt>,
    ifact: Vec<ModInt>,
}

#[allow(dead_code)]
impl Precalc {
    pub fn new(n: usize) -> Precalc {
        let mut inv = vec![ModInt::one(); n + 1];
        let mut fact = vec![ModInt::one(); n + 1];
        let mut ifact = vec![ModInt::one(); n + 1];
        for i in 2..(n + 1) {
            inv[i] = -inv[MOD as usize % i] * ModInt(MOD / i as u32);
            fact[i] = fact[i - 1] * ModInt(i as u32);
            ifact[i] = ifact[i - 1] * inv[i];
        }
        Precalc {
            inv: inv,
            fact: fact,
            ifact: ifact,
        }
    }
    pub fn inv(&self, n: usize) -> ModInt {
        self.inv[n]
    }
    pub fn fact(&self, n: usize) -> ModInt {
        self.fact[n]
    }
    pub fn ifact(&self, n: usize) -> ModInt {
        self.ifact[n]
    }
    pub fn comb(&self, n: usize, k: usize) -> ModInt {
        if k > n {
            return ModInt::zero();
        }
        self.fact[n] * self.ifact[k] * self.ifact[n - k]
    }
}
// ---------- end Precalc ----------
// ---------- begin Matrix ----------
#[allow(dead_code)]
mod matrix {
    use std::ops::{Add, Mul};
    pub trait SemiRing: Add<Output = Self> + Mul<Output = Self> + Copy {
        fn zero() -> Self;
        fn one() -> Self;
    }
    pub const SIZE: usize = 2;
    #[derive(Clone)]
    pub struct SquareMatrix<T: SemiRing> {
        buf: [[T; SIZE]; SIZE],
    }
    impl<T: SemiRing> SquareMatrix<T> {
        pub fn zero() -> Self {
            let z = T::zero();
            SquareMatrix {
                buf: [[z; SIZE]; SIZE],
            }
        }
        pub fn identity() -> Self {
            let mut m = Self::zero();
            for i in 0..SIZE {
                m.buf[i][i] = T::one();
            }
            m
        }
        pub fn set_at(&mut self, i: usize, j: usize, v: T) {
            self.buf[i][j] = v;
        }
        pub fn get_at(&self, i: usize, j: usize) -> T {
            self.buf[i][j]
        }
        pub fn matmul(&self, rhs: &Self) -> Self {
            let mut res = Self::zero();
            for (x, a) in res.buf.iter_mut().zip(self.buf.iter()) {
                for (a, b) in a.iter().zip(rhs.buf.iter()) {
                    for (x, b) in x.iter_mut().zip(b.iter()) {
                        *x = *x + *a * *b;
                    }
                }
            }
            res
        }
        pub fn matadd(&self, rhs: &Self) -> Self {
            let mut c = Self::zero();
            for (c, (a, b)) in c.buf.iter_mut().zip(self.buf.iter().zip(rhs.buf.iter())) {
                for (c, (a, b)) in c.iter_mut().zip(a.iter().zip(b.iter())) {
                    *c = *a + *b;
                }
            }
            c
        }
        pub fn matpow(&self, mut n: usize) -> Self {
            let mut t = Self::identity();
            let mut s = self.clone();
            while n > 0 {
                if n & 1 == 1 {
                    t = t.matmul(&s);
                }
                s = s.matmul(&s);
                n >>= 1;
            }
            t
        }
    }
}
// ---------- end Matrix ----------
//https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 より
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

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

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

// ここまで

use matrix::*;
use std::io::Write;

impl SemiRing for ModInt {
    fn zero() -> Self {
        ModInt::zero()
    }
    fn one() -> Self {
        ModInt::one()
    }
}

fn run() {
    input! {
        h: usize,
        w: usize,
        l: u32,
        r: u32,
    }
    let d = r - l + 1;
    let x = ModInt(d / 2);
    let y = ModInt(d) - x;
    let mut mat = SquareMatrix::<ModInt>::zero();
    mat.set_at(0, 0, y);
    mat.set_at(1, 1, y);
    mat.set_at(0, 1, x);
    mat.set_at(1, 0, x);
    let p = mat.matpow(h);
    let q = p.matpow(w);
    let a = q.get_at(0, 0);
    let b = q.get_at(1, 0);
    let mut ans = a;
    if h % 2 == 1 && w % 2 == 1 {
        ans += b;
    }
    println!("{}", ans);
}

fn main() {
    run();
}


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

// Field (mod prime) {{{
mod field {
	use std::ops::*;
	#[allow(dead_code)] pub const Z0: Field = Field(0);
	#[allow(dead_code)] pub const Z1: Field = Field(1);
	const P5: i32 = 998244353;
	const P6: i64 = P5 as i64;
	#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Default)] pub struct Field(i32);
	#[allow(dead_code)] impl Field {
		pub fn new<T: Into<i64>>(a: T) -> Self { Self(Self::cv(a)) }
		pub fn new_unchecked(a: i32) -> Self { Self(a) }
		fn hi(mut a: i32) -> i32 { if a >= P5 { a -= P5; } a }
		fn lo(mut a: i32) -> i32 { if a < 0 { a += P5; } a }
		fn cv<T: Into<i64>>(a: T) -> i32 { Self::lo((a.into() % P6) as i32) }
		pub fn inv(self) -> Self { self.pow(P5-2) }
		pub fn pow<T: Into<i64>>(self, b: T) -> Self {
			let b = b.into(); if b == 0 { Self(1) } else {
				let mut res = self.pow(b/2); res *= res; if b % 2 == 1 {res *= self;} res
			}
		}
	}
	impl Add for Field { type Output = Self; fn add(self, a: Self) -> Self::Output { Self(Self::hi(self.0 + a.0)) }}
	impl Sub for Field { type Output = Self; fn sub(self, a: Self) -> Self::Output { Self(Self::lo(self.0 - a.0)) }}
	impl Mul for Field { type Output = Self; fn mul(self, a: Self) -> Self::Output { Self(Self::cv(self.0 as i64 * a.0 as i64)) }}
	impl Div for Field { type Output = Self; fn div(self, a: Self) -> Self::Output { self * a.inv() }}
	impl Neg for Field { type Output = Self; fn neg(self) -> Self::Output { Self(Self::lo(-self.0)) }}
	impl AddAssign for Field { fn add_assign(&mut self, a: Self) { *self = *self + a; } }
	impl SubAssign for Field { fn sub_assign(&mut self, a: Self) { *self = *self - a; } }
	impl MulAssign for Field { fn mul_assign(&mut self, a: Self) { *self = *self * a; } }
	impl DivAssign for Field { fn div_assign(&mut self, a: Self) { *self = *self / a; } }
	use std::fmt::{Display, Formatter, Result};
	impl Display for Field { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "{}", self.0) } }
}
#[allow(unused_imports)] use field::{Field, Field as Z, Z0, Z1};
//}}}
// Square Matrix (Field) {{{
type MatT = Field;
const MAT_T_0: MatT = Z0;
const MAT_T_1: MatT = Z1;
#[derive(Debug,Clone)] struct Mat { n: usize, a: Vec<MatT> }
#[allow(dead_code)] impl Mat {
	fn new(n:usize)->Self{Self{n,a:vec![MAT_T_0;n*n]}}
	fn diag(n:usize,v:MatT)->Self{let mut m=Self::new(n);let mut p=0;for _ in 0..n{m.a[p]=v;p+=n+1;}m}
	fn pow(&self,n:u64)->Self{if n==0{Self::diag(self.n,MAT_T_1)}else{let mut t=self.pow(n/2);t*=t.clone();if n%2==1{t*=self.clone();}t}}
	fn range(&self,r:Range<usize>,c:Range<usize>)->Vec<Vec<MatT>>{if r.start<r.end||c.start<c.end{Vec::new()}else{let mut res=vec![vec![MAT_T_0;c.end-c.start];r.end-r.start];
		for i in r.start..r.end{let ir=i-r.start;let ii=i*self.n+c.start;for j in 0..c.end-c.start{res[ir][j]=self.a[ii+j];}}res}}
	fn at(&self,r:usize,c:usize)->MatT{self.a[r*self.n+c]}
	fn at_mut<'a>(&'a mut self,r:usize,c:usize)->&'a mut MatT{&mut self.a[r*self.n+c]}//'
}
impl Mul for Mat{type Output=Self;fn mul(self,o:Self)->Self::Output{assert!(self.n==o.n);let n=self.n;let mut res=Self::new(n);
	for ii in(0..n).map(|i|i*n){for j in 0..n{let mut t=MAT_T_0;let mut kk=j;for k in 0..n{t+=self.a[ii+k]*o.a[kk];kk+=n;}res.a[ii+j]=t;}}res}}
impl Add for Mat{type Output=Self;fn add(mut self,o:Self)->Self{self+=o;self}}
impl Sub for Mat{type Output=Self;fn sub(mut self,o:Self)->Self{self-=o;self}}
impl MulAssign for Mat{fn mul_assign(&mut self,a:Self){*self=self.clone()*a;}}
impl AddAssign for Mat{fn add_assign(&mut self,o:Self){assert!(self.n==o.n);for(x,y)in self.a.iter_mut().zip(o.a.into_iter()){*x+=y;}} }
impl SubAssign for Mat{fn sub_assign(&mut self,o:Self){assert!(self.n==o.n);for(x,y)in self.a.iter_mut().zip(o.a.into_iter()){*x-=y;}} }
impl PartialEq for Mat{fn eq(&self,o:&Self)->bool{self.n==o.n&&self.a==o.a}}impl Eq for Mat{}
// }}}

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

	l!(n,m,l,r = rin.l());
	let sol = if n*m % 2 == 1 {
		Z::new(r-l+1).pow(n*m)
	} else {
		let b = (n*m+1)/2;
		let w = n*m/2;
		let o = Z::new((r+1)/2 - l/2);
		let e = Z::new(r/2 - (l-1)/2);
		let mut mat = Mat::new(2);
		*mat.at_mut(0,0) = e;
		*mat.at_mut(0,1) = o;
		*mat.at_mut(1,0) = o;
		*mat.at_mut(1,1) = e;
		let bm = mat.pow(b as u64);
		let bw = mat.pow(w as u64);
		bm.at(0,1) * bw.at(0,1) + bm.at(1,1) * bw.at(1,1)
	};
	writeln!(rout, "{}", sol).ok();
}


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

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

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

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

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

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

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

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

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

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

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

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

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (let _ = write!(out,$($format)*););
    }
    input!(n: i64, m: i64, l: i64, r: i64);
    let a = (n * m + 1) / 2;
    let b = n * m - a;
    let d = r / 2 - (l - 1) / 2;
    let c = r - l + 1 - d;
    if a != b {
        puts!("{}\n", ModInt::new(c + d).pow(n * m));
        return;
    }
    let diff = ModInt::new(d) - ModInt::new(c);
    puts!("{}\n",
          (ModInt::new(c + d).pow(n * m) + diff.pow(n * m))
          * ModInt::new(2).inv());
}

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;

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

fn div_and_ceil(n1: i32, n2: i32) -> i32 {
    if n1 % n2 == 0 {
        n1 / n2
    } else {
        n1 / n2 + 1
    }
}

fn main() {
    let count = readln!(i32);
    let width = (count as f64).sqrt() as i32;
    println!("{}", width + div_and_ceil(count, width));
}


#![allow(unused_imports)]
#![allow(unused_macros)]
// use proconio::input;
use std::cmp::Ordering::*;
use std::collections::{BTreeMap, BTreeSet};
use std::io::{self, BufWriter, Write};
use std::str::{self, SplitAsciiWhitespace};

// I have no idea what I'm doing

macro_rules! answer {
    ($out:ident, $ans:expr) => {
        writeln!($out, "{}", $ans)
    };
}

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

    let n: i64 = scan.token();

    let sqrt = (1..=n).take_while(|x| x * x <= n).last().unwrap();

    answer!(out, sqrt + (n + sqrt - 1) / sqrt)
}

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

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

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

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

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

// aka #![feature(bool_to_option)]
trait BoolThen {
    fn then_<T>(self, f: impl FnOnce() -> T) -> Option<T>;
}

impl BoolThen for bool {
    fn then_<T>(self, f: impl FnOnce() -> T) -> Option<T> {
        if self {
            Some(f())
        } else {
            None
        }
    }
}

trait BoolToYes {
    fn yes(self) -> &'static str;
}

impl BoolToYes for bool {
    fn yes(self) -> &'static str {
        if self {
            "YES"
        } else {
            "NO"
        }
    }
}


use std::io;

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

fn main() {
    let n = read_i32();
    let mut a = 0;
    let mut b = 0;
    while a * b < n {
        if a == b {
            a += 1;
        } else {
            b += 1;
        }
    }
    println!("{}", a + b);
}


#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, StdoutLock, Write};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_macros)]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; let mut next = || { iter . next ( ) . unwrap ( ) } ; input_inner ! { next , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let mut bytes = std :: io :: Read :: bytes ( std :: io :: BufReader :: new ( stdin . lock ( ) ) ) ; let mut next = move || -> String { bytes . by_ref ( ) . map ( | r | r . unwrap ( ) as char ) . skip_while ( | c | c . is_whitespace ( ) ) . take_while ( | c |! c . is_whitespace ( ) ) . collect ( ) } ; input_inner ! { next , $ ( $ r ) * } } ; }
#[allow(unused_macros)]
macro_rules ! input_inner { ( $ next : expr ) => { } ; ( $ next : expr , ) => { } ; ( $ next : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ next , $ t ) ; input_inner ! { $ next $ ( $ r ) * } } ; }
#[allow(unused_macros)]
macro_rules ! read_value { ( $ next : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ next , $ t ) ) ,* ) } ; ( $ next : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ next , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ next : expr , chars ) => { read_value ! ( $ next , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ next : expr , bytes ) => { read_value ! ( $ next , String ) . into_bytes ( ) } ; ( $ next : expr , usize1 ) => { read_value ! ( $ next , usize ) - 1 } ; ( $ next : expr , $ t : ty ) => { $ next ( ) . parse ::<$ t > ( ) . expect ( "Parse error" ) } ; }
#[allow(dead_code)]
pub fn with_bufwriter<F: FnOnce(BufWriter<StdoutLock>) -> ()>(f: F) {
    let out = stdout();
    let writer = BufWriter::new(out.lock());
    f(writer)
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) } ; }
#[allow(dead_code)]
fn main() {
    input!{
        n: u64,
    }
    let mut i = 1;
    while i <= 31623 {
        if i * i == n {
            println!("{}", i * 2);
            return;
        }
        if i * i > n {
            if n <= i * (i - 1) {
                println!("{}", i * 2 - 1);
            } else {
                println!("{}", i * 2);
            }
            return;
        }
        i += 1;
    }
}


use std::io;

fn main() {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).expect("failed to read input");
    let s: u32 = buffer.trim().parse().expect("invalid input");

    println!("{}", if s == 2 { 2 } else { 1 });
}


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

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

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

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

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

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

thread_local!(static SRC: RefCell<Source> = RefCell::new(Source::from_stdin()));

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

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

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

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

fn main() {
    input! { n: mut u32 }

    if n > 2 {
        println!("1")
    } else {
        println!("{}", n)
    }
}


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

fn main() {
    let stdin = io::stdin();
    let line = stdin.lock()
        .lines()
        .next()
        .expect("there was no next line")
        .expect("the line could not be read");

    let numbers: Vec<_> = line.split(" ").collect();
    let v: i32 = numbers[0].parse().unwrap();
//    let b: i32 = numbers[1].parse().unwrap();

    println!("{}", if v == 2 {2} else {1});
}

//fn main() {
//    let mut line = String::new();
//    let stdin = io::stdin();
//    stdin.lock().read_line(&mut line).expect("Could not read line");
//    println!("{}", line)
//}

/*
fn main() {
    let stdin = io::stdin();
    let lines: Vec<String> = stdin.lock().lines().map(|x| x.unwrap()).collect();

    let line = &lines[0];

//    let data = fs::read_to_string("test").expect("Unable to read file");
//    println!("{}", data);

    let numbers: Vec<_> = line.split(" ").collect();
    let a: i32 = numbers[0].parse().unwrap();
    let b: i32 = numbers[1].parse().unwrap();

    println!("{}", a + b);
}

*/


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

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

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

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

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

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

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

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

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

impl std::fmt::Display for ModInt {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::str::FromStr for ModInt {
    type Err = std::num::ParseIntError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let val = s.parse::<u32>()?;
        Ok(ModInt::new(val))
    }
}

impl From<usize> for ModInt {
    fn from(val: usize) -> ModInt {
        ModInt((val % MOD as usize) as u32)
    }
}

#[allow(dead_code)]
impl ModInt {
    pub fn new(n: u32) -> ModInt {
        ModInt(n % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        assert!(self.0 > 0);
        self.pow(MOD - 2)
    }
}
// ---------- end ModInt ----------

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let n: u32 = it.next().unwrap().parse().unwrap();
    let k: usize = it.next().unwrap().parse().unwrap();
    let mut is_prime = vec![true; k + 1];
    for i in 2.. {
        if i * i > k {
            break;
        }
        if is_prime[i] {
            let mut j = i * i;
            while let Some(p) = is_prime.get_mut(j) {
                *p = false;
                j += i;
            }
        }
    }
    let mut mobius = vec![ModInt::one(); k + 1];
    for (i, p) in is_prime.into_iter().enumerate().skip(2) {
        if !p {
            continue;
        }
        let mut j = i;
        while let Some(x) = mobius.get_mut(j) {
            *x = -*x;
            j += i;
        }
        let k = i.saturating_mul(i);
        let mut j = k;
        while let Some(x) = mobius.get_mut(j) {
            *x = ModInt::zero();
            j += k;
        }
    }
    let pow: Vec<ModInt> = (0..=k).map(|k| ModInt::from(k).pow(n)).collect();
    let mut imos = vec![ModInt::zero(); 2 * k + 1];
    for (i, v) in mobius.into_iter().enumerate().skip(2) {
        if v.0 == 0 {
            continue;
        }
        for (x, &pow) in pow.iter().enumerate().skip(1) {
            if x * i > k {
                break;
            }
            let v = v * pow;
            let l = x * i;
            let r = (x + 1) * i;
            imos[l] += v;
            imos[r] -= v;
        }
    }
    let mut ans = ModInt::zero();
    for i in 1..=k {
        imos[i] = imos[i] + imos[i - 1];
        let way = ModInt::from(i).pow(n) + imos[i];
        ans += ModInt::new(way.0 ^ i as u32);
    }
    println!("{}", ans);
}

fn main() {
    run();
}


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

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

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

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

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

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

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

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

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

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

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

mod pollard_rho {
    use std::collections::HashMap;
    /// binary gcd
    pub fn gcd(mut x: i64, mut y: i64) -> i64 {
        if y == 0 { return x; }
        if x == 0 { return y; }
        let mut sh = 0;
        while ((x | y) & 1) == 0 {
            x >>= 1; y >>= 1; sh += 1;
        }
        while (x & 1) == 0 { x >>= 1; }
        while y != 0 {
            while (y & 1) == 0 { y >>= 1; }
            if x > y { let t = x; x = y; y = t; }
            y -= x;
        }
        x << sh
    }

    fn add_mod(x: i64, y: i64, n: i64) -> i64 {
        let z = x + y;
        if z >= n { z - n } else { z }
    }

    fn mul_mod(x: i64, mut y: i64, n: i64) -> i64 {
        assert!(x >= 0);
        assert!(x < n);
        let mut sum = 0;
        let mut cur = x;
        while y > 0 {
            if (y & 1) == 1 {
                sum = add_mod(sum, cur, n);
            }
            cur = add_mod(cur, cur, n);
            y >>= 1;
        }
        sum
    }

    fn mod_pow(x: i64, mut e: i64, n: i64) -> i64 {
        let mut prod = if n == 1 { 0 } else { 1 };
        let mut cur = x % n;
        while e > 0 {
            if (e & 1) == 1 {
                prod = mul_mod(prod, cur, n);
            }
            cur = mul_mod(cur, cur, n);
            e >>= 1;
        }
        prod
    }

    pub fn is_prime(n: i64) -> bool {
        if n <= 1 { return false; }
        let small = [2, 3, 5, 7, 11, 13];
        if small.iter().any(|&u| u == n) { return true; }
        if small.iter().any(|&u| n % u == 0) { return false; }
        let mut d = n - 1;
        let mut e = 0;
        while (d & 1) == 0 {
            d >>= 1;
            e += 1;
        }
        let a = [2, 325, 9375, 28178, 450775, 9780504, 1795265022];
        a.iter().all(|&a| {
            if a >= n { return true; }
            let mut x = mod_pow(a, d, n);
            if x == 1 { return true; }
            for _ in 0 .. e {
                if x == n - 1 {
                    return true;
                }
                x = mul_mod(x, x, n);
                if x == 1 { return false; }
            }
            x == 1
        })
    }

    fn pollard_rho(n: i64, c: &mut i64) -> i64 {
        if n % 2 == 0 { return 2; }
        loop {
            let mut x: i64 = 2;
            let mut y = 2;
            let mut d = 1;
            let cc = *c;
            let f = |i| add_mod(mul_mod(i, i, n), cc, n);
            while d == 1 {
                x = f(x);
                y = f(f(y));
                d = gcd((x - y).abs(), n);
            }
            if d == n {
                *c += 1;
                continue;
            }
            return d;
        }
    }

    /// Outputs (p, e) in p's ascending order.
    pub fn factorize(x: i64) -> Vec<(i64, usize)> {
        if x <= 1 {
            return Vec::new();
        }
        let mut hm = HashMap::new();
        let mut pool = vec![x];
        let mut c = 1;
        while let Some(u) = pool.pop() {
            if is_prime(u) {
                *hm.entry(u).or_insert(0) += 1;
                continue;
            }
            let p = pollard_rho(u, &mut c);
            pool.push(p);
            pool.push(u / p);
        }
        let mut v: Vec<_> = hm.into_iter().collect();
        v.sort();
        v
    }
} // mod pollard_rho

use pollard_rho::*;

fn calc(p: i64, e: usize, k: usize) -> ModInt {
    let mut dp = vec![vec![ModInt::new(0); e + 1]; k + 1];
    dp[0][e] = ModInt::new(1);
    let mut inv = vec![ModInt::new(0); e + 2];
    for i in 1 .. e + 2 {
        inv[i] = ModInt::new(i as i64).inv();
    }
    for i in 0 .. k {
        let mut accum = ModInt::new(0);
        for j in (0 .. e + 1).rev() {
            accum += dp[i][j] * inv[j + 1];
            dp[i + 1][j] = accum;
        }
    }
    let mut tot = ModInt::new(0);
    let mut cur = ModInt::new(1);
    let p = ModInt::new(p);
    for i in 0 .. e + 1 {
        tot += dp[k][i] * cur;
        cur *= p;
    }
    tot
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (write!(out,$($format)*).unwrap());
    }
    input! {
        n: i64,
        k: usize,
    }
    let fac = factorize(n);
    let mut prod = ModInt::new(1);
    for (p, e) in fac {
        prod *= calc(p, e, k);
    }
    puts!("{}\n", prod);
}

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


#[allow(unused_imports)]
use std::cmp::{min,max};
#[allow(unused_imports)]
use std::collections::{BTreeMap,BTreeSet};
#[allow(unused_imports)]
use std::ops::*;
#[allow(unused_imports)]
use std::collections::BinaryHeap;

#[allow(unused_macros)]
macro_rules! ite {
    ($c:expr, $t:expr, $f:expr) => {{
        if $c { $t } else { $f }
    }};
}

// ref: tanakh <https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8>
// diff: using Parser
#[macro_export]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut parser = Parser::from_str($s);
        input_inner!{parser, $($r)*}
    };
    (parser = $parser:ident, $($r:tt)*) => {
        input_inner!{$parser, $($r)*}
    };
    (new_stdin_parser = $parser:ident, $($r:tt)*) => {
        let stdin = std::io::stdin();
        let reader = std::io::BufReader::new(stdin.lock());
        let mut $parser = Parser::new(reader);
        input_inner!{$parser, $($r)*}
    };
    ($($r:tt)*) => {
        input!{new_stdin_parser = parser, $($r)*}
    };
}

#[macro_export]
macro_rules! input_inner {
    ($parser:ident) => {};
    ($parser:ident, ) => {};
    ($parser:ident, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($parser, $t);
        input_inner!{$parser $($r)*}
    };
}

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

fn prime_factorization(n: i64) -> Vec<(i64,usize)> {
    let mut res = vec![];
    let mut x = n;
    let mut i = 2;
    while i * i <= x {
        let mut count = 0;
        while x % i == 0 {
            count += 1;
            x /= i;
        }
        if count != 0 {
            res.push((i, count));
        }
        i += 1;
    }
    if x != 1 {
        res.push((x,1));
    }
    res
}

fn dfs(ps: &Vec<(i64,usize)>, table: &Vec<Vec<Mod>>, i: usize, x: i64, prob: Mod) -> Mod {
    if i == ps.len() {
        return prob * Mod::new(x as u64);
    }
    let mut res = Mod::new(0);
    for k in 0..ps[i].1+1 {
        res += dfs(ps, table, i+1, x * ps[i].0.pow(k as u32), prob * table[i][k]);
    }
    res
}

fn main() {
    input! {
        n: i64,
        m: u64,
    }
    let ps = prime_factorization(n);

    let mut inv_table = vec![Mod::new(1), Mod::new(1)];
    for i in 2..1000 {
        inv_table.push(Mod::new(1) / Mod::new(i));
    }

    let mut table = vec![];
    for &(p,count) in &ps {
        let mut dp = vec![Mod::new(0); count+1];
        dp[count] = Mod::new(1);
        for _ in 0..m {
            let mut dp2 = vec![Mod::new(0); count+1];
            for j in 0..count+1 {
                for k in 0..j+1 {
                    // dp2[k] += dp[j] / Mod((j+1) as u64);
                    dp2[k] += dp[j] * inv_table[j+1];
                }
            }
            dp = dp2;
        }
        table.push(dp);
    }

    let res = dfs(&ps, &table, 0, 1, Mod::new(1));
    println!("{}", res.0);
}

use std::ops::*;

const MOD : u64 = 1_000_000_007;
#[derive(Clone,Copy,PartialEq,Debug)]
pub struct Mod (pub u64);

impl Mod {
    pub fn new(x: u64) -> Mod {
        Mod(x % MOD)
    }
    pub fn pow(self, n: u64) -> Mod {
        if n == 0 {
            return Mod(1);
        }
        let t = self.pow(n/2);
        if n % 2 == 0 {
            t * t
        }
        else {
            t * t * self
        }
    }
}

impl Add for Mod {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        Mod((self.0 + rhs.0) % MOD)
    }
}

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

impl Sub for Mod {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        Mod((self.0 + MOD - rhs.0 % MOD) % MOD)
    }
}

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

impl Neg for Mod {
    type Output = Mod;
    fn neg(self) -> Mod {
        Mod(MOD - self.0)
    }
}

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

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

impl Div for Mod {
    type Output = Self;
    fn div(self, rhs: Self) -> Self::Output {
        if rhs.0 == 0 {
            loop {}
        }
        assert!(rhs.0 != 0);
        self * rhs.pow(MOD-2)
    }
}

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

// ref: tatsuya6502 <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e>
// ref: wariuni <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e#comment-7040a5ae96305e884eb9>
// diff: using std::io::BufRead::fill_buf()
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}

impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}

impl<R:BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len,complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                (len, buf2[len-1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T:str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            }
            else {
                self.update_buf();
            }
        }
    }
}

use std::fmt::Display;
#[allow(dead_code)]
fn write_vec<T: Display>(xs: &Vec<T>) {
    if xs.len() == 0 {
        println!();
        return;
    }
    print!("{}", xs[0]);
    for i in 1..xs.len() {
        print!(" {}", xs[i]);
    }
    println!();
}


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

const MOD: u128 = 1000000007;

fn get_vals<T>(count: usize) -> Vec<T> where
    T: FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Debug {
    let mut val = String::new();
    stdin().read_line(&mut val).expect("Failed to read line");
    val.split_whitespace()
        .map(|x|
            x.parse::<T>().expect("Failed to parse value"))
        .take(count).collect()
}

pub fn main() {
    let mut ins = get_vals::<usize>(2);
    let (n, k) = (ins.remove(0), ins.remove(0));
    let mut dp = vec![vec![0 as u128; k]; n];
    for x in dp[0].iter_mut() {
        *x = 1;
    }
    for i in dp.iter_mut() {
        i[0] = 1;
    }
    for i in 1..dp.len() {
        let facs = factor((i as u64) + 1);
        for j in 1..dp[i].len() {
            dp[i][j] = (&facs).into_iter()
                .map(|x| dp[(*x as usize) - 1][j - 1])
                .sum::<u128>() % MOD;
        }
    }
    // for i in &dp {
    //     for j in i {
    //         print!("{0: <10}", *j)
    //     }
    //     println!()
    // }
    let ans: u128 = dp.iter().map(|x| x[k - 1]).sum();
    println!("{}", ans % MOD)
}

pub fn factor(input: u64) -> Vec<u64> {
    let mut vector = vec![];

    let mut i = 1;
    while i * i <= input {
        if input % i == 0 {
            vector.push(i);
            if i != input / i {
                vector.push(input / i);
            }
        }
        i += 1;
    }

    vector
}


// CodeForces 414b Rust Solution
// (from CF 414b Solution with ruby)

use std::io;

fn main() {
    let stdin = io::stdin();
    let mut line = String::new();
    let modulo = 1_000_000_000 + 7;
    if let Ok(_) = stdin.read_line(&mut line) {
        let words = line.split_whitespace();
        let parsed: Vec<usize> = words.map( |s| s.parse::<usize>().unwrap() ).collect();
        let n = parsed[0];
        let k = parsed[1];
        let mut dp:Vec<Vec<i64>> = vec![vec![0; n + 1usize]; k + 1usize];

        for j in 1..=n {
            dp[1][j] = 1;
        }

        for i in 2..=k {
            for j in 1..=n {
                let mut l = j;
                while l <= n {
                    dp[i][l] = (dp[i][l] + dp[i-1][j])%modulo;
                    l += j;
                }
            }
        }

        //println!("{:?}", dp);
        let mut sum: i64 = 0i64;
        for value in &dp[k] {
            sum = (sum + value)%modulo;
        }

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

// # coding: utf-8
// # Good sequence의 길이는 k, 숫자 제한은 n까지
// # 1부터 n까지 감소 없는 방향으로 (증가 or 같음)으로 만들어지는 Good seq의 수
// # Good seq에서는 이전 숫자가 다음숫자를 나눠도 잘 떨어진다
// # 문제 이해를 제대로 하고 시작합시다.
// # 여기는 1로 끝나도 되고 2로 끝나도 되고 n으로 끝나도 됨
// # 즉 바닥부터 모든 경우가 나와야한다.
// # n = 3, k = 3 에서 한번 트리 분기를 봐보면
// #                           R
// #                1          2          3
// #          1     2    3     2          3
// #  꼴로 반복 된다. 이 해법은 CF 414b의 기존 정답과도 동일함
// #  (1,1) (1,2), (1,3) (2,2), (3,3) total 5 tuples.
// #  이 개수는 tree의 k depth에서의 child 수를 구하는 것과 동일하다.
// #  child에서 1 2 3 이 각각 몇회 나오는지 카운트 한다면 충분할 것 같음
// #
// #  아 근데 자꾸 타임아웃나서 뒈질 것 같네여

// # << 이 문제는 Ruby의 퍼포먼스 문제로 일단 제출 중단합니다. >>

// n, k = gets.split.map(&:to_i)
// MODULO_BASE = 10 ** 9 + 7
// dpcounters = []
// init = Array.new(n + 1) { 1 } # k = 1에서는 각 하나씩
// init[0] = 0 # 당연히 0이죠
// dpcounters << init

// for a in 2..k
//   sub_dpcounter = Array.new(n + 1) { 0 }
//   for b in 1..n
//     c = b
//     while c <= n
//       sub_dpcounter[c] = (sub_dpcounter[c] + dpcounters.last[b]) % MODULO_BASE
//       c += b
//     end
//   end
//   dpcounters << sub_dpcounter
// end

// puts dpcounters.last.inject { |sum, n| (sum + n) % MODULO_BASE }


const MOD: usize = 1000000007;

fn count_good_sequences(n: usize, k: usize) -> usize {
    let mut d: Vec<Vec<usize>> = vec![vec![0; n + 1]; k + 1];
    d[1] = vec![1; n + 1];
    d[1][0] = 0;

    for length in 2..=k {
        for x in 1..=n {
            for t in (x..=n).step_by(x) {
                d[length][t] += d[length - 1][x];
                d[length][t] %= MOD;
            }
        }
    }
    // dbg!(&d);
    let mut sum: usize = 0;
    for x in d.last().unwrap() {
        sum += x;
        sum %= MOD;
    }
    sum
}

fn main() {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    let mut n_k = buf.trim().split_whitespace().map(|x| x.parse::<usize>().unwrap());
    let n = n_k.next().unwrap();
    let k = n_k.next().unwrap();

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


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

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

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

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

fn get_divs(x: usize) -> Vec<usize> {
    let mut result = vec![1usize];
    for i in 2..=x {
        if x % i == 0 {
            result.push(i);
        }
    }
    result
}

fn _main() -> std::io::Result<()> {
    let mut scan = Scan::new();
    let n: usize = scan.next();
    let k: usize = scan.next();
    let mut divs: Vec<Vec<usize>> = vec![Vec::new(); 2048];
    for i in 1..=n {
        divs[i] = get_divs(i);
    }
    let mut dp = [[0usize; 2048]; 2048];
    for i in 1..=n {
        dp[1][i] = 1;
    }
    for i in 2..=k {
        for j in 1..=n {
            for d in &divs[j] {
                dp[i][j] = (dp[i][j] + dp[i - 1][*d]) % 1000000007;
            }
        }
    }
    let mut result = 0usize;
    for i in 1..=n {
        result = (result + dp[k][i]) % 1000000007;
    }
    println!("{}", result);
    Ok(())
}

fn main() -> std::io::Result<()> {
    std::thread::Builder::new()
        .stack_size(1 << 26)
        .spawn(_main)
        .unwrap()
        .join()
        .unwrap()?;
    Ok(())
}


use std::io::{self, prelude::*};

#[allow(unused_must_use)]
fn solve<B: BufRead, W: Write>(mut scan: Scanner<B>, mut w: W) {
    let n = scan.token::<usize>();
    let m = scan.token::<usize>();

    let mut primes = [true; 51];

    primes[0] = false;
    primes[1] = false;

    for i in 2usize..=50 {
        for j in ((2*i)..=50).step_by(i) {
            primes[j] = false;
        }
    }

    let mut i = n;
    assert!(primes[i]);

    let mut ans = "NO";
    while i < 50 {
        i += 1;
        if primes[i] == true {
            if i == m {
                ans = "YES"
            }
            break;
        }
    }

    writeln!(w, "{}", ans);
}

fn main() {
    let stdin = io::stdin();
    let stdout = io::stdout();
    let reader = Scanner::new(stdin.lock());
    let writer = io::BufWriter::new(stdout.lock());
    solve(reader, writer);
}

#[allow(dead_code)]
fn matrix_to_str<T: ToString>(matrix: &Vec<Vec<T>>, separator: &str) -> String {
    use std::fmt::Write;
    let mut ans = String::new();
    for line in matrix.iter() {
        for elem in line.iter() {
            write!(&mut ans, "{}{}", elem.to_string(), separator).unwrap();
        }
        write!(&mut ans, "\n").unwrap();
    }
    ans
}
pub struct Scanner<B> {
    reader: B,
    buf_str: Vec<u8>,
    buf_iter: std::str::SplitWhitespace<'static>,
}
impl<B: BufRead> Scanner<B> {
    pub fn new(reader: B) -> Self {
        Self {
            reader,
            buf_str: Vec::new(),
            buf_iter: "".split_whitespace()
        }
    }
    pub fn token<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buf_iter.next() {
                return token.parse().ok().expect("Failed parse");
            }
            self.buf_str.clear();
            self.reader.read_until(b'\n', &mut self.buf_str).expect("Failed read");
            self.buf_iter = unsafe {
                let slice = std::str::from_utf8_unchecked(&self.buf_str);
                std::mem::transmute(slice.split_whitespace()) }
        }
    }
    pub fn get_matrix<T: std::str::FromStr>(&mut self, m: usize, n: usize) -> Vec<Vec<T>> {
        // m rows and n columns
        let mut ans: Vec<Vec<T>> = Vec::with_capacity(m);
        for i in 0..m {
            ans.push(Vec::with_capacity(n));
            for _ in 0..n {
                ans[i].push(self.token::<T>());
            }
        }
        ans
    }
}


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

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

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

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

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

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

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

fn main() {
  let mut sieve = vec![true; 51];
  for i in 2..50 {
    let mut j = 2 * i;
    while j < 51 {
      sieve[j] = false;
      j += i;
    }
  }
  scanln!(n: usize, m: usize);
  let mut next_prime = n;
  for i in n+1..51 {
    if sieve[i] { next_prime = i; break; }
  }
  if next_prime == m {
    println!("YES");
  } else {
    println!("NO");
  }
}


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

#[allow(unused_macros)]
macro_rules! a {
    ($c: tt, $x: expr, $y: expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
struct WordReader<'a> { it : SplitAsciiWhitespace<'a>, }
#[allow(dead_code)]
impl<'a> WordReader<'a> {
    fn new<T: Read>(b: &mut String, mut r: T) -> WordReader {
        b.clear();
        r.read_to_string(b).ok();
        WordReader { it: b.split_ascii_whitespace() }
    }
    fn from_stdin(b: &mut String) -> WordReader {
        WordReader::new(b, stdin())
    }
    fn sl(&mut self) ->  &str { self.it.next().unwrap() }
    fn bs(&mut self) -> &[u8] { self.sl().as_bytes()    }
    fn s(&mut self) -> String { String::from(self.sl()) }
    fn i(&mut self) ->    i32 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn vi(&mut self, n: usize) -> Vec<i32> {
        self.vp::<i32>(n)
    }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}

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

fn f(a: i32) -> i32 {
    let p = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47];
    for i in 0..p.len() {
        if a == p[i] {
            return i as i32;
        }
    }
    -1
}
fn main() {
    let mut bin = String::new();
    let mut input = WordReader::from_stdin(&mut bin);

    let a = f(input.i());
    let b = f(input.i());
    if a + 1 == b {
        println!("YES");
    } else {
        println!("NO");
    }
}


#![allow(non_snake_case, unused_imports)]

// Input macros
macro_rules! input { (source = $s:expr, $($r:tt)*) => { let mut iter = $s.split_whitespace(); let mut next = || { iter.next().unwrap() }; input_inner!{next, $($r)*} }; ($($r:tt)*) => { let stdin = std::io::stdin(); let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); let mut next = move || -> String{ bytes.by_ref().map(|r|r.unwrap() as char).skip_while(|c|c.is_whitespace()).take_while(|c|!c.is_whitespace()).collect() }; input_inner!{next, $($r)*} }; }
macro_rules! input_inner { ($next:expr) => {}; ($next:expr, ) => {}; ($next:expr, $var:ident : $t:tt $($r:tt)*) => { let $var = read_value!($next, $t); input_inner!{$next $($r)*} }; ($next:expr, mut $var:ident : $t:tt $($r:tt)*) => { let mut $var = read_value!($next, $t); input_inner!{$next $($r)*} }; }
macro_rules! read_value { ($next:expr, ( $($t:tt),* )) => { ( $(read_value!($next, $t)),* ) }; ($next:expr, [ $t:tt ; $len:expr ]) => { (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>() }; ($next:expr, [ $t:tt ]) => { { let len = read_value!($next, usize); (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>() } }; ($next:expr, chars) => { read_value!($next, String).chars().collect::<Vec<char>>() }; ($next:expr, bytes) => { read_value!($next, String).into_bytes() }; ($next:expr, usize1) => { read_value!($next, usize) - 1 }; ($next:expr, $t:ty) => { $next().parse::<$t>().expect("Parse error") }; }

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

// Functions

// Main
fn main(){
    input!{
        N: u64,
        M: u64,
    }
    let mut next_prime = 0;
    for i in N+1..M+1{
        let mut cnt = 0;
        for j in 2..i{
            if i%j==0{
                cnt += 1;
            }
        }
        if cnt == 0{
            next_prime = i;
            break;
        }
    }
    println!("{}", if next_prime==M{"YES"}else{"NO"});
}


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

fn get_pair() -> (i32, i32) {
	let mut input = String::new();

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

	let v = input.trim()
			.split_whitespace()
			.map(|d| i32::from_str(d).unwrap())
			.collect::<Vec<_>>();

	(v[0], v[1])
}

fn main() {
	let (n, m) = get_pair();

	let mut v = false;
	for x in n+1..m+1 {
		if is_prime(x) {
			if x == m {
				v = true;
			}
			break;
		}
	}

	if v {
		println!("YES");
	} else {
		println!("NO");
	}

	fn is_prime(n: i32) -> bool {
		let m = (n as f32).sqrt().round() as i32;
		for i in 2..m+1 {
			if n%i == 0 {
				return false;
			}
		}
		true
	}
}