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

trait PowerLog: Clone
    where Self: Sized
{
    fn unit() -> Self;
    fn mult(x: &Self, y: &Self) -> Self;
    fn power(&self, mut n: usize) -> Self {
        let mut ret = Self::unit();
        let mut two_pow = (*self).clone();
        while n > 0 {
            if n & 1 != 0 { ret = Self::mult(&ret, &two_pow); }
            two_pow = Self::mult(&two_pow, &two_pow);
            n >>= 1;
        }
        return ret;
    }
}

impl PowerLog for usize {
    fn unit() -> usize { return 1; }
    fn mult(x: &usize, y: &usize) -> usize { return *x * *y; }
}


// (g, s, t) == egcd(a, b)  --->  sa + tb = g
pub fn egcd(a: isize, b: isize) -> (isize, isize, isize) {
    if a == 0 {
        (b, 0, 1)
    } else {
        let (g, t, u) = egcd(b % a, a);
        (g, u - (b / a) * t, t)
    }
}

pub fn gcd(a: isize, b: isize) -> isize {
    if a == 0 { b }
    else      { gcd(b % a, a) }
}

static mut MODN: isize = 1_000_000_007;

#[derive(Debug, Copy, Clone)]
pub struct Fp(isize);

impl Fp {
    pub fn modn() -> isize { unsafe{MODN} }

    pub fn set_modn(v: isize) -> () { unsafe{MODN = v;} }
    
    pub fn inverse(self) -> Self {
        if self.0 == 0 {
            assert!(false, "inverse() is called for zero.");
        }
        let (_, u, _) = egcd(self.0, Fp::modn());
        Fp::from(u)
    }
}

impl std::cmp::PartialEq for Fp {
    fn eq(&self, o: &Self) -> bool { (self.0 - o.0) % Fp::modn() == 0 }
}

impl From<isize> for Fp {
    fn from(x: isize) -> Fp {
        if x < 0 { Fp(x % Fp::modn() + Fp::modn()) }
        else     { Fp(x % Fp::modn()) }
    }
}

impl From<i32> for Fp {
    fn from(x: i32) -> Fp { Fp::from(x as isize) }
}

impl From<usize> for Fp {
    fn from(x: usize) -> Fp { Fp((x as isize) % Fp::modn()) }
}

impl From<Fp> for isize {
    fn from(x: Fp) -> isize {
        if x.0 < 0 { x.0 % Fp::modn() + Fp::modn() }
        else       { x.0 % Fp::modn() }
    }
}

impl From<Fp> for usize {
    fn from(x: Fp) -> usize { isize::from(x) as usize }
}

impl std::ops::AddAssign for Fp {
    fn add_assign(&mut self, o: Self) {
        self.0 += o.0;
        if self.0 >= Fp::modn() { self.0 -= Fp::modn(); }
    }
}

impl std::ops::SubAssign for Fp {
    fn sub_assign(&mut self, o: Self) {
        if self.0 < o.0 { self.0 += Fp::modn(); }
        self.0 -= o.0;
    }
}

impl std::ops::MulAssign for Fp {
    fn mul_assign(&mut self, o: Self) {
        self.0 = (self.0 * o.0) % Fp::modn();
    }
}

impl std::ops::DivAssign for Fp {
    fn div_assign(&mut self, o: Self) { *self *= o.inverse(); }
}

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

impl std::ops::Add for Fp {
    type Output = Fp;
    fn add(self, o: Self) -> Self {
        let mut x = Fp(self.0);
        x += o;
        return x;
    }
}

impl std::ops::Sub for Fp {
    type Output = Fp;
    fn sub(self, o: Self) -> Self {
        let mut x = Fp(self.0);
        x -= o;
        return x;
    }
}

impl std::ops::Mul for Fp {
    type Output = Fp;
    fn mul(self, o: Self) -> Self {
        let mut x = Fp(self.0);
        x *= o;
        return x;
    }
}

impl std::ops::Div for Fp {
    type Output = Fp;
    fn div(self, o: Self) -> Self {
        let mut x = Fp(self.0);
        x /= o;
        return x;
    }
}

#[derive(Debug)]
pub struct Comb {
    v_fact: Vec<Fp>,
    v_inv_fact: Vec<Fp>,
}

impl Comb {
    pub fn new(n_max: usize) -> Comb {
        let mut v_fact = vec![Fp(1)];
        for i in 1..n_max+1 { v_fact.push(Fp::from(i) * v_fact[i-1]); }
        let mut v_inv_fact = vec![Fp(0); n_max];
        v_inv_fact.push(v_fact[n_max].inverse());
        for i in (1..n_max+1).rev() {
            v_inv_fact[i-1] = Fp::from(i) * v_inv_fact[i];
        }
        Comb { v_fact, v_inv_fact }
    }

    pub fn fact(&self, n: usize) -> Fp { self.v_fact[n] }

    pub fn comb(&self, n: usize, r: usize) -> Fp {
        self.v_fact[n] * self.v_inv_fact[r] * self.v_inv_fact[n-r]
    }

    pub fn perm(&self, n: usize, r: usize) -> Fp {
        self.v_fact[n] * self.v_inv_fact[n-r]
    }
}

impl PowerLog for Fp {
    fn unit() -> Fp { return Fp(1); }
    fn mult(x: &Fp, y: &Fp) -> Fp { return *x * *y; }
}

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    (itvar = $iter:ident, $($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)*}
    };
    ($($r:tt)*) => { input!{ itvar = iter, $($r)* } };
}

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

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

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

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

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

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

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

fn main() {
    let out = &mut std::io::BufWriter::new(std::io::stdout());

    input! { n: usize, k: usize }
    Fp::set_modn(1e9 as isize + 7);
    let mut tbl: Vec<Fp> = vec![Fp::from(0); k+1];
    for i in (1..k+1).rev() {
        let m = k / i;
        let mut j = 2*i;
        let mut sum = Fp::from(0);
        while j < k+1 {
            sum += tbl[j];
            j += i;
        }
        tbl[i] = Fp::from(m).power(n) - sum;
    }
    // dbg!(&tbl);
    let mut ans = Fp::from(0);
    for i in 1..k+1 {
        ans += tbl[i] * Fp::from(i);
    }
    writeln!(out, "{}", usize::from(ans)).ok();
}


Measured memory_bytes: 2800