#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<map>
#include<ctime>
#include<set>
#include<queue>
#include<cmath>
#include<vector>
#include<bitset>
#include<functional>
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define REP(i,l,r) for((i)=(l);(i)<=(r);++(i))
#define REP2(i,l,r) for((i)=(l);(i)!=(r);++(i))
using namespace std;
typedef long long LL;
typedef double ld;
const int Mod=(int)1e9+7;
int n,m;
//\sum_{d|n} phi(d) = n
//对于任意一个元素,必然可以生成一个子群C_d,为n中mod d == 0的数的集合
//对于一个子群,其生成元个数为phi(d)
//而总数为n
//得证
//g(n)=\sum_{d|n} phi(d)
//G(n) = \sum_{i<=n} g(i) = \sum_{i<=n} \sum_{d|i} phi(d)
//G(n) = \sum_{d<=n} \sum_{j<=n/d} phi(d)
//在phi(d) 统计n/d次
//G(n) = \sum_{j<=n} \sum_{d<=n/j} phi(d)
//G(n) = \sum_{j<=n} S_{n/j}
//so calc(n)=G(n)-\sum_{j<=n} S_{n/j}
//and g(n)=n, G(n) = n*(n-1)/2
/*
以及对于squre-free number n
phi(nk)=\sum_{d|(n,k)} phi(n/d) phi(k)
这个的证明:令g=(n,k),则phi(nk)=phi(k) g phi(n)/phi(g)
g*phi(n)/phi(g) \sum_{d|g} phi(n)/phi(g/d) 得证
calc(n,m)=\sum_{j<=m} phi(nj)=\sum phi(j) \sum_{d|(j,n)} phi(n/d)
=\sum_{d<=n} phi(n/d) \sum_{j<=m/d} phi(dj)
=\sum_{d<=n,d|n} phi(n/d) calc(d, m/d)
若miu(n)==0
设miu(k)!=0,k|n,calc(n,m)=\frac{n}{k}calc(k,m)
*/
const int MAX=1000000+10;
int prime[MAX],phi[MAX],K[MAX],mm[MAX];
int q[MAX],top;
vector<int> yueshu[MAX];
map<int,int> S[MAX/10];
void update(int& a,int b)
{
a+=b;
if(a>=Mod)
a-=Mod;
}
LL calc(int n,int m)
{
int t=K[n];
if(m==0)
return 0;
if(t!=n && n!=1)
return (n/t) * calc(t,m) % Mod;
if(S[n].find(m)!=S[n].end())
return S[n][m];
int& ans=S[n][m];
if(n==1)
{
int now=m,next,t;
for(;now>=2;now=next)
{
t=m/now;
next=m/(t+1);
update(ans,(now-next) * calc(1,t) % Mod);
}
return ans=( (LL)m*(m+1)/2-ans + Mod ) % Mod;
}
int i;
REP2(i,0,(int)yueshu[n].size())
{
int d=yueshu[n][i];
update(ans,phi[n/d] * calc(d,m/d)% Mod);
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
#endif
int i;
scanf("%d%d",&n,&m);
mm[1]=phi[1]=K[1]=1;
for(i=2;i<MAX;++i)
{
if(!mm[i])
{
mm[i]=i;
phi[i]=i-1;
K[i]=i;
q[++top]=i;
}
for(int j=1;j<=top && q[j]*i<MAX;++j)
{
int u=q[j]*i;
mm[u]=q[j];
phi[u]=phi[i];
K[u]=K[i];
if(i%q[j]==0)
{
phi[u]*=q[j];
break;
}
phi[u]*=(q[j]-1);
K[u]*=q[j];
}
}
for(i=1;i<=n;++i)
for(int j=i;j<=n;j+=i)
yueshu[j].pb(i);
int now=0;
for(i=1;i<MAX;++i)
{
update(now,phi[i]);
S[1][i]=now;
}
int ans=0;
REP(i,1,n)
update(ans,calc(i,m));
printf("%d\n",ans);
return 0;
}
I2luY2x1ZGU8Y3N0ZGlvPgojaW5jbHVkZTxjc3RkbGliPgojaW5jbHVkZTxjc3RyaW5nPgojaW5jbHVkZTxhbGdvcml0aG0+CiNpbmNsdWRlPGlvc3RyZWFtPgojaW5jbHVkZTxmc3RyZWFtPgojaW5jbHVkZTxtYXA+CiNpbmNsdWRlPGN0aW1lPgojaW5jbHVkZTxzZXQ+CiNpbmNsdWRlPHF1ZXVlPgojaW5jbHVkZTxjbWF0aD4KI2luY2x1ZGU8dmVjdG9yPgojaW5jbHVkZTxiaXRzZXQ+CiNpbmNsdWRlPGZ1bmN0aW9uYWw+CiNkZWZpbmUgeCBmaXJzdAojZGVmaW5lIHkgc2Vjb25kCiNkZWZpbmUgbXAgbWFrZV9wYWlyCiNkZWZpbmUgcGIgcHVzaF9iYWNrCiNkZWZpbmUgUkVQKGksbCxyKSBmb3IoKGkpPShsKTsoaSk8PShyKTsrKyhpKSkKI2RlZmluZSBSRVAyKGksbCxyKSBmb3IoKGkpPShsKTsoaSkhPShyKTsrKyhpKSkKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnR5cGVkZWYgbG9uZyBsb25nIExMOwp0eXBlZGVmIGRvdWJsZSBsZDsKCmNvbnN0IGludCBNb2Q9KGludCkxZTkrNzsKCmludCBuLG07Ci8vXHN1bV97ZHxufSBwaGkoZCkgPSBuCi8v5a+55LqO5Lu75oSP5LiA5Liq5YWD57Sg77yM5b+F54S25Y+v5Lul55Sf5oiQ5LiA5Liq5a2Q576kQ19k77yM5Li6buS4rW1vZCBkID09IDDnmoTmlbDnmoTpm4blkIgKLy/lr7nkuo7kuIDkuKrlrZDnvqTvvIzlhbbnlJ/miJDlhYPkuKrmlbDkuLpwaGkoZCkKLy/ogIzmgLvmlbDkuLpuCi8v5b6X6K+BCgovL2cobik9XHN1bV97ZHxufSBwaGkoZCkKLy9HKG4pID0gXHN1bV97aTw9bn0gZyhpKSA9IFxzdW1fe2k8PW59IFxzdW1fe2R8aX0gcGhpKGQpCi8vRyhuKSA9IFxzdW1fe2Q8PW59IFxzdW1fe2o8PW4vZH0gcGhpKGQpCi8v5ZyocGhpKGQpIOe7n+iuoW4vZOasoQovL0cobikgPSBcc3VtX3tqPD1ufSBcc3VtX3tkPD1uL2p9IHBoaShkKQovL0cobikgPSBcc3VtX3tqPD1ufSBTX3tuL2p9Ci8vc28gY2FsYyhuKT1HKG4pLVxzdW1fe2o8PW59IFNfe24van0KLy9hbmQgZyhuKT1uLCBHKG4pID0gbioobi0xKS8yCgovKgogICDku6Xlj4rlr7nkuo5zcXVyZS1mcmVlIG51bWJlciBuCgogICBwaGkobmspPVxzdW1fe2R8KG4sayl9IHBoaShuL2QpIHBoaShrKQogICDov5nkuKrnmoTor4HmmI7vvJrku6RnPShuLGsp77yM5YiZcGhpKG5rKT1waGkoaykgZyBwaGkobikvcGhpKGcpCiAgIGcqcGhpKG4pL3BoaShnKSBcc3VtX3tkfGd9IHBoaShuKS9waGkoZy9kKSDlvpfor4EKCiAgIGNhbGMobixtKT1cc3VtX3tqPD1tfSBwaGkobmopPVxzdW0gcGhpKGopIFxzdW1fe2R8KGosbil9IHBoaShuL2QpCiAgID1cc3VtX3tkPD1ufSBwaGkobi9kKSBcc3VtX3tqPD1tL2R9IHBoaShkaikKICAgPVxzdW1fe2Q8PW4sZHxufSBwaGkobi9kKSBjYWxjKGQsIG0vZCkKCiAgIOiLpW1pdShuKT09MAogICDorr5taXUoaykhPTAsa3xu77yMY2FsYyhuLG0pPVxmcmFje259e2t9Y2FsYyhrLG0pCiAgICovCgpjb25zdCBpbnQgTUFYPTEwMDAwMDArMTA7CgppbnQgcHJpbWVbTUFYXSxwaGlbTUFYXSxLW01BWF0sbW1bTUFYXTsKaW50IHFbTUFYXSx0b3A7CnZlY3RvcjxpbnQ+IHl1ZXNodVtNQVhdOwptYXA8aW50LGludD4gU1tNQVgvMTBdOwoKdm9pZCB1cGRhdGUoaW50JiBhLGludCBiKQp7CiAgICBhKz1iOwogICAgaWYoYT49TW9kKQogICAgICAgIGEtPU1vZDsKfQoKTEwgY2FsYyhpbnQgbixpbnQgbSkKewogICAgaW50IHQ9S1tuXTsKICAgIGlmKG09PTApCiAgICAgICAgcmV0dXJuIDA7CiAgICBpZih0IT1uICYmIG4hPTEpCiAgICAgICAgcmV0dXJuIChuL3QpICogY2FsYyh0LG0pICUgTW9kOwogICAgaWYoU1tuXS5maW5kKG0pIT1TW25dLmVuZCgpKQogICAgICAgIHJldHVybiBTW25dW21dOwogICAgaW50JiBhbnM9U1tuXVttXTsKICAgIGlmKG49PTEpCiAgICB7CiAgICAgICAgaW50IG5vdz1tLG5leHQsdDsKICAgICAgICBmb3IoO25vdz49Mjtub3c9bmV4dCkKICAgICAgICB7CiAgICAgICAgICAgIHQ9bS9ub3c7CiAgICAgICAgICAgIG5leHQ9bS8odCsxKTsKICAgICAgICAgICAgdXBkYXRlKGFucywobm93LW5leHQpICogY2FsYygxLHQpICUgTW9kKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFucz0oIChMTCltKihtKzEpLzItYW5zICsgTW9kICkgJSBNb2Q7CiAgICB9CiAgICBpbnQgaTsKICAgIFJFUDIoaSwwLChpbnQpeXVlc2h1W25dLnNpemUoKSkKICAgIHsKICAgICAgICBpbnQgZD15dWVzaHVbbl1baV07CiAgICAgICAgdXBkYXRlKGFucyxwaGlbbi9kXSAqIGNhbGMoZCxtL2QpJSBNb2QpOwogICAgfQogICAgcmV0dXJuIGFuczsKfQoKaW50IG1haW4oKQp7CiNpZm5kZWYgT05MSU5FX0pVREdFCiAgICBmcmVvcGVuKCJpbnB1dC50eHQiLCJyIixzdGRpbik7ZnJlb3Blbigib3V0cHV0LnR4dCIsInciLHN0ZG91dCk7CiNlbmRpZgogICAgaW50IGk7CiAgICBzY2FuZigiJWQlZCIsJm4sJm0pOwogICAgbW1bMV09cGhpWzFdPUtbMV09MTsKICAgIGZvcihpPTI7aTxNQVg7KytpKQogICAgewogICAgICAgIGlmKCFtbVtpXSkKICAgICAgICB7CiAgICAgICAgICAgIG1tW2ldPWk7CiAgICAgICAgICAgIHBoaVtpXT1pLTE7CiAgICAgICAgICAgIEtbaV09aTsKICAgICAgICAgICAgcVsrK3RvcF09aTsKICAgICAgICB9CiAgICAgICAgZm9yKGludCBqPTE7ajw9dG9wICYmIHFbal0qaTxNQVg7KytqKQogICAgICAgIHsKICAgICAgICAgICAgaW50IHU9cVtqXSppOwogICAgICAgICAgICBtbVt1XT1xW2pdOwogICAgICAgICAgICBwaGlbdV09cGhpW2ldOwogICAgICAgICAgICBLW3VdPUtbaV07CiAgICAgICAgICAgIGlmKGklcVtqXT09MCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcGhpW3VdKj1xW2pdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcGhpW3VdKj0ocVtqXS0xKTsKICAgICAgICAgICAgS1t1XSo9cVtqXTsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaT0xO2k8PW47KytpKQogICAgICAgIGZvcihpbnQgaj1pO2o8PW47ais9aSkKICAgICAgICAgICAgeXVlc2h1W2pdLnBiKGkpOwoKICAgIGludCBub3c9MDsKICAgIGZvcihpPTE7aTxNQVg7KytpKQogICAgewogICAgICAgIHVwZGF0ZShub3cscGhpW2ldKTsKICAgICAgICBTWzFdW2ldPW5vdzsKICAgIH0KCiAgICBpbnQgYW5zPTA7CiAgICBSRVAoaSwxLG4pCiAgICAgICAgdXBkYXRlKGFucyxjYWxjKGksbSkpOwogICAgcHJpbnRmKCIlZFxuIixhbnMpOwogICAgcmV0dXJuIDA7Cn0K