#include<bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#define maxn 1000005
#define itachi ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define fi first
#define se second
#define maxb ((1<<8)+5)
#define ll long long
#define sti string
#define int long long
using namespace std;
const int MAX=1e6;
int prime[maxn];
const int mod=1e9+7;
vector<int> primes;
int n,k,test;
void prepare(){
for(int i=2;i<=MAX;i++) prime[i]=1;
for(int i=2;i*i<=MAX;i++){
if(prime[i]){
for(int j=2*i;j<=MAX;j+=i) prime[j]=0;
}
}
for(int i=2;i<=MAX;i++) if(prime[i]) primes.push_back(i);
}
int power(int a,int b){
int res=1;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
signed main() {
itachi
freopen("stablecomplex.inp","r",stdin);
freopen("stablecomplex.out","w",stdout);
prepare();
cin>>test;
while(test--){
cin>>n>>k;
if(k==1){
cout<<(power(2,n)-1+mod)%mod<<'\n';
continue;
}
vector<int> divi;
for(int x : primes){
if(k%x==0){
int cur=1;
while(k%x==0){
cur*=x;
k/=x;
}
divi.push_back(cur);
}
}
if(k>1) divi.push_back(k);
bool zero=0;
for(int x : divi){
if( x > n) {
zero=1;
break;
}
}
if(zero){
cout<<0<<'\n';
continue;
}
vector<int> Lcm(((1<<divi.size())+5),0);
vector<int> cnt(((1<<divi.size())+5),0);
Lcm[0]=1;
cnt[0]=n;
for(int mask=1;mask<(1<<divi.size());mask++){
int j=__builtin_ctz(mask);
if(Lcm[mask^(1<<j)] > n / divi[j]) Lcm[mask]=n+1;
else Lcm[mask]=Lcm[mask^(1<<j)]*divi[j];
cnt[mask]=n/Lcm[mask];
}
for(int i=0;i<divi.size();i++){
for(int mask=0;mask<(1<<divi.size());mask++){
if((mask>>i)&1){
cnt[mask^(1<<i)] -= cnt[mask];
}
}
}
vector<int> num=cnt;
for(int i=0;i<divi.size();i++){
for(int mask=0;mask<(1<<divi.size());mask++){
if((mask>>i)&1){
num[mask] += num[mask^(1<<i)];
}
}
}
int res=0;
for(int mask=0;mask<(1<<divi.size());mask++){
int Count=power(2,num[mask]);
if((divi.size() - __builtin_popcountll(mask))%2==1){
res=(res-Count+mod)%mod;
}
else res=(res+Count)%mod;
}
cout<<res<<'\n';
}
return 0;
}
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KI3ByYWdtYSBHQ0Mgb3B0aW1pemUoIk8zLHVucm9sbC1sb29wcyIpCiNkZWZpbmUgbWF4biAxMDAwMDA1CiNkZWZpbmUgaXRhY2hpIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oMCk7Y2luLnRpZSgwKTtjb3V0LnRpZSgwKTsKI2RlZmluZSBmaSBmaXJzdAojZGVmaW5lIHNlIHNlY29uZAojZGVmaW5lIG1heGIgKCgxPDw4KSs1KQojZGVmaW5lIGxsIGxvbmcgbG9uZwojZGVmaW5lIHN0aSBzdHJpbmcKI2RlZmluZSBpbnQgbG9uZyBsb25nCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY29uc3QgaW50IE1BWD0xZTY7CmludCBwcmltZVttYXhuXTsKY29uc3QgaW50IG1vZD0xZTkrNzsKdmVjdG9yPGludD4gcHJpbWVzOwppbnQgbixrLHRlc3Q7Cgp2b2lkIHByZXBhcmUoKXsKICAgZm9yKGludCBpPTI7aTw9TUFYO2krKykgcHJpbWVbaV09MTsKICAgZm9yKGludCBpPTI7aSppPD1NQVg7aSsrKXsKICAgICAgaWYocHJpbWVbaV0pewogICAgICAgIGZvcihpbnQgaj0yKmk7ajw9TUFYO2orPWkpIHByaW1lW2pdPTA7CiAgICAgIH0KICAgfQogICBmb3IoaW50IGk9MjtpPD1NQVg7aSsrKSBpZihwcmltZVtpXSkgcHJpbWVzLnB1c2hfYmFjayhpKTsKfQoKaW50IHBvd2VyKGludCBhLGludCBiKXsKICBpbnQgcmVzPTE7CiAgd2hpbGUoYil7CiAgICAgaWYoYiYxKSByZXM9cmVzKmElbW9kOwogICAgIGE9YSphJW1vZDsKICAgICBiPj49MTsKICB9CiAgcmV0dXJuIHJlczsKfQoKc2lnbmVkIG1haW4oKSB7CiAgICBpdGFjaGkKICAgIGZyZW9wZW4oInN0YWJsZWNvbXBsZXguaW5wIiwiciIsc3RkaW4pOwogICAgZnJlb3Blbigic3RhYmxlY29tcGxleC5vdXQiLCJ3IixzdGRvdXQpOwogICAgcHJlcGFyZSgpOwogICAgY2luPj50ZXN0OwogICAgd2hpbGUodGVzdC0tKXsKICAgICAgICBjaW4+Pm4+Pms7CiAgICAgICAgaWYoaz09MSl7CiAgICAgICAgICAgIGNvdXQ8PChwb3dlcigyLG4pLTErbW9kKSVtb2Q8PCdcbic7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICB2ZWN0b3I8aW50PiBkaXZpOwogICAgICAgIGZvcihpbnQgeCA6IHByaW1lcyl7CiAgICAgICAgICAgIGlmKGsleD09MCl7CiAgICAgICAgICAgICAgICBpbnQgY3VyPTE7CiAgICAgICAgICAgICAgICB3aGlsZShrJXg9PTApewogICAgICAgICAgICAgICAgICAgIGN1cio9eDsKICAgICAgICAgICAgICAgICAgICBrLz14OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGl2aS5wdXNoX2JhY2soY3VyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihrPjEpIGRpdmkucHVzaF9iYWNrKGspOwogICAgICAgIGJvb2wgemVybz0wOwogICAgICAgIGZvcihpbnQgeCA6IGRpdmkpewogICAgICAgICAgICBpZiggeCA+IG4pIHsKICAgICAgICAgICAgICAgIHplcm89MTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmKHplcm8pewogICAgICAgICAgICBjb3V0PDwwPDwnXG4nOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgdmVjdG9yPGludD4gTGNtKCgoMTw8ZGl2aS5zaXplKCkpKzUpLDApOwogICAgICAgIHZlY3RvcjxpbnQ+IGNudCgoKDE8PGRpdmkuc2l6ZSgpKSs1KSwwKTsKICAgICAgICBMY21bMF09MTsKICAgICAgICBjbnRbMF09bjsKICAgICAgICBmb3IoaW50IG1hc2s9MTttYXNrPCgxPDxkaXZpLnNpemUoKSk7bWFzaysrKXsKICAgICAgICAgICAgaW50IGo9X19idWlsdGluX2N0eihtYXNrKTsKICAgICAgICAgICAgaWYoTGNtW21hc2teKDE8PGopXSA+IG4gLyBkaXZpW2pdKSBMY21bbWFza109bisxOwogICAgICAgICAgICBlbHNlIExjbVttYXNrXT1MY21bbWFza14oMTw8aildKmRpdmlbal07CiAgICAgICAgICAgIGNudFttYXNrXT1uL0xjbVttYXNrXTsKICAgICAgICB9CgogICAgICAgIGZvcihpbnQgaT0wO2k8ZGl2aS5zaXplKCk7aSsrKXsKICAgICAgICAgICAgZm9yKGludCBtYXNrPTA7bWFzazwoMTw8ZGl2aS5zaXplKCkpO21hc2srKyl7CiAgICAgICAgICAgICAgICBpZigobWFzaz4+aSkmMSl7CiAgICAgICAgICAgICAgICAgICAgY250W21hc2teKDE8PGkpXSAtPSBjbnRbbWFza107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHZlY3RvcjxpbnQ+IG51bT1jbnQ7CiAgICAgICAgZm9yKGludCBpPTA7aTxkaXZpLnNpemUoKTtpKyspewogICAgICAgICAgICBmb3IoaW50IG1hc2s9MDttYXNrPCgxPDxkaXZpLnNpemUoKSk7bWFzaysrKXsKICAgICAgICAgICAgICAgIGlmKChtYXNrPj5pKSYxKXsKICAgICAgICAgICAgICAgICAgICBudW1bbWFza10gKz0gbnVtW21hc2teKDE8PGkpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50IHJlcz0wOwogICAgICAgIGZvcihpbnQgbWFzaz0wO21hc2s8KDE8PGRpdmkuc2l6ZSgpKTttYXNrKyspewogICAgICAgICAgICBpbnQgQ291bnQ9cG93ZXIoMixudW1bbWFza10pOwogICAgICAgICAgICBpZigoZGl2aS5zaXplKCkgLSBfX2J1aWx0aW5fcG9wY291bnRsbChtYXNrKSklMj09MSl7CiAgICAgICAgICAgICAgICByZXM9KHJlcy1Db3VudCttb2QpJW1vZDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHJlcz0ocmVzK0NvdW50KSVtb2Q7CiAgICAgICAgfQogICAgICAgIGNvdXQ8PHJlczw8J1xuJzsKICAgIH0KICAgIHJldHVybiAwOwp9Cg==