#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
// #include<unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include "boost/algorithm/string.hpp"
#define fio ios_base::sync_with_stdio(false)
#define mod 1000000007
#define mod1 mod
#define mod2 100000009
#define li long long int
#define ll li
#define readi(x) scanf("%d",&x)
#define reads(x) scanf("%s", x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000000
#define MINN -1000000000000000000
#define pii pair<ll,ll>
#define pdd pair<double,double>
#define pic pair<int,char>
#define N 200010
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20
// #define INTMAX 200000000
// using namespace boost;
// #define si short int
using namespace std;
using namespace __gnu_pbds;
// typedef priority_queue<ll, vector<ll> > max_pq;
// typedef priority_queue<pii, vector<pii> , greater<pii > > min_pq;
ll toint(const string &s) {stringstream ss; ss << s; ll x; ss >> x; return x;}
string tostring ( ll number ){stringstream ss; ss<< number; return ss.str();}
// typedef priority_queue<pair < ll , pair < pii , ll > > , vector<pair < ll , pair < pii , ll > > > ,greater<pair < ll , pair < pii , ll > > > > min_pq;
// #define TRACE
// #ifdef TRACE
// #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
// template <typename Arg1>
// void __f(const char* name, Arg1&& arg1){
// cout << name << " : " << arg1 << std::endl;
// //use cerr if u want to display at the bottom
// }
// template <typename Arg1, typename... Args>
// void __f(const char* names, Arg1&& arg1, Args&&... args){
// const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
// }
// #else
// #define trace(...)
// #endif
typedef tree< ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update > OST;
typedef priority_queue< pii , vector<pii> > max_pq;
typedef priority_queue<pii, vector<pii> , greater <pii> > min_pq;
ll x,y;
map < ll, ll > dp;
ll modex ( ll a, ll b )
{
ll res = 1;
while ( b )
{
if ( b%2 )
{
res = (res*a)%mod;
}
a = (a*a)%mod;
b/=2;
}
return res;
}
ll solve(ll x )
{
if ( x == 1 )
return 1;
else if ( dp[x] )
return dp[x];
else
{
ll ret = modex(2,x-1);
for ( ll i = 2; i <= sqrt(x); i ++)
{
if ( x%i == 0 )
{
ret = (ret - (solve(i))+mod)%mod;
if ( x/i != i )
ret = (ret - (solve(x/i))+mod)%mod;
}
}
return dp[x]= (ret-1+mod)%mod;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
cin >> x >> y;
// return 0;
if ( y%x == 0 )
{
ll numb = (y/x);
if ( y == x )
{
cout <<"1";
return 0;
}
// ll ans = 0;
// ll temp = numb;
// ll tot = 1;
// for ( ll i = 2; i <= sqrt(numb); i ++)
// {
// if ( temp%i == 0 )
// {
// tot = (tot*(i-1))/i;
// while ( temp%i == 0 )
// {
// temp/=i;
// }
// }
// }
// if ( temp != 1)
// tot = (tot*(temp-1))/temp;
// ans = tot%mod;
cout << (solve(y/x))%mod;
}
else
{
cout <<"0";
}
}
I2luY2x1ZGU8aW9zdHJlYW0+CiNpbmNsdWRlPHN0ZGlvLmg+CiNpbmNsdWRlPGFsZ29yaXRobT4KI2luY2x1ZGU8bWF0aC5oPgojaW5jbHVkZTxiaXRzL3N0ZGMrKy5oPgojaW5jbHVkZTxzdGFjaz4KI2luY2x1ZGU8cXVldWU+CiNpbmNsdWRlPGxpc3Q+CiNpbmNsdWRlPHZlY3Rvcj4KI2luY2x1ZGU8Yml0c2V0PgovLyAjaW5jbHVkZTx1bm9yZGVyZWRfbWFwPiAKI2luY2x1ZGUgPGV4dC9wYl9kcy9hc3NvY19jb250YWluZXIuaHBwPgojaW5jbHVkZSA8ZXh0L3BiX2RzL3RyZWVfcG9saWN5LmhwcD4KLy8gI2luY2x1ZGUgImJvb3N0L2FsZ29yaXRobS9zdHJpbmcuaHBwIgojZGVmaW5lIGZpbyBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKQojZGVmaW5lIG1vZCAxMDAwMDAwMDA3CiNkZWZpbmUgbW9kMSBtb2QKI2RlZmluZSBtb2QyIDEwMDAwMDAwOQojZGVmaW5lIGxpIGxvbmcgbG9uZyBpbnQKI2RlZmluZSBsbCBsaQojZGVmaW5lIHJlYWRpKHgpIHNjYW5mKCIlZCIsJngpCiNkZWZpbmUgIHJlYWRzKHgpICBzY2FuZigiJXMiLCB4KQojZGVmaW5lIHJlYWRsKHgpIHNjYW5mKCIlSTY0ZCIsJngpCiNkZWZpbmUgcmVwKGksbikgZm9yKGk9MDtpPG47aSsrKQojZGVmaW5lIHJldnAoaSxuKSBmb3IoaT0obi0xKTtpPj0wO2ktLSkKI2RlZmluZSBteXJlcDEoaSxhLGIpIGZvcihpPWE7aTw9YjtpKyspCiNkZWZpbmUgbXlyZXAyKGksYSxiKSBmb3IoaT1iO2k+PWE7aS0tKQojZGVmaW5lIHBiIHB1c2hfYmFjawojZGVmaW5lIG1wIG1ha2VfcGFpcgojZGVmaW5lIGZpIGZpcnN0CiNkZWZpbmUgc2VjIHNlY29uZAojZGVmaW5lIE1BWE4gMTAwMDAwMDAwMDAwMDAwMDAwMAojZGVmaW5lIE1JTk4gLTEwMDAwMDAwMDAwMDAwMDAwMDAKI2RlZmluZSBwaWkgcGFpcjxsbCxsbD4gCiNkZWZpbmUgcGRkIHBhaXI8ZG91YmxlLGRvdWJsZT4KI2RlZmluZSBwaWMgcGFpcjxpbnQsY2hhcj4KI2RlZmluZSBOIDIwMDAxMAojZGVmaW5lIGxnbiAyMAojZGVmaW5lIGRkb3VibGUgbG9uZyBkb3VibGUKI2RlZmluZSBtaW51cyBtaW51CiNkZWZpbmUgUEkgMy4xNDE1OTI2NTM1CiNkZWZpbmUgbGduIDIwCiAKIAovLyAjZGVmaW5lIElOVE1BWCAyMDAwMDAwMDAKIAovLyB1c2luZyBuYW1lc3BhY2UgYm9vc3Q7Ci8vICNkZWZpbmUgc2kgc2hvcnQgaW50CiAKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbmFtZXNwYWNlIF9fZ251X3BiZHM7ICAgICAgICAgICAgIAovLyB0eXBlZGVmIHByaW9yaXR5X3F1ZXVlPGxsLCB2ZWN0b3I8bGw+ID4gbWF4X3BxOwovLyB0eXBlZGVmIHByaW9yaXR5X3F1ZXVlPHBpaSwgdmVjdG9yPHBpaT4gLCBncmVhdGVyPHBpaSA+ICA+IG1pbl9wcTsKbGwgdG9pbnQoY29uc3Qgc3RyaW5nICZzKSB7c3RyaW5nc3RyZWFtIHNzOyBzcyA8PCBzOyBsbCB4OyBzcyA+PiB4OyByZXR1cm4geDt9CnN0cmluZyB0b3N0cmluZyAoIGxsIG51bWJlciApe3N0cmluZ3N0cmVhbSBzczsgc3M8PCBudW1iZXI7IHJldHVybiBzcy5zdHIoKTt9CiAKLy8gdHlwZWRlZiBwcmlvcml0eV9xdWV1ZTxwYWlyIDwgbGwgLCBwYWlyIDwgcGlpICwgbGwgPiA+ICAsIHZlY3RvcjxwYWlyIDwgbGwgLCBwYWlyIDwgcGlpICwgbGwgPiA+ICA+ICxncmVhdGVyPHBhaXIgPCBsbCAsIHBhaXIgPCBwaWkgLCBsbCA+ID4gID4gPiBtaW5fcHE7Ci8vICNkZWZpbmUgVFJBQ0UKLy8gI2lmZGVmIFRSQUNFCi8vICNkZWZpbmUgdHJhY2UoLi4uKSBfX2YoI19fVkFfQVJHU19fLCBfX1ZBX0FSR1NfXykKLy8gICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBBcmcxPgovLyAgICAgdm9pZCBfX2YoY29uc3QgY2hhciogbmFtZSwgQXJnMSYmIGFyZzEpewovLyAgICAgICAgIGNvdXQgPDwgbmFtZSA8PCAiIDogIiA8PCBhcmcxIDw8IHN0ZDo6ZW5kbDsKLy8gICAgICAgICAvL3VzZSBjZXJyIGlmIHUgd2FudCB0byBkaXNwbGF5IGF0IHRoZSBib3R0b20KLy8gICAgIH0KLy8gICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZS4uLiBBcmdzPgovLyAgICAgdm9pZCBfX2YoY29uc3QgY2hhciogbmFtZXMsIEFyZzEmJiBhcmcxLCBBcmdzJiYuLi4gYXJncyl7Ci8vICAgICAgICAgY29uc3QgY2hhciogY29tbWEgPSBzdHJjaHIobmFtZXMgKyAxLCAnLCcpOyBjb3V0LndyaXRlKG5hbWVzLCBjb21tYSAtIG5hbWVzKSA8PCAiIDogIiA8PCBhcmcxPDwiIHwgIjtfX2YoY29tbWErMSwgYXJncy4uLik7Ci8vICAgICB9Ci8vICNlbHNlCi8vICNkZWZpbmUgdHJhY2UoLi4uKQovLyAjZW5kaWYKIAp0eXBlZGVmIHRyZWU8IGxsLCBudWxsX3R5cGUsIGxlc3M8bGw+LCByYl90cmVlX3RhZywgdHJlZV9vcmRlcl9zdGF0aXN0aWNzX25vZGVfdXBkYXRlID4gT1NUOwp0eXBlZGVmIHByaW9yaXR5X3F1ZXVlPCBwaWkgLCB2ZWN0b3I8cGlpPiA+IG1heF9wcTsKdHlwZWRlZiBwcmlvcml0eV9xdWV1ZTxwaWksIHZlY3RvcjxwaWk+ICwgZ3JlYXRlciA8cGlpPiAgPiBtaW5fcHE7CgoKbGwgeCx5OwptYXAgPCBsbCwgbGwgPiBkcDsKCmxsIG1vZGV4ICggbGwgYSwgbGwgYiApCnsKICAgIGxsIHJlcyA9IDE7CiAgICB3aGlsZSAoIGIgKQogICAgewogICAgICAgIGlmICggYiUyICkKICAgICAgICB7CiAgICAgICAgICAgIHJlcyA9IChyZXMqYSklbW9kOwogICAgICAgIH0KICAgICAgICBhID0gKGEqYSklbW9kOwogICAgICAgIGIvPTI7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgpsbCBzb2x2ZShsbCB4ICkKewogICAgaWYgKCB4ID09IDEgKQogICAgICAgIHJldHVybiAxOwogICAgZWxzZSBpZiAoIGRwW3hdICkKICAgICAgICByZXR1cm4gZHBbeF07CiAgICBlbHNlCiAgICB7CiAgICAgICAgbGwgcmV0ID0gbW9kZXgoMix4LTEpOwogICAgICAgIGZvciAoIGxsIGkgPSAyOyBpIDw9IHNxcnQoeCk7IGkgKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAoIHglaSA9PSAwICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0ID0gKHJldCAtIChzb2x2ZShpKSkrbW9kKSVtb2Q7CiAgICAgICAgICAgICAgICBpZiAoIHgvaSAhPSBpICkKICAgICAgICAgICAgICAgICAgICByZXQgPSAocmV0IC0gKHNvbHZlKHgvaSkpK21vZCklbW9kOyAgICAgICAKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZHBbeF09IChyZXQtMSttb2QpJW1vZDsKICAgIH0KCn0KCmludCBtYWluKCkKewogICAgaW9zOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOwogICAgY2luLnRpZShOVUxMKTsKICAgICNpZm5kZWYgT05MSU5FX0pVREdFCiAgICBmcmVvcGVuKCJpbnB1dC50eHQiLCJyIixzdGRpbik7CiAgICBmcmVvcGVuKCJvdXRwdXQudHh0IiwidyIsc3Rkb3V0KTsKICAgICNlbmRpZgogICAgY2luID4+IHggPj4geTsKICAgIC8vIHJldHVybiAwOwogICAgaWYgKCB5JXggPT0gMCApCiAgICB7CiAgICAgICAgbGwgbnVtYiA9ICh5L3gpOwogICAgICAgIGlmICggeSA9PSB4ICkKICAgICAgICB7CiAgICAgICAgICAgIGNvdXQgPDwiMSI7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICAvLyBsbCBhbnMgPSAwOwogICAgICAgIC8vIGxsIHRlbXAgPSBudW1iOwogICAgICAgIC8vIGxsIHRvdCA9IDE7CiAgICAgICAgLy8gZm9yICggbGwgaSA9IDI7IGkgPD0gc3FydChudW1iKTsgaSArKykKICAgICAgICAvLyB7CiAgICAgICAgLy8gICAgIGlmICggdGVtcCVpID09IDAgKQogICAgICAgIC8vICAgICB7CiAgICAgICAgLy8gICAgICAgICB0b3QgPSAodG90KihpLTEpKS9pOwogICAgICAgIC8vICAgICAgICAgd2hpbGUgKCB0ZW1wJWkgPT0gMCApCiAgICAgICAgLy8gICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICAgdGVtcC89aTsKICAgICAgICAvLyAgICAgICAgIH0KICAgICAgICAvLyAgICAgfQogICAgICAgIC8vIH0KICAgICAgICAvLyBpZiAoIHRlbXAgIT0gMSkKICAgICAgICAvLyAgICAgdG90ID0gKHRvdCoodGVtcC0xKSkvdGVtcDsKICAgICAgICAvLyBhbnMgPSB0b3QlbW9kOwogICAgICAgIGNvdXQgPDwgKHNvbHZlKHkveCkpJW1vZDsKCgoKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBjb3V0IDw8IjAiOwogICAgfQoKCgoKCgp9ICAgICAgICAgICAgICAgICAgICAgICAg