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 :$base :expr } ) =>{read_value !($iter ,String ) .chars () .map (|c |(c as u8 -$base as u8 ) as usize ) .collect ::<Vec <usize >>() } ;($iter :expr ,{char :$base :expr } ) =>{read_value !($iter ,{chars :$base } ) [0 ] } ;($iter :expr ,chars ) =>{read_value !($iter ,String ) .chars () .collect ::<Vec <char >>() } ;($iter :expr ,char ) =>{read_value !($iter ,chars ) [0 ] } ;($iter :expr ,usize1 ) =>{read_value !($iter ,usize ) -1 } ;($iter :expr ,$t :ty ) =>{$iter .next () .unwrap () .parse ::<$t >() .unwrap () } ;}
macro_rules !input_inner {($iter :expr ) =>{} ;($iter :expr ,) =>{} ;($iter :expr ,mut $var :ident :$t :tt $($r :tt ) *) =>{let mut $var =read_value !($iter ,$t ) ;input_inner !{$iter $($r ) *} } ;($iter :expr ,mut $var :ident $($r :tt ) *) =>{input_inner !{$iter ,mut $var :usize $($r ) *} } ;($iter :expr ,$var :ident :$t :tt $($r :tt ) *) =>{let $var =read_value !($iter ,$t ) ;input_inner !{$iter $($r ) *} } ;($iter :expr ,$var :ident $($r :tt ) *) =>{input_inner !{$iter ,$var :usize $($r ) *} } ;}
macro_rules !input {(source =$s :expr ,$($r :tt ) *) =>{let mut iter =$s .split_whitespace () ;input_inner !{iter ,$($r ) *} } ;(iter =$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 ) *) =>{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 ) *} } ;}
const MOD: i64 = 1_000_000_007;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Modi64(pub i64);
impl Modi64 {
    #[inline]
    pub fn new(i: i64) -> Self {
        Modi64(Self::modulo(i, MOD))
    }
    #[inline]
    pub fn modulo(i: i64, m: i64) -> i64 {
        let mut x = i % m;
        if x < 0 {
            x += m;
        }
        x
    }
    pub fn pow(self, y: i64) -> Self {
        let mut y = Self::modulo(y, MOD - 1);
        let mut x = Self::new(1);
        let mut base = self;
        while y > 0 {
            if y & 1 == 1 {
                x *= base;
            }
            base *= base;
            y = y >> 1;
        }
        x
    }
    #[inline]
    pub fn inv(self) -> Self {
        let (mut x, mut s, mut t, mut u) = (1, self.0, MOD, 0);
        while t != 0 {
            let k = s / t;
            s -= k * t;
            std::mem::swap(&mut s, &mut t);
            x -= k * u;
            std::mem::swap(&mut x, &mut u);
        }
        Modi64::new(x)
    }
}
impl From<i64> for Modi64 {
    fn from(i: i64) -> Self {
        Self::new(i)
    }
}
impl std::ops::Add for Modi64 {
    type Output = Self;
    #[inline]
    fn add(self, rhs: Self) -> Self::Output {
        Modi64((self.0 + rhs.0) % MOD)
    }
}
impl<'a> std::ops::Add<Modi64> for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn add(self, rhs: Modi64) -> Self::Output {
        *self + rhs
    }
}
impl<'a> std::ops::Add<&'a Modi64> for Modi64 {
    type Output = Modi64;
    #[inline]
    fn add(self, rhs: &'a Modi64) -> Self::Output {
        self + *rhs
    }
}
impl<'a> std::ops::Add for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn add(self, rhs: Self) -> Self::Output {
        *self + *rhs
    }
}
impl std::ops::AddAssign for Modi64 {
    #[inline]
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs;
    }
}
impl<'a> std::ops::AddAssign<&'a Modi64> for Modi64 {
    #[inline]
    fn add_assign(&mut self, rhs: &'a Modi64) {
        *self += *rhs;
    }
}
impl std::ops::Sub for Modi64 {
    type Output = Self;
    #[inline]
    fn sub(self, rhs: Self) -> Self::Output {
        Self::new(self.0 - rhs.0)
    }
}
impl<'a> std::ops::Sub<Modi64> for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn sub(self, rhs: Modi64) -> Self::Output {
        *self - rhs
    }
}
impl<'a> std::ops::Sub<&'a Modi64> for Modi64 {
    type Output = Modi64;
    #[inline]
    fn sub(self, rhs: &'a Modi64) -> Self::Output {
        self - *rhs
    }
}
impl<'a> std::ops::Sub for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn sub(self, rhs: Self) -> Self::Output {
        *self - *rhs
    }
}
impl std::ops::SubAssign for Modi64 {
    #[inline]
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs;
    }
}
impl<'a> std::ops::SubAssign<&'a Modi64> for Modi64 {
    #[inline]
    fn sub_assign(&mut self, rhs: &'a Modi64) {
        *self -= *rhs;
    }
}
impl std::ops::Mul for Modi64 {
    type Output = Self;
    #[inline]
    fn mul(self, rhs: Self) -> Self::Output {
        Modi64(self.0 * rhs.0 % MOD)
    }
}
impl<'a> std::ops::Mul<Modi64> for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn mul(self, rhs: Modi64) -> Self::Output {
        *self * rhs
    }
}
impl<'a> std::ops::Mul<&'a Modi64> for Modi64 {
    type Output = Modi64;
    #[inline]
    fn mul(self, rhs: &'a Modi64) -> Self::Output {
        self * *rhs
    }
}
impl<'a> std::ops::Mul for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn mul(self, rhs: Self) -> Self::Output {
        *self * *rhs
    }
}
impl std::ops::MulAssign for Modi64 {
    #[inline]
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs;
    }
}
impl<'a> std::ops::MulAssign<&'a Modi64> for Modi64 {
    #[inline]
    fn mul_assign(&mut self, rhs: &'a Modi64) {
        *self *= *rhs;
    }
}
impl std::ops::Div for Modi64 {
    type Output = Self;
    #[inline]
    fn div(self, rhs: Self) -> Self::Output {
        self * rhs.inv()
    }
}
impl<'a> std::ops::Div<Modi64> for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn div(self, rhs: Modi64) -> Self::Output {
        *self * rhs.inv()
    }
}
impl<'a> std::ops::Div<&'a Modi64> for Modi64 {
    type Output = Modi64;
    #[inline]
    fn div(self, rhs: &'a Modi64) -> Self::Output {
        self * rhs.inv()
    }
}
impl<'a> std::ops::Div for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn div(self, rhs: Self) -> Self::Output {
        *self * rhs.inv()
    }
}
impl std::ops::DivAssign for Modi64 {
    #[inline]
    fn div_assign(&mut self, rhs: Self) {
        *self = *self * rhs.inv();
    }
}
impl<'a> std::ops::DivAssign<&'a Modi64> for Modi64 {
    #[inline]
    fn div_assign(&mut self, rhs: &'a Modi64) {
        *self *= rhs.inv();
    }
}
impl std::ops::Neg for Modi64 {
    type Output = Self;
    #[inline]
    fn neg(self) -> Self::Output {
        Self::new(-self.0)
    }
}
impl<'a> std::ops::Neg for &'a Modi64 {
    type Output = Modi64;
    #[inline]
    fn neg(self) -> Self::Output {
        -*self
    }
}
impl std::iter::Sum for Modi64 {
    #[inline]
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.fold(Self::new(0), std::ops::Add::add)
    }
}
impl<'a> std::iter::Sum<&'a Modi64> for Modi64 {
    #[inline]
    fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
        iter.fold(Self::new(0), |x, &y| x + y)
    }
}
impl std::fmt::Display for Modi64 {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> Result<(), std::fmt::Error> {
        write!(f, "{}", self.0)
    }
}
impl std::str::FromStr for Modi64 {
    type Err = std::num::ParseIntError;
    #[inline]
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        s.parse::<i64>().map(|i| Modi64::new(i))
    }
}
pub fn gcd(a: u64, b: u64) -> u64 {
    let mut a = a;
    let mut b = b;
    loop {
        if b == 0 {
            return a;
        }
        a %= b;
        if a == 0 {
            return b;
        }
        b %= a;
    }
}
fn main() {
    input! { n, k };
    let mut dp = vec![Modi64(0); k + 1];
    let mut ans = Modi64(0);
    for g in (1..k + 1).rev() {
        dp[g] = Modi64::new((k / g) as i64).pow(n as i64);
        for i in (g * 2..k + 1).step_by(g) {
            dp[g] = dp[g] - dp[i];
        }
        ans += dp[g] * Modi64::new(g as i64);
    }
    println!("{}", ans);
}


Measured memory_bytes: 2728