//题目大意:输入n,m,zhao找出1~n中与m互质的的数,将这些数当作a数组的下标,求和;
//思路:打表得出,a[i]=i*i+i;
质因数不超过10个,所以先找出m的质因数,然后找出1~n中与m不互质的的数,容斥一下,得出答案
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
long long inv6;
long long inv2;
ll n,m;
const ll mod=1e9+7;
vector<ll>x;//用来存储m的质因数;
ll Qpow(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b%2==1)ans=ans*a%mod;
a=a*a%mod;
b=b>>1;
}
return ans%mod;
}
void f1(ll m)
{
for(ll i=2;i*i<=m;i++)
{
if(m%i==0)
{
x.push_back(i);
while(m%i==0)
m=m/i;
}
}
if(m>1)x.push_back(m);
return ;
}
ll NN(ll n)//n^2求和公式,n*(1+n)*(2*n+1)/6;因为n*(n+1)*(2*n+1)模完之后,不一定能被6整除,所以乘以inv6;
{
inv6=Qpow(6,mod-2);
ll ans=n*(n+1)%mod;
ans=ans*(2*n+1)%mod*inv6%mod;
return ans%mod;
}
ll N(ll n)//n的求和公式n*(n+1)/2;
{
inv2=Qpow(2,mod-2);
ll ans=(1+n)*n%mod;
ans=ans*inv2%mod;
return ans%mod;
}
int main()
{
while(~scanf("%lld%lld",&n,&m))
{
ll sum=0,sum1=0;
sum=NN(n)+N(n);
x.clear();
f1(m);
ll len=x.size();
for(int i=1;i<(1<<len);i++)
{
ll temp=1;
int cn=0;
for(ll j=0;j<len;j++)
{
if(i&(1<<j))
{
temp*=x[j];
cn++;
}
}
ll num=n/temp;
ll sum2=NN(num)*temp%mod*temp%mod+N(num)*temp%mod;
if(cn%2==1)sum1=(sum1+sum2)%mod;
else sum1=(sum1-sum2+mod)%mod;
}
ll ans=(sum-sum1+mod)%mod;
printf("%lld\n",ans);
}
return 0;
}