#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";
    }






}                        