# AtCoder Beginner Contest 162 E Sum of gcd of Tuples (Hard) 莫比烏斯反演做法

n個求和

$\sum_{i=1}^{k}\sum_{j=1}^{k}...\sum_{z=1}^{k} gcd(i,j...z)$

$f(x) = \sum_{i=1}^{k}\sum_{j=1}^{k}...\sum_{z=1}^{k} [gcd(i,j...z) = x]$

$g(x) = \sum_{x | d}f(d) =\sum_{x | d}\sum_{i=1}^{k}\sum_{j=1}^{k}...\sum_{z=1}^{k} [gcd(i,j...z) = d]$

= $[(int)(\frac{k}{x})]^n$ gcd(i,j,…z)爲x的倍數，每個位置取值$(int)(\frac{k}{x})$

$T = \frac{d}{x}$ ,$d = T*x$

= $\sum_{x=1}^{k}x\sum_{T}{u(T)}[(int)(\frac{k}{T*x})]^n$

$D =x * T$

= $\sum_{D=1}^{k}[(int)(\frac{k}{T*x})]^n\sum_{T|D}{u(T)}*\frac{D}{T}$

= $\sum_{D=1}^{k}[(int)(\frac{k}{D})]^nphi(D)$

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
#define IOS ios::sync_with_stdio(0)
typedef long long ll;
const ll mod = 1e9+7;

bool vis[man];
int prime[man],phi[man];

void init(int maxn){
phi[1] = 1;
vis[1] = 1;
int cnt = 0;
for(int i = 2;i <= maxn;i++){
if(!vis[i]){
prime[cnt++] = i;
phi[i] = i-1;
}
for(int j = 0;j < cnt && i * prime[j] <= maxn;j++){
vis[i*prime[j]] = 1;
phi[i*prime[j]] = phi[i]*phi[prime[j]];
if(i%prime[j]==0){
phi[i*prime[j]] = phi[i]*prime[j];
break;
}
}
}
for(int i = 1;i <= maxn;i++){
phi[i] = (phi[i-1] + phi[i])%mod;
}
}

ll quick_mod(ll a,ll b){
ll ans = 1;
while(b){
if(b&1)ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}

int main() {
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int n,k;
cin >> n >> k;
init(k+5);
ll ans = 0;
for(int l = 1,r = 0;l <= k;l = r + 1){
r = k / (k / l);
ans = (ans + quick_mod(k/l,n)*(phi[r] - phi[l-1] + mod)%mod) % mod;
}
cout << ans << endl;
return 0;
}