#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(long long i=0;i<n;i++)
#define all(v) v.begin(),v.end()

using vi = vector<int>; // intの1次元の型に vi という別名をつける
using vvi = vector<vi>; // intの2次元の型に vvi という別名をつける
using vvvi = vector<vvi>;
using ll = long long; //long longをllだけにした
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll =vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using mii = map<int,int>;


void printv(vector<long long> v);

vector<ll> keta(ll x);


long long modpow(long long a, long long n, long long mod);
long long modinv(long long a, long long mod);

//20200416
vector<long long> inputv(long long n);

//20200417
vector<long long> yakusuu(int n);
map<long long,long long> soinsuu(long long n);
vector<vector<long long>> maze(long long i,long long j,vector<string> &s);


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



//ベクトルの出力(検証済)
//debug用にvectorの中身を出力する
void printv(vector<long long> v){
    cout<<"{ ";
    for(auto &p:v){
        cout<<p<<",";
    }
    cout<<"}"<<endl;
}



//10進法でn桁の整数xに対して、大きい方の位から、その位の1桁の数字を
//収納した長さnのベクトルを返す
//0に対しては{0}を返す
//検証済み
vector<ll> keta(ll x){
    if(x==0) return {0};
    ll n=log10(x)+1;//xの桁数
    vll w(n,0);
    for(ll i=0;i<n;i++){
        ll p;
        p=x%10;
        x=x/10;
        w[n-1-i]=p;
    }
    return w;
}


//20200415
// a^n mod を計算する
long long modpow(long long a, long long n, long long mod) {
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

// a^{-1} mod を計算する
//modとaが互いに素のときのみ有効(数学的に逆元が一意に定まるのがそのときのみ)
long long modinv(long long a, long long mod) {
    return modpow(a, mod - 2, mod);
}



//整数n個の入力を受け取ってベクトルに突っ込んで返す
//チェック済み
vector<long long> inputv(long long n){
    vector<long long> v(n);
    for(long long i=0;i<n;i++){
        cin>>v[i];
    }
    return v;
}


vector<long long> yakusuu(long long n)//nの約数を列挙
{
	vector<long long> ret;
	for(long long i=1 ; i<=sqrt(n) ; ++i)
	{
		if(n%i == 0)
		{
			ret.push_back(i);
			if(i*i!=n)
			{
				ret.push_back(n/i);
			}
		}
	}
    sort(ret.begin(),ret.end());
	return ret;
}


map<long long,long long> soinsuu(long long n){
    map <long long,long long> m;
    long long p=sqrt(n);
    while(n%2==0){
        n/=2;
        if(m.count(2)){
            m[2]++;
        }else{
            m[2]=1;
        }
    }
    for(long long i=3;i*i<=n;i+=2){   
        while(n%i==0){
            n/=i;
            if(m.count(i)){
                m[i]++;
            }else{
                m[i]=1;
            }
        }
    }
    if(n!=1) m[n]=1;
    return m;
}




//スタートが(i,j)の迷路の全ての地点までの距離を幅優先探索で解く
//スタートから何マス離れているか(辿り着けない場合は-1)を入れたベクトルを返す
//壁からスタートしても正常に動作するので注意(この関数の外で処理が必要)
//検証済み 一応O(地図の広さ)くらい
vector<vector<long long>> maze(ll i,ll j,vector<string> &s){
    ll h=s.size();
    ll w=s[0].size();
    queue<vector<long long>> q;
    vector<vector<long long>> dis(h,vll(w,-1));
    q.push({i,j});
    dis[i][j]=0;
    while(!q.empty()){
        auto v=q.front();
        q.pop();
        if(v[0]>0 && s[v[0]-1][v[1]]=='.' && dis[v[0]-1][v[1]]==-1){
            dis[v[0]-1][v[1]]=dis[v[0]][v[1]]+1;
            q.push({v[0]-1,v[1]});
        }
        if(v[1]>0 && s[v[0]][v[1]-1]=='.' && dis[v[0]][v[1]-1]==-1){
            dis[v[0]][v[1]-1]=dis[v[0]][v[1]]+1;
            q.push({v[0],v[1]-1});
        }
        if(v[0]<h-1 && s[v[0]+1][v[1]]=='.' && dis[v[0]+1][v[1]]==-1){
            dis[v[0]+1][v[1]]=dis[v[0]][v[1]]+1;
            q.push({v[0]+1,v[1]});
        }
        if(v[1]<w-1 && s[v[0]][v[1]+1]=='.' && dis[v[0]][v[1]+1]==-1){
            dis[v[0]][v[1]+1]=dis[v[0]][v[1]]+1;
            q.push({v[0],v[1]+1});
        }
    }
    return dis;//スタートから何マス離れているか(辿り着けない場合は-1)
}


//エラトステネスのふるいによりn以下の素数を全てベクトルに入れて返す
// vector<long long> eratos(long long n){
// }



//二項係数の剰余を求める
//引数は剰余の形ではなくもとの数そのものである
//未検証(検証サンプルがない)
long long modC(long long n,long long k,long long mod){
    if(n<k) return 0;
    long long p=1,q=1;
    for(long long i=0;i<k;i++){
        p = p*(n-i-1)%mod;
        q = q *(i+1)%mod;
    }
    return p*modinv(q,mod)%mod;
}


//20200418
// 整数のとき限定の普通のPOW関数
//標準機能のpow(a,n)は整数だとバグるのでこちらを使う
long long POW(long long a, long long n) {
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a;
        a = a * a;
        n >>= 1;
    }
    return res;
}

//cout<<fixed<<setprecision(10);
//////////////////////////////////////////////////




int main(){
    long long const mod=1e9+7;
    ll n,k;
    cin>>n>>k;
    vll a(k+1,0);//a[i]はgcdがiとなるケースの数
    
    for(long long i=k;i>=1;i--){
        ll p=k/i;
        a[i]=modpow(p,n,mod);
        for(long long j=2;j<=p;j++){
            a[i]-=a[i*j];
            a[i] = a[i] % mod;
        }
    }

    //printv(a);

    ll res=0;
    rep(i,k+1){
        res+=((i * a[i]) % mod);
        //cout<<res<<endl;
        res = res%mod;
    }
    if(res<0) res+=mod;
    cout<<res<<endl;
}

