Count the number of distinct sequences a1, a2, ..., an (1 ≤ ai) consisting of positive integers such that gcd(a1, a2, ..., an) = x and . As this number could be large, print the answer modulo 109 + 7.gcd here means the greatest common divisor.

The only line contains two positive integers x and y (1 ≤ x, y ≤ 109).

Print the number of such sequences modulo 109 + 7.

NoteThere are three suitable sequences in the first test: (3, 3, 3), (3, 6), (6, 3).There are no suitable sequences in the second test.

import java.io.*;
import java.math.*;
import java.security.KeyStore.Entry;
import java.util.*;

public class SPOJANDCC
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static int mod = (int) 1e9 + 7;

	static int pow(long x, long y)
	{
		long ans = 1;
		while (y > 0)
		{
			if ((y & 1) == 1)
				ans = (ans * x) % mod;
			x = (x * x) % mod;
			y >>= 1;
		}
		return (int) ans;
	}

	static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

	static int cnt(int n)
	{
		if (map.containsKey(n))
			return map.get(n);
		int ans = pow(2, n - 1) - 1;
		if (ans < 0)
			ans += mod;
		for (int i = 2; i * i <= n; i++)
		{
			if (n % i == 0)
			{
				ans = ans - cnt(n / i);
				if (ans < 0)
					ans += mod;
				if (i * i != n)
				{
					ans = ans - cnt(i);
					if (ans < 0)
						ans += mod;
				}
			}
		}
		map.put(n, ans);
		return ans;
	}

	static void solve()
	{
		map.put(1, 1);
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
			out.println("0");
		else
			out.println(cnt(y / x));
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.util.*;

public class CODEFORCES
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static long mod = (long) 1e9 + 7;

	static long pow(long a, long b)
	{
		long ans = 1;
		while (b > 0)
		{
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	static ArrayList<Integer> primes = new ArrayList<Integer>();

	static int mobius(int p)
	{
		if (p == 1)
			return 1;
		int c = 0;
		for (int i : primes)
		{
			if (p % i == 0)
				c++;
			if (p % (i * i) == 0)
				return 0;
		}
		return ((c & 1) == 1) ? -1 : 1;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
		{
			out.println("0");
			return;
		}
		y /= x;
		int m = y;
		for (int i = 2; i * i <= y; i++)
		{
			if (y % i == 0)
				primes.add(i);
			while (y % i == 0)
				y /= i;
		}
		if (y != 1)
			primes.add(y);
		long ans = 0;
		for (int i = 1; i * i <= m; i++)
		{
			if (m % i != 0)
				continue;
			int c = mobius(i);
			ans += pow(2, m / i - 1) * c;
			if (i * i != m)
			{
				c = mobius(m / i);
				ans += pow(2, i - 1) * c;
			}
			while (ans < 0)
				ans += mod;
			while (ans >= mod)
				ans -= mod;
		}
		ans %= mod;
		out.println(ans);
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	// To Get Input
	// Some Buffer Methods
	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

//
// UnusualSeq.java
// Created by Alister Estrada Cueto on 9/25/18.

import java.util.*;
public class UnusualSeq{

	public static void main(String [] args){
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt();
		int y = sc.nextInt();
		int MOD = (int) 1e9 + 7;
		if (y%x == 0) {
			y /= x;

			List<Integer> n = new ArrayList<>();
			for (int i = 1; 1l * i * i <= y ;i++ ) {
				if (y%i == 0) {
					n.add(i);
					if (y/i!=i) {
						n.add(y/i);
					}

				}
			}
			long[] m = new long[n.size()];
			Collections.sort(n);
			for (int i = 0;i<n.size() ;i++ ) {
				int k = n.get(i);
				m[i] = calc(2,k-1,MOD);
				for (int j = 0;j < i ;j++ ) {
					if (k%n.get(j) == 0) {
						m[i]-=m[j];
						if (m[i]<0) {
							m[i] += MOD;
						}
					}
				}

			}
			System.out.println(m[n.size()-1]);
		}else{
			System.out.println("0");
		}
	}
	public static long calc(int base, int exponent, int p) {
		if (exponent == 0) return 1;
		if (exponent == 1) return base % p;
		long m = calc(base, exponent >> 1, p);
		if (exponent % 2 == 0) return (m * m) % p;
		return 1l * base * m  % p * m % p;
	}
}

import java.io.*;
import java.util.*;
public class Main {
    static int mod=(int)(1e9+7);
    static HashMap<Integer,Long>map;
    public static void main(String[] args) {
        FastScanner sc=new FastScanner();
        PrintWriter pw=new PrintWriter(System.out);
        while(sc.hasNext()){
            int x=sc.nextInt();
            int y=sc.nextInt();
            map=new HashMap<>();
            map.put(1,1L);
            map.put(2,1L);
            if(y%x!=0)pw.println(0);
            else{
                pw.println(dfs(y/x));
            }
            pw.flush();
        }
    }
    static long quickmod(long a,int n){
        long res=1;
        while(n>0){
            if(n%2!=0)res=(res*a)%mod;
            a=(a*a)%mod;
            n/=2;
        }
        return res;
    }
    static long dfs(int n){
        if(map.containsKey(n))return map.get(n);
        long sum=0;
        for(int i=2;i<=Math.sqrt(n);i++){
            if(n%i==0) {
                sum = (sum - dfs(n / i)) % mod;
                if(i*i!=n)
                    sum = (sum - dfs(i)) % mod;
            }
        }
        if(n!=1)sum = (sum - 1) % mod;
        sum=(sum%mod+quickmod(2,n-1)+mod)%mod;
        map.put(n,sum);
        return sum;
    }
}
class FastScanner{
    BufferedReader br;
    StringTokenizer st;
    FastScanner(){
        br=new BufferedReader(new InputStreamReader(System.in));
        st=new StringTokenizer("");
    }

    String nextLine(){
        String s="";
        try {
            s=br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return s;
    }
    boolean hasNext(){
        String s = "";
        while(!st.hasMoreTokens()){
            s=nextLine();
            if(s==null)return false;
            st=new StringTokenizer(s);
        }
        return true;
    }
    String next(){
        String s="";
        while(!st.hasMoreTokens()){
            s=nextLine();
            st=new StringTokenizer(s);
        }
        return st.nextToken();
    }
    int nextInt(){
        return Integer.valueOf(next());
    }
    long nextLong(){
        return Long.valueOf(next());
    }
    double nextDouble(){
        return Double.valueOf(next());
    }
}

import java.io.*;
import java.util.*;
public class C {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
        static class TaskE {
         long mod=(long)(1E9)+7;
         long rpe(long a,long b){
          long ans=1;
          while(b!=0){
           if(b%2!=0)ans=(ans*a)%mod;
           a=(a*a)%mod;b/=2;
          }return ans;
         }
         class pair{
          long n,v;pair(long a,long b){n=a;v=b;}
         }
         public void solve(int testNumber, InputReader in, PrintWriter out) {
          long x=in.nextLong(),y=in.nextLong();
          if(y%x==0)y/=x;else{out.print(0);return;}
          ArrayList<pair> al=new ArrayList<>();
          for(long i=1;i*i<=y;i++){
           if(y%i==0){
            al.add(new pair(i,0));if(y/i!=i)al.add(new pair(y/i,0));
           }
          }
          Collections.sort(al,new Comparator<pair>(){
           public int compare(pair p1,pair p2){return (int)(p1.n-p2.n);}
          });
          for(int i=0;i<al.size();i++){
           al.get(i).v=(al.get(i).v+rpe(2,al.get(i).n-1))%mod;
           for(int j=i+1;j<al.size();j++){
            if(al.get(j).n%al.get(i).n==0)
            al.get(j).v=(al.get(j).v-al.get(i).v+mod)%mod;
           }
          }
          out.print(al.get(al.size()-1).v);
         }
    }
    static class InputReader {
        BufferedReader br;
        StringTokenizer st;
        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
            st = null;
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
        public double nextDouble() {
            return Double.parseDouble(next());
        }
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.Writer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Asgar Javadov
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        FastWriter out = new FastWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        Map<Integer, Integer> memo = new HashMap<>();

        public void solve(int testNumber, InputReader in, FastWriter out) {
            int x = in.nextInt();
            int y = in.nextInt();

            if (y % x != 0) {
                out.println(0);
                return;
            }

            int sum = y / x;
            memo.put(1, 1);
            out.println(f(sum));
        }

        private int f(int n) {
            Integer res = memo.get(n);
            if (res != null)
                return res;

            res = NumberTheory.pow(2, n - 1) - 1;
            for (int i = 2; i * i <= n; ++i) {
                if (n % i == 0) {
                    res = NumberTheory.subtract(res, f(i));
                    int other = n / i;
                    if (other != i)
                        res = NumberTheory.subtract(res, f(other));
                }
            }
            memo.put(n, res);
            return res;
        }

    }

    static class InputReader extends BufferedReader {
        StringTokenizer tokenizer;

        public InputReader(InputStream inputStream) {
            super(new InputStreamReader(inputStream), 32768);
        }

        public InputReader(String filename) {
            super(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(filename)));
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(readLine());
                } catch (IOException e) {
                    throw new RuntimeException();
                }
            }
            return tokenizer.nextToken();
        }

        public Integer nextInt() {
            return Integer.valueOf(next());
        }

    }

    static class NumberTheory {
        public static final int MODULO = 1_000_000_007;

        public static int subtract(int a, int b) {
            if (a >= b)
                return a - b;
            else
                return a - b + MODULO;
        }

        public static int pow(int a, long n) {
            return pow(a, n, MODULO);
        }

        public static int pow(int a, long n, int mod) {
            long res = 1L;
            long half = a;
            while (n != 0) {
                if ((n & 1) == 1)
                    res = res * half % mod;
                half = half * half % mod;
                n >>= 1;
            }
            return (int) res;
        }

    }

    static class FastWriter extends PrintWriter {
        public FastWriter(OutputStream outputStream) {
            super(outputStream);
        }

        public FastWriter(Writer writer) {
            super(writer);
        }

        public FastWriter(String filename) throws FileNotFoundException {
            super(filename);
        }

    }
}

import java.util.*;
import java.io.*;

public class ProblemG
{

    static int mod = (int) (1e9+7);
    static InputReader in;
    static PrintWriter out;

    static int brute(int n, int sum, int gcd){
        if(sum > n) return 0;
        if(sum == n) return (gcd == 1) ? 1 : 0;
        int ans = 0;

        for(int i = 1; i <= n; i++)
            ans += brute(n, sum + i, gcd(gcd,i));

        return ans;
    }

    static void solve()
    {
        in = new InputReader(System.in);
        out = new PrintWriter(System.out);

        //debug(brute(8, 0, 0));
        int x = in.nextInt();
        int y = in.nextInt();
        ArrayList<Integer> prime = new ArrayList<>();
        int maxn = 100000;
        boolean[] p = new boolean[maxn];
        for(int i = 2; i < maxn; i++){
            if(p[i]) continue;
            prime.add(i);
            for(int j = i + i; j < maxn; j += i)
                p[j] = true;
        }

        if(y % x == 0){
            y = y / x;
            ArrayList<Integer> list = new ArrayList<>();
            for(int i = 1; i <= Math.sqrt(y); i++){
                if(y % i == 0){
                    list.add(i);
                    if(i * i != y) list.add(y / i);
                }
            }
            int mm = y;
            for(int pp : prime){
                while(mm % pp == 0){
                    mm /= pp;
                }
            }
            if(mm > 1) prime.add(mm);
            long ans = 0;
            HashMap<Integer,Integer> map = new HashMap<>();
            for(int m: list){
                int k = m;
                if(k == 1){
                    map.put(1, 1);
                    continue;
                }
                int c = 0;
                int xx = -1;
                for(int pp : prime){
                    if(k % pp != 0) continue;
                    int c1 = 0;
                    while(k % pp == 0){
                        k /= pp;
                        c1++;
                    }
                    if(c1 > 1){
                        map.put(m, 0);
                        xx = 0;
                        break;
                    }
                    c++;
                }
                if(xx == 0) continue;
                map.put(m, (c % 2 == 0) ? 1 : -1);
            }
            //debug(map);
            for(int k : list){
                long tmp = pow(2, k - 1, mod);
                //debug(y/k,k,map.get(y/k),tmp);
                tmp = map.get(y / k) * tmp;
                ans = (ans + tmp + mod) % mod;
            }
            out.println(ans);
        }
        else out.println(0);

        out.close();
    }

    public static void main(String[] args)
    {
        new Thread(null ,new Runnable(){
            public void run(){
                try{
                    solve();
                } catch(Exception e){
                    e.printStackTrace();
                }
            }
        },"1",1<<26).start();

    }

    static class Pair implements Comparable<Pair>
    {

        int x;
        long y;
        int i;

        Pair (int x,long y)
        {
                this.x = x;
                this.y = y;
        }

        Pair (int x,int y, int i)
        {
                this.x = x;
                this.y = y;
                this.i = i;
        }

        public int compareTo(Pair o)
        {
            return Long.compare(this.y,o.y);
                //return 0;
        }

        public boolean equals(Object o)
        {
            if (o instanceof Pair)
            {
                Pair p = (Pair)o;
                return p.x == x && p.y==y;
            }
            return false;
        }

        @Override
        public String toString()
        {
            return x + " "+ y + " "+i;
        }

        /*public int hashCode()
        {
            return new Long(x).hashCode() * 31 + new Long(y).hashCode();
        }*/

    }

    static long add(long a,long b){
        long x=(a+b);
        while(x>=mod) x-=mod;
        return x;
    }

    static long sub(long a,long b){
        long x=(a-b);
        while(x<0) x+=mod;
        return x;
    }

    static long mul(long a,long b){
        long x=(a*b);
        while(x>=mod) x-=mod;
        return x;
    }

    static String rev(String s){
        StringBuilder sb=new StringBuilder(s);
        sb.reverse();
        return sb.toString();
    }

    static long gcd(long x,long y)
    {
        if(y==0)
                return x;
        else
                return gcd(y,x%y);
    }

    static int gcd(int x,int y)
    {
        if(y==0)
                return x;
        else
                return gcd(y,x%y);
    }

    static long pow(long n,long p,long m)
    {
         long  result = 1;
          if(p==0){
            return 1;
          }

        while(p!=0)
        {
            if(p%2==1)
                result *= n;
            if(result >= m)
               result %= m;
            p >>=1;
            n*=n;
            if(n >= m)
                n%=m;
        }

        return result;
    }

    static long pow(long n,long p)
    {
        long  result = 1;
          if(p==0)
            return 1;

        while(p!=0)
        {
            if(p%2==1)
                result *= n;
            p >>=1;
            n*=n;
        }
        return result;
    }

    static void debug(Object... o)
    {
            System.out.println(Arrays.deepToString(o));
    }

    static class InputReader
    {

        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
                this.stream = stream;
        }

        public int snext()
        {
                if (snumChars == -1)
                        throw new InputMismatchException();
                if (curChar >= snumChars)
                {
                        curChar = 0;
                        try
                        {
                                snumChars = stream.read(buf);
                        } catch (IOException e)
                        {
                                throw new InputMismatchException();
                        }
                        if (snumChars <= 0)
                                return -1;
                }
                return buf[curChar++];
        }

        public int nextInt()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                int sgn = 1;
                if (c == '-')
                {
                        sgn = -1;
                        c = snext();
                }
                int res = 0;
                do
                {
                        if (c < '0' || c > '9')
                                throw new InputMismatchException();
                        res *= 10;
                        res += c - '0';
                        c = snext();
                } while (!isSpaceChar(c));
                return res * sgn;
        }

        public long nextLong()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                int sgn = 1;
                if (c == '-')
                {
                        sgn = -1;
                        c = snext();
                }
                long res = 0;
                do
                {
                        if (c < '0' || c > '9')
                                throw new InputMismatchException();
                        res *= 10;
                        res += c - '0';
                        c = snext();
                } while (!isSpaceChar(c));
                return res * sgn;
        }

        public int[] nextIntArray(int n)
        {
                int a[] = new int[n];
                for (int i = 0; i < n; i++)
                {
                        a[i] = nextInt();
                }
                return a;
        }

        public long[] nextLongArray(int n)
        {
                long a[] = new long[n];
                for (int i = 0; i < n; i++)
                {
                        a[i] = nextLong();
                }
                return a;
        }

        public String readString()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                StringBuilder res = new StringBuilder();
                do
                {
                        res.appendCodePoint(c);
                        c = snext();
                } while (!isSpaceChar(c));
                return res.toString();
        }

        public String nextLine()
        {
                int c = snext();
                while (isSpaceChar(c))
                        c = snext();
                StringBuilder res = new StringBuilder();
                do
                {
                        res.appendCodePoint(c);
                        c = snext();
                } while (!isEndOfLine(c));
                return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
                if (filter != null)
                        return filter.isSpaceChar(c);
                return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
                return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter
        {
                public boolean isSpaceChar(int ch);
        }

    }
}

// Let f(x) = # of sequences a_i such that gcd() = 1, sum(a_i)=x. We want f(y - x). This is a hard AF function to calculate: easiest recurrence would be sum(f_i) where i<t, gcd(t,i)=1,
// but that's not fast enough at all.

// Trick from editorial: Relate a function to an easier function with a relationship IN EITHER DIRECTION. Here, let g(t) = # of sequences w/o gcd()=1 condition.
// Then, we realize that a_i can onyl have so many gcd's, so g(t)=sum_(d|t) f(t/d), f(t)=g(t)-sum_(d|t, d not t) f(t).

// Notice the repeats in f(t). That means we can DP it. Let's code!

import java.util.*;
public class Unusual {
	private static final int N = 1000000007;
	public static long pow(int n) {
		if (n == 0) return 1;
		long x = pow(n / 2);
		x = (x * x) % N;
		if (n % 2 == 1) x = (x * 2) % N;
		return x;
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int x = in.nextInt(), y = in.nextInt(), t = y / x, i;
		if (y % x != 0) {
			System.out.println(0);
			System.exit(0);
		}
		ArrayList<Integer> divisors = new ArrayList<Integer>();
		for (i = 1; i * i < t; i++) {
			if (t % i == 0) {
				divisors.add(i); divisors.add(t / i);
			}
		}
		if (i * i == t) divisors.add(i);
		int[] d = new int[divisors.size()];
		for (i = 0; i < d.length; i++) {
			d[i] = divisors.get(i);
		}
		Arrays.sort(d);
		long[] f = new long[divisors.size()];
		f[0] = 1;
		for (i = 1; i < d.length; i++) {
			f[i] = pow(d[i] - 1);
			for (int j = 0; j < i; j++) {
				if (d[i] % d[j] == 0) f[i] = (f[i] - f[j] + N) % N;
			}
		}
//		System.out.println(Arrays.toString(d));
//		System.out.println(Arrays.toString(f));
		System.out.println(f[d.length - 1]);
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * @author Don Li
 */
public class UnusualSequences2 {

    int N = (int) 1e5;
    int MOD = (int) 1e9 + 7;

    void solve() {
        int x = in.nextInt(), y = in.nextInt();

        if (y % x != 0) {
            out.println(0);
            return;
        }

        y /= x;
        int[] primes = sieve(N);

        long ans = 0;
        for (int d = 1; d * d <= y; d++) {
            if (y % d == 0) {
                ans = (ans + mobius(d, primes) * mpow(2, y / d - 1) + MOD) % MOD;
                if (d != y / d) ans = (ans + mobius(y / d, primes) * mpow(2, d - 1) + MOD) % MOD;
            }
        }
        out.println(ans);
    }

    long mpow(long a, long n) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) > 0) res = res * a % MOD;
            a = a * a % MOD;
            n >>= 1;
        }
        return res;
    }

    int mobius(long n, int[] primes) {
        int mob = 1;
        for (int p : primes) {
            if ((long) p * p > n) break;
            if (n % ((long) p * p) == 0) return 0;
            if (n % p == 0) {
                n /= p;
                mob = -mob;
            }
        }
        if (n > 1) mob = -mob;
        return mob;
    }

    int[] sieve(int n) {
        boolean[] isp = new boolean[n];
        Arrays.fill(isp, true);
        isp[0] = isp[1] = false;
        int sqrt = (int) (Math.sqrt(n) + 0.5);
        for (int i = 2; i <= sqrt; i++) {
            if (isp[i]) {
                for (int j = i * i; j < n; j += i) isp[j] = false;
            }
        }
        int sz = 0;
        for (int i = 0; i < n; i++) if (isp[i]) sz++;
        int[] ret = new int[sz];
        for (int i = 0, j = 0; i < n; i++) if (isp[i]) ret[j++] = i;
        return ret;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new UnusualSequences2().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        public long nextLong() {
            return Long.parseLong(nextToken());
        }

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * @author Don Li
 */
public class UnusualSequences {

    int MOD = (int) 1e9 + 7;

    Map<Integer, Integer> memo = new HashMap<>();

    void solve() {
        int x = in.nextInt(), y = in.nextInt();

        if (y % x != 0) {
            out.println(0);
            return;
        }

        out.println(calc(y / x));
    }

    long calc(int t) {
        if (memo.containsKey(t)) return memo.get(t);
        long tot = mpow(2, t - 1);
        int sqrt = (int) (Math.sqrt(t) + 0.5);
        for (int i = 1; i <= sqrt; i++) {
            if (t % i == 0) {
                if (i != 1) tot = (tot - calc(t / i) + MOD) % MOD;
                if (i != t / i) tot = (tot - calc(t / (t / i)) + MOD) % MOD;
            }
        }
        memo.put(t, (int) tot);
        return tot;
    }

    long mpow(long a, long n) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) > 0) res = res * a % MOD;
            a = a * a % MOD;
            n >>= 1;
        }
        return res;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new UnusualSequences().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        public long nextLong() {
            return Long.parseLong(nextToken());
        }

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}

import java.util.*;
public class sequ{

	public static void main(String [] args){
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt();
		int y = sc.nextInt();
		int MOD = (int) 1e9 + 7;
		if (y%x == 0) {
			y /= x;

			List<Integer> n = new ArrayList<>();
			for (int i = 1; 1l * i * i <= y ;i++ ) {
				if (y%i == 0) {
					n.add(i);
					if (y/i!=i) {
						n.add(y/i);
					}

				}
			}
			long[] m = new long[n.size()];
			Collections.sort(n);
			//System.out.println(n);
			for (int i = 0;i<n.size() ;i++ ) {
				int k = n.get(i);
				m[i] = calc(2,k-1,MOD);
				for (int j = 0;j < i ;j++ ) {
					if (k%n.get(j) == 0) {
						m[i]-=m[j];
						if (m[i]<0) {
							m[i] += MOD;
						}
					}
				}

			}
			System.out.println(m[n.size()-1]);
		}else{
			System.out.println("0");
		}
	}
	public static long calc(int base, int exponent, int p) {
		if (exponent == 0) return 1;
		if (exponent == 1) return base % p;
		long m = calc(base, exponent >> 1, p);
		if (exponent % 2 == 0) return (m * m) % p;
		return 1l * base * m  % p * m % p;
	}
}

import java.util.*;
public class sequences{

	public static void main(String [] args){
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt();
		int y = sc.nextInt();
		int MOD = (int) 1e9 + 7;
		if (y%x == 0) {
			y /= x;

			List<Integer> n = new ArrayList<>();
			for (int i = 1; 1l * i * i <= y ;i++ ) {
				if (y%i == 0) {
					n.add(i);
					if (y/i!=i) {
						n.add(y/i);
					}

				}
			}
			long[] m = new long[n.size()];
			Collections.sort(n);
			//System.out.println(n);
			for (int i = 0;i<n.size() ;i++ ) {
				int k = n.get(i);
				m[i] = calc(2,k-1,MOD);
				for (int j = 0;j < i ;j++ ) {
					if (k%n.get(j) == 0) {
						m[i]-=m[j];
						if (m[i]<0) {
							m[i] += MOD;
						}
					}
				}

			}
			System.out.println(m[n.size()-1]);
		}else{
			System.out.println("0");
		}
	}
	public static long calc(int base, int exponent, int p) {
		if (exponent == 0) return 1;
		if (exponent == 1) return base % p;
		long m = calc(base, exponent >> 1, p);
		if (exponent % 2 == 0) return (m * m) % p;
		return 1l * base * m  % p * m % p;
	}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;

import com.sun.javafx.collections.MappingChange.Map;

public class E {

	static StringTokenizer st;
	static BufferedReader br;
	static PrintWriter pw;
	static int mod = (int) (1e9+7);
	static HashMap<Integer, Integer> map;
	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int x = nextInt();
		int y = nextInt();
		if (y % x != 0) {
			System.out.println(0);
			return;
		}
		int n = y / x;
		if (n==1) {
			System.out.println(1);
			return;
		}
		map = new HashMap<Integer, Integer>();
		long ans = calc(n);

		System.out.println(ans);
		pw.close();
	}
	private static int calc(int n) {
		if (map.containsKey(n))
			return map.get(n);
		int res = (int) (binPow(2, n-1)-1);
		if (res < 0)
			res += mod;
		for (int i = 2; i*i <= n; i++) {
			if (n % i==0) {
				res -= calc(i);
				if (res < 0)
					res += mod;
				if (i*i != n) {
					res -= calc(n / i);
					if (res < 0)
						res += mod;
				}
			}
		}
		map.put(n, res);
		return res;
	}
	private static long binPow(long a, int n) {
		long b = 1;
		while (n > 0) {
			if (n % 2==1)
				b = b * a % mod;
			n /= 2;
			a = a * a % mod;
		}
		return b;
	}
	private static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}
	private static long nextLong() throws IOException {
		return Long.parseLong(next());
	}
	private static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	private static String next() throws IOException {
		while (st==null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}
}

import java.io.*;
import java.util.*;

public class Solution {

    static MyScanner sc;
    private static PrintWriter out;
    static long M2 = 1_000_000_000L + 7;

    private static HashMap<Long, Long>[] mods;

    public static void main(String[] s) throws Exception {
        StringBuilder stringBuilder = new StringBuilder();
        if (stringBuilder.length() == 0) {
            sc = new MyScanner(System.in);
        } else {
            sc = new MyScanner(new BufferedReader(new StringReader(stringBuilder.toString())));
        }

        out = new PrintWriter(new OutputStreamWriter(System.out));

        initData();
        solve();
        out.flush();
    }

    private static void initData() {

    }

    private static void solve() throws IOException {
        int k = sc.nextInt();
        int r = sc.nextInt();
        if (r % k != 0) {
            out.println(0);
            return;
        }
        r /= k;

        int t = r;
        int d = 2;
        ArrayList<Integer> div = new ArrayList<>();
        while (d * d <= t) {
            if (t % d != 0) {
                d++;
                continue;
            }
            div.add(d);
            t /= d;
        }
        if (t != 1) {
            div.add(t);
        }

        long res = 0;
        for (int mt = 1; (long) mt * mt <= r; mt++) {
            if (r % mt != 0) continue;
            int l1 = mt;
            int l2 = r / mt;
            res = add(res, l2, l1, div);
            if (l1 != l2) {
                res = add(res, l1, l2, div);
            }
        }
        out.println(res);
    }

    private static long add(long res, int l1, int l2, ArrayList<Integer> div) {
        int a = 1;
        int sum = l2;
        for (int i : div) {
            if (sum % (1L * i * i) == 0) {
                return res;
            }
            if ((sum % i) == 0) {
                a = -a;
                sum /= i;
            }
        }

        long x = pow(2, l1 - 1, M2);

        res += a * x;
        if (res < 0) {
            res += M2;
        }
        return res % M2;
    }

    private static boolean solve(int n, int p, int p1, int i) {
        return false;
    }

    private static boolean isset(long i, int k) {
        return (i & (1 << k)) > 0;
    }

    private static void solveT() throws IOException {
        int t = sc.nextInt();
        while (t-- > 0) {
            solve();
        }
    }

    private static long gcd(long l, long l1) {
        if (l > l1) return gcd(l1, l);
        if (l == 0) return l1;
        return gcd(l1 % l, l);
    }

    private static long pow(long a, long b, long m) {
        if (b == 0) return 1;
        if (b == 1) return a;
        long pp = pow(a, b / 2, m);
        pp *= pp;
        pp %= m;
        return (pp * (b % 2 == 0 ? 1 : a)) % m;
    }

    static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        MyScanner(BufferedReader br) {
            this.br = br;
        }

        public MyScanner(InputStream in) {
            this(new BufferedReader(new InputStreamReader(in)));
        }

        void findToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        String next() {
            findToken();
            return st.nextToken();
        }

        Integer[] nab(int n) {
            Integer[] k = new Integer[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.fi();
            }
            return k;
        }

        int[] na(int n) {
            int[] k = new int[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.fi();
            }
            return k;
        }

        long[] nl(int n) {
            long[] k = new long[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.nextLong();
            }
            return k;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        int fi() {
            String t = next();
            int cur = 0;
            boolean n = t.charAt(0) == '-';
            for (int a = n ? 1 : 0; a < t.length(); a++) {
                cur = cur * 10 + t.charAt(a) - '0';
            }
            return n ? -cur : cur;
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }
    }

}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Vadim
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        r450D solver = new r450D();
        solver.solve(1, in, out);
        out.close();
    }

    static class r450D {
        long mod = (int) 1e9 + 7;
        Long[] memo;
        int MAX = 1_000_000;

        private long subsolve(int x, int y) {
            if (y % x != 0)
                return 0;
            y = y / x;
            x = 1;
            if (y < MAX && memo[y] != null)
                return memo[y];
            long total = IntegerUtils.pow(2, y - 1, mod); // all compositions
            long discard = 0; // discard all where x != 1;
            int div = 2;
            for (; div * div < y; div++) {
                if (y % div == 0) {
                    discard = (discard + subsolve(div, y) + subsolve(y / div, y)) % mod;
                }
            }
            if (div * div == y)
                discard = (discard + subsolve(div, y)) % mod;
//        System.out.print("x = " + x);
//        System.out.print(" y = " + y);
//        System.out.print(" total = " + total);
//        System.out.println(" discard = " + discard);
            long res = (total - discard + 2 * mod - 1) % mod; // -1 discard x == y
            if (y < MAX)
                memo[y] = res;
            return res;
        }

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int x = in.ni(), y = in.ni();
            if (x == y) {
                out.println(1);
                return;
            }

            memo = new Long[MAX];
//        if(y < 10)
//        getCompositions(y, x);
            long res = subsolve(x, y);
//        System.out.println("res = " + res);
            out.println(res);
        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String ns() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int ni() {
            return Integer.parseInt(ns());
        }

    }

    static class IntegerUtils {
        public static long pow(long a, long p, long mod) {
            if (p == 0) {
                return 1;
            }

            long t = pow(a, p / 2, mod);

            if (p % 2 != 0) {
                return (((t * t) % mod) * a) % mod;
            } else {
                return (t * t) % mod;
            }
        }

    }
}

import java.io.*;
import java.util.*;
public class CF900_D2_D{
	public static void main(String[] args)throws Throwable {
		MyScanner sc=new MyScanner();
		PrintWriter pw=new PrintWriter(System.out);

		int x=sc.nextInt();
		int y=sc.nextInt();
		if(y%x!=0)
			pw.println(0);
		else{
			int n=y/x;
			map=new HashMap<Integer, Integer>();
			map.put(1, 1);
			ArrayList<Integer> div=new ArrayList<Integer>();
			for(int i=1;i*i<=n;i++){
				if(n%i==0){
					div.add(i);
					int j=n/i;
					if(j!=i)
						div.add(j);
				}
			}
			Collections.sort(div);
			int sz=div.size();
			div2=new ArrayList [sz];
			for(int i=0;i<sz;i++)
				div2[i]=new ArrayList<Integer>();
			pos=new HashMap<Integer, Integer>();
			for(int i=1;i<sz;i++){
				pos.put(div.get(i), i);
				for(int j=i;j<sz;j++){
					if(div.get(j)%div.get(i)==0)
						div2[j].add(div.get(i));
				}
			}
			pw.println(dp(n));
		}

		pw.flush();
		pw.close();
	}
	static ArrayList<Integer> [] div2;
	static HashMap<Integer, Integer> map,pos;

	static int dp(int i){

		if(map.containsKey(i))
			return map.get(i);

		int ans=pow2(i-1);
		for(int x : div2[pos.get(i)]){
			ans-=dp(i/x);
			ans%=mod;
			if(ans<0)
				ans+=mod;
		}
		map.put(i, ans);
		return ans;
	}
	static int mod=(int)(1e9+7);

	static int pow2(int y){
		if(y==0)
			return 1;
		if(y%2==0){
			int z=pow2(y/2);
			return (int) ((1L*z*z)%mod);
		}else{
			int z=pow2(y-1);
			return (int) ((1L*2*z)%mod);
		}
	}

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;
		public MyScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}
		String next() {while (st == null || !st.hasMoreElements()) {
			try {st = new StringTokenizer(br.readLine());}
			catch (IOException e) {e.printStackTrace();}}
		return st.nextToken();}
		int nextInt() {return Integer.parseInt(next());}
		long nextLong() {return Long.parseLong(next());}
		double nextDouble() {return Double.parseDouble(next());}
		String nextLine(){String str = "";
		try {str = br.readLine();}
		catch (IOException e) {e.printStackTrace();}
		return str;}
	}
}

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.List;

public class Main {

	static int MOD = (int) 1e9 + 7;
	static HashMap<Integer, Long> map;

	public static void main(String[] args) {
		FastScanner input = new FastScanner(System.in);

		int x = input.nextInt();
		int y = input.nextInt();

		map = new HashMap<>();

		if (y % x != 0)
			System.out.println(0);
		else
			System.out.println(f(y / x));
	}

	static List<Integer> divisors(int t) {
		List<Integer> ls = new ArrayList<>();
		for (int i = 2; i * i <= t; i++) {
			if (t % i == 0) {
				ls.add(i);
				if (i != t / i)
					ls.add(t / i);
			}
		}
		ls.add(t);
		return ls;
	}

	static long f(int t) {
		if (t == 1)
			return 1L;
		if (map.containsKey(t))
			return map.get(t);
		long sum = exp(2L, t - 1);
		for (int div : divisors(t))
			sum = (sum - f(t / div) + MOD) % MOD;
		map.put(t, sum);
		return sum;
	}

	static long exp(long a, int n) {
		if (n == 0)
			return 1;
		return exp(a * a % MOD, n / 2) * (n % 2 == 1 ? a : 1) % MOD;
	}

	// Matt Fontaine's Fast IO
	static class FastScanner {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public FastScanner(InputStream stream) {
			this.stream = stream;
		}

		int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		boolean isEndline(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String next() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		String nextLine() {
			int c = read();
			while (isEndline(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndline(c));
			return res.toString();
		}
	}
}

import org.omg.CORBA.INTERNAL;

import java.io.*;
import java.math.*;
import java.util.*;
import java.lang.*;

public class Main implements Runnable {
    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;
        private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();

            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }

                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
            return res * sgn;
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return readString();
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    public static void main(String args[]) throws Exception {
        new Thread(null, new Main(), "Main", 1 << 26).start();
    }

    static long gcd(long a, long b) {
        if (b == 0) return a;
        return gcd(b, a % b);
    }

    static int gcd(int a, int b) {
        if (b == 0) return a;
        return gcd(b, a % b);
    }

    static long modPow(long a, long p, long m) {
        if (a == 1) return 1;
        long ans = 1;
        while (p > 0) {
            if (p % 2 == 1) ans = (ans * a) % m;
            a = (a * a) % m;
            p >>= 1;
        }
        return ans;
    }

    static long modInv(long a, long m) {
        return modPow(a, m - 2, m);
    }

    static class Radix {

        static int getMax(int arr[], int n) {
            int mx = arr[0];
            for (int i = 1; i < n; i++)
                if (arr[i] > mx)
                    mx = arr[i];
            return mx;
        }

        static void countSort(int arr[], int n, int exp) {
            int output[] = new int[n];
            int i;
            int count[] = new int[10];
            Arrays.fill(count, 0);

            for (i = 0; i < n; i++)
                count[(arr[i] / exp) % 10]++;

            for (i = 1; i < 10; i++)
                count[i] += count[i - 1];

            for (i = n - 1; i >= 0; i--) {
                output[count[(arr[i] / exp) % 10] - 1] = arr[i];
                count[(arr[i] / exp) % 10]--;
            }

            for (i = 0; i < n; i++)
                arr[i] = output[i];
        }

        static void radixsort(int arr[], int n) {
            int m = getMax(arr, n);

            for (int exp = 1; m / exp > 0; exp *= 10)
                countSort(arr, n, exp);
        }

    }

    class DSU {
        int par[], size[], connectedComponent;

        DSU(int n) {
            par = new int[n];
            size = new int[n];
            for (int i = 0; i < n; i++) {
                size[i] = 1;
                par[i] = i;
            }
            connectedComponent = n;
        }

        int root(int n) {
            if (n == par[n]) return n;
            return par[n] = root(par[n]);
        }

        boolean union(int u, int v) {
            return f_union(root(u), root(v));
        }

        boolean f_union(int u, int v) {
            if (u == v) return false;
            if (size[u] > size[v]) {
                size[u] += size[v];
                par[v] = u;
            } else {
                size[v] += size[u];
                par[u] = v;
            }
            connectedComponent--;
            return true;
        }

        DSU clone_DSU() {
            DSU t = new DSU(par.length);
            t.connectedComponent = connectedComponent;
            for (int i = 0; i < par.length; i++) {
                t.par[i] = par[i];
                t.size[i] = size[i];
            }
            return t;
        }
    }

    class segmentTree {
        long query(int cur, int l, int r, int start, int end, long tree[], long a[], long[] lazy) {
            if (l > end || r < start) return 0;
            if (lazy[cur] != 0) {
                tree[cur] += lazy[cur];
                if (l != r) {
                    lazy[2 * cur + 1] += lazy[cur];
                    lazy[2 * cur + 2] += lazy[cur];
                }
                lazy[cur] = 0;
            }
            if (l >= start && r <= end) return tree[cur];
            int mid = (l + r) >> 1;
            long p1 = query(2 * cur + 1, l, mid, start, end, tree, a, lazy);
            long p2 = query(2 * cur + 2, mid + 1, r, start, end, tree, a, lazy);
            return p1 + p2;
        }

        void build(int cur, int l, int r, long tree[], long a[]) {
            if (l == r) {
                tree[cur] = a[l];
                return;
            }
            int mid = (l + r) >> 1;
            build(2 * cur + 1, l, mid, tree, a);
            build(2 * cur + 2, mid + 1, r, tree, a);
            tree[cur] = tree[2 * cur + 1] + tree[2 * cur + 2];
        }

        void update(int cur, int start, int end, long val, int l, int r, long tree[], long a[], long[] lazy) {
            if (l > end || r < start) return;
            if (lazy[cur] != 0) {
                tree[cur] += (r - l + 1) * lazy[cur];
                if (l != r) {
                    lazy[2 * cur + 1] += lazy[cur];
                    lazy[2 * cur + 2] += lazy[cur];
                }
                lazy[cur] = 0;
            }
            if (l >= start && r <= end) {
                tree[cur] += (r - l + 1) * val;
                if (l != r) {
                    lazy[cur * 2 + 1] += val;
                    lazy[cur * 2 + 2] += val;
                }
                return;
            }
            int mid = (l + r) >> 1;
            update(2 * cur + 1, start, end, val, l, mid, tree, a, lazy);
            update(2 * cur + 2, start, end, val, mid + 1, r, tree, a, lazy);
            tree[cur] = tree[2 * cur + 1] + tree[2 * cur + 2];
        }
    }

    public void run() {
        InputReader sc = new InputReader(System.in);
        // Scanner sc=new Scanner(System.in);
        //  Random sc=new Random();
        PrintWriter out = new PrintWriter(System.out);

        int x=sc.nextInt();
        int y=sc.nextInt();
        if(y%x!=0){
            out.println(0);
            out.close();return;
        }
        dp=new HashMap<>();
        out.println(f(y/x));

        out.close();
    }

    long mod=1000000007;
    HashMap<Integer,Long> dp;

    long f(int n){
        if(dp.containsKey(n))return dp.get(n);
        if(n==1){
            dp.put(1,1L);
            return 1;
        }
        long ans=modPow(2,n-1,mod);
        int i;
        for (i = 2; i*i<n ; i++) {
            if(n%i==0){
                ans=(ans-f(i)+mod)%mod;
                ans=(ans-f(n/i)+mod)%mod;
            }
        }
        if(i*i==n){
            ans=(ans-f(n/i)+mod)%mod;
        }
        ans=(ans-f(1)+mod)%mod;
        dp.put(n,ans);
        return ans;
    }

}

import java.io.*;
import java.util.*;

public class Mainn {
	FastReader scn;
	PrintWriter out;
	String INPUT = "1000000000 1000000000\r\n" + "";

	void solve() {
		int x = scn.nextInt(), y = scn.nextInt(), mod = (int) 1e9 + 7;
		if (y % x != 0) {
			out.println(0);
			return;
		}
		int k = y / x;

		HashMap<Integer, Long> map = new HashMap<>();
		map.put(1, 1L);
		map.put(2, 1L);

		long ans = 0;
		if (map.containsKey(k)) {
			ans = map.get(k);
		} else {
			ans = func(k, map, mod);
			ans = (power(2, k - 1, mod) - ans + mod) % mod;
		}
		out.println(ans);
	}

	long func(int k, HashMap<Integer, Long> map, int mod) {
		long rv = 1;
		for (int i = 2; i * i <= k; i++) {
			if (k % i != 0) {
				continue;
			}
			if (map.containsKey(i)) {
				rv += map.get(i);
			} else {
				long x = (power(2, i - 1, mod) - func(i, map, mod) + mod) % mod;
				map.put(i, x);
				rv += x;
			}
			if (i * i != k) {
				if (map.containsKey(k / i)) {
					rv += map.get(k / i);
				} else {
					long x = (power(2, k / i - 1, mod) - func(k / i, map, mod) + mod) % mod;
					map.put(k / i, x);
					rv += x;
				}
			}
			rv %= mod;
		}

		return rv;
	}

	long power(long a, long x, long mod) {
		if (x == 0) {
			return 1;
		}
		long p = power(a, x / 2, mod);
		p *= p;
		p %= mod;
		if (x % 2 == 1) {
			p *= a;
			p %= mod;
		}
		return p;
	}

	void run() throws Exception {
		boolean oj = System.getProperty("ONLINE_JUDGE") != null;
		out = new PrintWriter(System.out);
		scn = new FastReader(oj);
		long time = System.currentTimeMillis();
		solve();
		out.flush();
		if (!oj) {
			System.out.println(Arrays.deepToString(new Object[] { System.currentTimeMillis() - time + " ms" }));
		}
	}

	public static void main(String[] args) throws Exception {
		new Mainn().run();
	}

	class FastReader {
		InputStream is;

		public FastReader(boolean onlineJudge) {
			is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());

		}

		byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		char nextChar() {
			return (char) skip();
		}

		String next() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		char[] next(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		char[][] nextMatrix(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = next(m);
			return map;
		}

		int[] nextArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		int nextInt() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		long nextLong() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		int[] shuffle(int[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				arr[i] = arr[i] ^ arr[j];
				arr[j] = arr[i] ^ arr[j];
				arr[i] = arr[i] ^ arr[j];
			}
			return arr;
		}
	}
}

import java.io.*;
import java.util.*;

public class Mainn {
	FastReader scn;
	PrintWriter out;
	String INPUT = "";

	void solve() {
		int x = scn.nextInt(), y = scn.nextInt(), mod = (int) 1e9 + 7;
		if (y % x != 0) {
			out.println(0);
			return;
		}
		int k = y / x;

		HashMap<Integer, Long> map = new HashMap<>();
		map.put(1, 1L);

		out.println(func(k, map, mod));
	}

	long func(int k, HashMap<Integer, Long> map, int mod) {
		if (map.containsKey(k)) {
			return map.get(k);
		}
		long rv = 1;
		for (int i = 2; i * i <= k; i++) {
			if (k % i != 0) {
				continue;
			}
			rv += func(i, map, mod);
			if (i * i != k) {
				rv += func(k / i, map, mod);
			}
		}

		rv %= mod;
		rv = (power(2, k - 1, mod) - rv + mod) % mod;
		map.put(k, rv);

		return rv;
	}

	long power(long a, long x, long mod) {
		if (x == 0) {
			return 1;
		}
		long p = power(a, x / 2, mod);
		p *= p;
		p %= mod;
		if (x % 2 == 1) {
			p *= a;
			p %= mod;
		}
		return p;
	}

	void run() throws Exception {
		boolean oj = System.getProperty("ONLINE_JUDGE") != null;
		out = new PrintWriter(System.out);
		scn = new FastReader(oj);
		long time = System.currentTimeMillis();
		solve();
		out.flush();
		if (!oj) {
			System.out.println(Arrays.deepToString(new Object[] { System.currentTimeMillis() - time + " ms" }));
		}
	}

	public static void main(String[] args) throws Exception {
		new Mainn().run();
	}

	class FastReader {
		InputStream is;

		public FastReader(boolean onlineJudge) {
			is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());

		}

		byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		char nextChar() {
			return (char) skip();
		}

		String next() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		char[] next(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		char[][] nextMatrix(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = next(m);
			return map;
		}

		int[] nextArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		int nextInt() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		long nextLong() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		int[] shuffle(int[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				arr[i] = arr[i] ^ arr[j];
				arr[j] = arr[i] ^ arr[j];
				arr[i] = arr[i] ^ arr[j];
			}
			return arr;
		}
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class A {

	public static final int MOD = 1000000007;

	static Map<Integer, Integer> memo;

	public static int poo(long b, int p) {
		long rt = 1;
		for(;p>0;p=p/2,b=b*b%MOD) if(p % 2 == 1) {
			rt = rt * b % MOD;
		}
		return (int) rt;
	}

	public static int calc(int x, int y) {
		if(y == 0) {
			return 0;
		} else if (y % x > 0) {
			return 0;
		} else if(x > 1) {
			return calc(1, y / x);
		} else {
			if(memo.containsKey(y)) {
				return memo.get(y);
			} else {
				int ans = poo(2, y - 1);

				for(int i=2;((long) i) * i <= y;i++) if(y % i == 0){
					int lo = y / i; int hi = i;
					ans = (ans + MOD - calc(lo, y)) % MOD;
					if(lo != hi) ans = (ans + MOD - calc(hi, y)) % MOD;
				}

				if(y > 1) ans = (ans + MOD - calc(y, y)) % MOD;

				memo.put(y, ans);

				return ans;
			}

		}
	}

	public static void main(String[] args) throws IOException {
		FastScanner sc = new FastScanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();

		memo = new HashMap<Integer, Integer>();

		pw.println(calc(x, y));

		pw.close();
		sc.close();
	}

}

class FastScanner {
	BufferedReader br;
	StringTokenizer st;

	public FastScanner(InputStream is) {
		br = new BufferedReader(new InputStreamReader(is));
		st = null;
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	public long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public void close() throws IOException {
		br.close();
	}
}

import static java.util.Arrays.*;
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import java.util.*;
import java.math.*;
import java.io.*;

public class Main implements Runnable {

	boolean TEST = System.getProperty("ONLINE_JUDGE") == null;

    void solve() throws IOException {
    	int x = nextInt(), y = nextInt();
    	if (y % x != 0) {
    		out.println(0);
    		return;
    	}
    	out.println(f(y / x));
    }

    int MOD = (int)1e9 + 7;
    Map<Integer, Long> map = new HashMap<>();
    long f(int t) {
    	if (t == 1) return 1;
    	if (map.containsKey(t)) return map.get(t);
    	long res = pow(2, t - 1, MOD);
    	for (int i = 2; i * i <= t; i++)
    		if (t % i == 0) {
    			res = (res + MOD - f(i)) % MOD;
    			if (i * i != t) res = (res + MOD - f(t / i)) % MOD;
    		}
    	map.put(t, (res + MOD - 1) % MOD);
    	return map.get(t);
    }

    long pow(long a, long p, int MOD) {
    	if (p == 0) return 1;
    	long b = pow(a, p / 2, MOD);
    	if (p % 2 == 0) return b * b % MOD;
    	return b * b % MOD * a % MOD;
    }

    String next() throws IOException {
        while(st == null || !st.hasMoreTokens()) st = new StringTokenizer(input.readLine());
        return st.nextToken();
    }

    int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    long nextLong() throws IOException {
        return Long.parseLong(next());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }

    void debug(Object... o) {
        System.out.println(deepToString(o));
    }

    void gcj(Object o) {
        String s = String.valueOf(o);
        out.println("Case #" + test + ": " + s);
        System.out.println("Case #" + test + ": " + s);
    }

    BufferedReader input;
    PrintWriter out;
    StringTokenizer st;
    int test;

    void init() throws IOException {
        if (TEST) input = new BufferedReader(new FileReader("input.in"));
        else input = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(new BufferedOutputStream(System.out));
    }

    public static void main(String[] args) throws IOException {
        new Thread(null, new Main(), "", 1 << 20).start();
    }

    public void run() {
        try {
            init();
            if (TEST) {
                int runs = nextInt();
                for(int i = 0; i < runs; i++) solve();
            } else solve();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        int mod = 1000000007;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int x = in.readInt();
            int y = in.readInt();

            if (y % x != 0) {
                out.println(0);
                return;
            }
            y /= x;

            ArrayList<Integer> div = new ArrayList<>();

            for (long i = 2; i * i <= y; i++) {
                if (y % i == 0) div.add((int) i);
                if (y % i == 0 && y / i != i) div.add(y / (int) i);
            }

            if (y != 1) {
                div.add(y);
            } else {
                out.println(1);
                return;
            }

            Collections.sort(div);

            int[] f = new int[div.size()];
            long total = 0;

            for (int i = 0; i < f.length; i++) f[i] = (mod + pow(2, div.get(i) - 1) - 1) % mod;

            for (int i = 1; i < f.length; i++) {
                for (int j = i - 1; j >= 0; j--) {
                    if (div.get(i) % div.get(j) == 0) {
                        f[i] = (int) ((mod + f[i] - (long) f[j]) % mod);
                    }
                }
                total += f[i];
                total = total % mod;
            }
            out.println(f[f.length - 1]);

        }

        int pow(long a, int b) {
            long ans = 1;
            while (b >= 1) {
                if (b % 2 == 1) ans = (ans * a) % mod;
                a = (a * a) % mod;
                b /= 2;
            }
            return (int) ans;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Pradyumn
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, FastReader in, PrintWriter out) {
            int x = in.nextInt();
            int y = in.nextInt();
            if (y % x != 0) {
                out.println(0);
                return;
            }
            int MODULO = NT.MOD7I;
            y /= x;
            int[] vec = getAllDivisors(y);
            int n = vec.length;
            long ans = 0;
            for (int i = 0; i < (1 << n); i++) {
                int cnt = 0;
                int d = 1;
                for (int j = 0; j < n; j++)
                    if ((i >> j & 1) != 0) {
                        d *= vec[j];
                        cnt++;
                    }
                int res = (int) NT.powerMod(2, y / d - 1, MODULO);
                if ((cnt & 1) != 0) ans -= res;
                else ans += res;
            }
            out.println((ans % MODULO + MODULO) % MODULO);
        }

        public static int[] getAllDivisors(int n) {
            List<Integer> divisors = new ArrayList<>();
            for (int i = 2; i * i <= n; ++i) {
                if (n % i == 0) {
                    while (n % i == 0) n /= i;
                    divisors.add(i);
                }
            }
            if (n != 1) divisors.add(n);
            int[] res = new int[divisors.size()];
            int ptr = 0;
            for (Integer dd : divisors) res[ptr++] = dd;
            return res;
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar;
        private int pnumChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(InputStream stream) {
            this.stream = stream;
        }

        private int pread() {
            if (pnumChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= pnumChars) {
                curChar = 0;
                try {
                    pnumChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (pnumChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = pread();
            while (isSpaceChar(c))
                c = pread();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = pread();
            }
            int res = 0;
            do {
                if (c == ',') {
                    c = pread();
                }
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = pread();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        private boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        private static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class NT {
        public static final int MOD7I = (int) 1e9 + 7;

        public static long powerMod(long a, long n, long mod) {
            //    a %= mod;
            long ret = 1;
            int x = 63 - Long.numberOfLeadingZeros(n);
            for (; x >= 0; x--) {
                ret = ret * ret % mod;
                if (n << 63 - x < 0) ret = ret * a % mod;
            }
            return ret;
        }

    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        Map<Integer, Integer> cache;
        ArrayList<Integer> divs;
        int MOD = (int) 1e9 + 7;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int X = in.nextInt();
            int Y = in.nextInt();

            if (Y % X != 0) {
                out.println(0);
                return;
            }

            cache = new HashMap<>();

            Y /= X;

            divs = divisors(Y);

            out.println(F(Y));
        }

        private int F(int num) {
            if (cache.containsKey(num)) {
                return cache.get(num);
            }

            int ans = (int) pow(2, num - 1);

            for (int d : divs) {
                if (d > 1 && d <= num && num % d == 0) {
                    ans = add(ans, -F(num / d));
                }
            }

            cache.put(num, ans);
            return ans;
        }

        private int add(long a, long b) {
            return (int) ((((a + b) % MOD) + MOD) % MOD);
        }

        private long pow(long n, long k) {
            if (k == 0) return 1;
            if (k % 2 == 0) return pow(n * n % MOD, k / 2);
            return pow(n, k - 1) * n % MOD;
        }

        private ArrayList<Integer> divisors(int num) {
            ArrayList<Integer> ans = new ArrayList<>();
            for (int x = 1; x * x <= num; x++) {
                if (num % x == 0) {
                    ans.add(x);
                    if (x * x != num) {
                        ans.add(num / x);
                    }
                }
            }
            Collections.sort(ans);
            return ans;
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

import java.util.*;
import java.io.*;
public class EdB {

	public static void main(String[] args) throws Exception{
		long num = 1000000007;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);

	 	StringTokenizer st = new StringTokenizer(bf.readLine());
	 	long x = Integer.parseInt(st.nextToken());
	 	long y = Integer.parseInt(st.nextToken());
	 	if (y%x != 0){
	 		out.println(0);
	 	}
	 	else if (y == x){
	 		out.println(1);
	 	}
	 	else{
		 	TreeSet<Long> divisors = new TreeSet<Long>();
		 	for(long j = 2;j*j<=y/x;j++){
		 		if ((y/x)%j == 0){
		 			divisors.add(j);
		 			divisors.add((y/x)/j);
		 		}
		 	}
		 	divisors.add(y/x);
		 	Map<Long, Long> dp = new HashMap<Long, Long>();
		 	dp.put(1L,  1L);
		 	for(long j: divisors){
		 		long ans = power(2, j-1, num)-1;
		 		for(long k = 2;k*k<=j;k++){
		 			if (j%k == 0 && j/k == k){
		 				ans-=dp.get(k);
		 				ans%=num;
		 				ans+=num;
		 				ans%=num;
		 			}
		 			else if (j%k == 0){
		 				ans-=dp.get(k);
		 				ans%=num;
		 				ans+=num;
		 				ans%=num;
		 				ans-=dp.get(j/k);
		 				ans%=num;
		 				ans+=num;
		 				ans%=num;
		 			}
		 		}
		 		dp.put(j,  ans);
		 	}
		 	out.println(dp.get(y/x));

	 	}

 		out.println();

 		out.close();

 	}
	public static int power(long x, long y, long mod){
		long ans = 1;
		while(y>0){
			if (y%2==1)
				ans = (ans*x)%mod;
			x = (x*x)%mod;
			y/=2;
		}
		return (int)(ans);
	}
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is

import java.util.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;

public class Main {
    static long x,y;
    static Map<Long ,Long> map;
    static long mod=1000*1000*1000+7;
    Main(){
        x=1;y=0;
    }

    static int legendre(int n ,int p)
    {
        //Exponenet of prime p in n!
        int exp=0,pr=p;
        while(pr<=n)
        {
            exp+=n/pr;
            pr=pr*p;

        }
        return exp;

    }
    static long gcd(long a ,long b)
    {
        if(b==0)
            return a;
        return gcd(b ,a%b);
    }
    public static int gcd(int a, int b) {
        while (b > 0) {
            int c = a;
            a = b;
            b = c % b;
        }
        return a;
    }
    static long expo(long x ,long n ,long mod)
    {
        long res=1;
        while(n>0)
        {
            if(n%2==1)
                res=(res*x)%mod;
            x=(x*x)%mod;
            n=n/2;
        }
        return res%mod;
    }

    static long fermat(long a ,long m)
    {
        return expo(a,m-2,m)%m;
    }

    static void extendedEuclidean(long a ,long m)
    {
        if(m==0)
        {
            x=1;
            y=0;
        }
        else
        {
            extendedEuclidean(m,a%m);
            long temp=x;
            x=y;
            y=temp-(a/m)*y;
        }

    }

    static long EuclidInverse(long a ,long m)
    {
        extendedEuclidean(a ,m);
        return (x%m+m)%m;
    }

    static long g(long t){
        return expo(2,t-1,mod);
    }

    static long f(long t)
    {
        if(map.containsKey(t)) return map.get(t);
        long ans=(g(t)-f(1)+mod)%mod;
        for(long x=2;x*x<=t;x++)
        {
            if(t%x==0){

            ans=(ans-f(t/x)+mod)%mod;
            if(t/x!=x)
                ans=(ans-f(t/(t/x))+mod)%mod;

            }

        }
        map.put(t,ans);
        return ans;

    }

    public static void main(String args[] ) throws Exception {
        FastScanner s = new FastScanner();
       long x=s.nextLong();long y=s.nextLong();
        map= new HashMap<>();
        map.put(new Long(1),new Long(1));
        if(y%x!=0)System.out.println(0);
        else System.out.println(f(y/x));
    }

static class FastScanner {

    private InputStream mIs;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public FastScanner() {
        this(System.in);
    }

    public FastScanner(InputStream is) {
        mIs = is;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = mIs.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public String nextLine() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isEndOfLine(c));
        return res.toString();
    }

    public String nextString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public long nextLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public int nextInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public boolean isEndOfLine(int c) {
        return c == '\n' || c == '\r' || c == -1;

    }

}
}

import java.util.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;

public class tr0 {
	static PrintWriter out;
	static StringBuilder sb;
	static int mod = 1000000007;
	static long inf = (long) 1e16;
	static int[][] ad;
	static int n, m;
	static long[][][] memo;
	static HashSet<Integer> h;
	static long[] a;

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);
		int x = sc.nextInt();
		int y = sc.nextInt();
		if (y % x != 0) {
			System.out.println(0);
			return;
		}
		long ans = 0;
		int n = y / x;
		ArrayList<Integer> div = new ArrayList<>();
		HashMap<Integer, Integer> val = new HashMap<>();
		for (long i = 1; i * i <= n; i++) {
			if (n % i != 0)
				continue;
			div.add((int) i);
			if (i != n / i) {
				int k = (int) (n / i);
				div.add(k);
			}
		}
		Collections.sort(div);
		val.put(1, 1);
		for (int i = 1; i < div.size(); i++) {
			int v = 0;
			int t = 0;
			int xp = div.get(i);
			for (long j = 2; j * j <= xp; j++) {
				if (xp % j != 0)
					continue;
				xp /= j;
				v++;
				if (xp % j == 0) {
					t = -1;
					break;
				}
			}
			if (xp > 1)
				v++;

			if (t == -1)
				val.put(div.get(i), 0);
			else if (v % 2 == 0)
				val.put(div.get(i), 1);
			else
				val.put(div.get(i), -1);

		}
	//	System.out.println(div);
		//System.out.println(val);
		for (long i = 1; i * i <= n; i++) {
			if (n % i != 0)
				continue;
			ans = (ans + modPow(2, i - 1) * val.get((int) (n / i)) + mod) % mod;
			if (i != n / i) {
				int k = (int) (n / i);
				ans = (ans + modPow(2, k - 1) * val.get((int)i) + mod) % mod;
			}
		}
		System.out.println(ans);
		out.close();
	}

	static long modPow(long a, long e)

	{
		long res = 1;
		while (e > 0) {
			if ((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public int[] nextArrInt(int n) throws IOException {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		public long[] nextArrLong(int n) throws IOException {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextLong();
			return a;
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.StringTokenizer;

import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Long.parseLong;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.fill;
import static java.util.Arrays.sort;
import static java.util.Collections.reverse;
import static java.util.Collections.reverseOrder;
import static java.util.Collections.sort;

public class Main {
    private FastScanner in;
    private PrintWriter out;

    long mod;

    private void solve() throws IOException {
        long x = in.nextLong(), y = in.nextLong();
        mod = (long) 1e9 + 7;

        if (y % x != 0) {
            out.print(0);
            return;
        }
        y /= x;

        d = divisors(y);
        map = new HashMap<>();
        out.println(dp(y));
    }

    ArrayList<Long> d;

    private ArrayList<Long> divisors(long n) {
        ArrayList<Long> a = new ArrayList<>();
        ArrayList<Long> b = new ArrayList<>();
        for (long i = 1; i * i <= n; i++)
            if (n % i == 0) {
                a.add(i);
                if (n / i != i)
                    b.add(n / i);
            }
        reverse(b);
        a.addAll(b);
        return a;
    }

    HashMap<Long, Long> map;

    private long dp(long n) {
        if (!map.containsKey(n)) {
            long ans = binpowmod(2, n - 1);
            for (long d : this.d) {
                if (d == 1)
                    continue;
                if (d > n)
                    break;
                if (n % d == 0)
                    ans = (ans - dp(n / d) + mod) % mod;
            }
            map.put(n, ans);
        }
        return map.get(n);
    }

    long binpowmod(long a, long n) {
        long res = 1;
        a %= mod;
        while (n > 0) {
            if (n % 2 == 1)
                res = (res * a) % mod;
            a = (a * a) % mod;
            n /= 2;
        }
        return res;
    }

    private void solveA() throws IOException {

    }

    private void solveB() throws IOException {

    }

    private void solveC() throws IOException {

    }

    private void solveD() throws IOException {

    }

    private void solveE() throws IOException {

    }

    class FastScanner {
        StringTokenizer st;
        BufferedReader br;

        FastScanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        boolean hasNext() throws IOException {
            return br.ready() || (st != null && st.hasMoreTokens());
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

        boolean hasNextLine() throws IOException {
            return br.ready();
        }
    }

    private void run() throws IOException {
        in = new FastScanner(System.in); // new FastScanner(new FileInputStream(".in"));
        out = new PrintWriter(System.out); // new PrintWriter(new FileOutputStream(".out"));

        solve();

        out.flush();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }
}

		import java.awt.List;
		import java.io.*;
		import java.util.*;

		/*
		 *
		 * daiict
		 *
		 *
		 *
		 */

		public class Main {
			FastScanner in;
			PrintWriter out;

			static ArrayList[] adj;

			static int n;
			static int m;
			static int visited[][];
			static int[][] arr;
			static int[][] brr;
			static int[][] ans;
			static int array[];
			static int pref[];
			static int sum = 0;
		//for dfs do not delete
			static int dir[][] ={{1,0},{0,1},{0,-1}};
			static HashMap<Long,Long> map;

			static long an = 0;
			static long bn = 0;
			static int p = 0;
			static int ta = -1;
			static int tb = -1;
			static Stack<Integer> st;
			static int k;
			static long mod = (long)1e9 + 7;
			static long[] seg;

			static class Pair implements Comparable<Pair>
		    {
				int x;
				boolean y;
				String s = "";
				String val;
		        Pair(int l, boolean b, String p,String q) {

		        	this.x = l;
		            this.y = b;
		           this.s = p;
		           this.val = q;
		        }
		        @Override
		        public int compareTo(Pair p) {

		        	String arr[] = val.split(" ");
		        	String brr[] = p.val.split(" ");

		        	if(s.equals("numeric")){
		        		int aa = Integer.parseInt(arr[x]);
						int bb = Integer.parseInt(brr[x]);

						if(aa>bb && this.y){
							return 1;
						}else if(this.y){
							return -1;
						}else if(aa >= bb && ! this.y){
							return -1;
						}else{
							return 1;
						}
		        	}else{
		        		if(this.y){
		        			return arr[x].compareTo(brr[x]);
		        		}else{
		        			return brr[x].compareTo(arr[x]);
		        		}
		        	}

		        }

		        public String toString(){
		        	return x + " " + y;
		        }

		        public boolean equals(Object o){
		        	if(o instanceof Pair){
		        		Pair a = (Pair)o;

		        		return this.x == a.x;
		        	}

		        	return false;
		        }

//		        public int hashCode(){
//		        	return new Long(x).hashCode()*31 + new Long(y).hashCode();
//		        }

		    }

			public static int gcd(int a, int b) {
				if (b == 0) return a;
				return gcd(b, a%b);
			}

			void build(int n) {  // build the tree
				  for (int i = n - 1; i > 0; --i) seg[i] = Math.min(seg[i<<1],seg[i<<1|1]);
				}

			public static void modify(int p, long val,int n) {  // set value at position p
				  for (seg[p += n] = val; p > 1; p >>= 1) seg[p>>1] = Math.min(seg[p],seg[p^1]);
				}

				long query(int l, int r,int n) {  // sum on interval [l, r)
				  long res = Long.MAX_VALUE;
				  for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
				    if ((l&1) == 1) res = (long) Math.min(res,seg[l++]);
				    if ((r&1) == 1) res = (long)Math.min(res,seg[--r]);
				  }
				  return res;
				}

				 static long bC(int n, int k)
				    {
				    long C[][] = new long[n+1][k+1];
				    int i, j;

				        // Calculate  value of Binomial Coefficient in bottom up manner
				    for (i = 0; i <= n; i++)
				    {
				        for (j = 0; j <= Math.min(i, k); j++)
				        {
				            // Base Cases
				            if (j == 0 || j == i)
				                C[i][j] = 1;

				            // Calculate value using previosly stored values
				            else
				                C[i][j] = C[i-1][j-1] + C[i-1][j];
				          }
				     }

				    return C[n][k];
				    }

		    void solve() throws NumberFormatException, IOException {

		    	Scanner in = new Scanner(System.in);

		    	long x = in.nextLong();
		    	long y = in.nextLong();
		    	int f = 0;

		    	if(y%x != 0 || x>y){
		    		out.println(0);
		    		return;
		    	}

		    	long n = y/x;

		    	map = new HashMap();
		    	map.put(1L, 1L);
		    	long ans = call(n);

		    	out.println(ans);
		    }

		    public static long call(long n){
		    	if(map.containsKey(n)){
		    		return map.get(n);
		    	}

		    	long ans = (pow(2,n-1,mod) - 1)%mod;

		    	for(int i = 2;i*i<=n;i++){
		    		if(n%i == 0){
		    			//removal of number whose gcd after removing i is n/i that is map.get(i)
		    			ans =(ans-call(i))%mod;
		    			if(ans < 0){
		    				ans += mod;
		    			}
		    			// if i*i = n then n/i = i
			    		//else

			    		if(i*i != n){
			    			ans = (ans-call(n/i))%mod;
			    			if(ans < 0){
			    				ans += mod;
			    			}
			    		}

		    		}

		    	}

		    	map.put(n,ans);
		    	return ans;

		    }

		    public static void dfs(int i,int j,int d){

		    	System.out.println(i + " " + j + " " +d);

		    	if(d <= ans[i][j]){
		    		return;
		    	}

		    	if(i == n-1 && j == m-1){
		    		p = Math.max(p,d);
		    		ans[i][j] = p;
		    		arr = brr;
		    		return;
		    	}

		    	ans[i][j] = d;
		    	int temp = arr[i][j];
		    	arr[i][j] = 0;

		    	for(int p= 0;p<3;p++){
		    		int x = i + dir[p][0];
		    		int y = j + dir[p][1];

		    		if(x < 0 || x >=n || y < 0 || y >=m){
		    			continue;
		    		}else{

		    			dfs(x,y,d+arr[x][y]);

		    		}
		    	}
		    	//arr[i][j] = temp;

		    }

		    public static int Floor(int[] dp, int low, int high, long x)
		    {
		        // If low and high cross each other
		        if (low > high)
		            return -1;

		        // If last element is smaller than x
		        if (x >= dp[high])
		            return high;

		        // Find the middle point
		        int mid = (low+high)/2;

		        // If middle point is floor.
		        if (dp[mid] == x)
		            return mid;

		        // If x lies between mid-1 and mid
		        if (mid > 0 && dp[mid-1] <= x && x < dp[mid])
		            return mid-1;

		        // If x is smaller than mid, floor must be in
		        // left half.
		        if (x < dp[mid])
		            return Floor(dp, low, mid-1, x);

		        // If mid-1 is not floor and x is greater than
		        // arr[mid],
		        return Floor(dp, mid+1, high, x);
		    }

		    public static String[] reverse(String arr[]){

		    	for(int i = 0;i<arr.length/2;i++){
		    		String temp = arr[i];
		    		arr[i] = arr[arr.length-i-1];
		    		arr[arr.length-1-i] = temp;
		    	}

		    	return arr;

		    }

		    static long inv(long x , long mod)
			{
				long r,y;
				for(r=1,y=mod-2;y!=0;x=x*x%mod,y>>=1)
				{
					if((y&1)==1)
						r=r*x%mod;

				}
				return r;
			}

		    public static long sum(long x){
		    	return x<10?x:x%10 + sum(x/10);
		    }

			public static long gcd(long x, long y) {
				if (x == 0)
					return y;
				else
					return gcd( y % x,x);
			}

			public static long pow(long x,long y,long n){
				if(y==0)
					return 1%n;
				if(y%2==0){
					long z=pow(x,y/2,n);
					return (z*z)%n;
				}
				return ((x%n)*pow(x,y-1,n))%n;
			}

			public static boolean isPrime(int n) {
				// Corner cases
				if (n <= 1)
					return false;
				if (n <= 3)
					return true;

				// This is checked so that we can skip
				// middle five numbers in below loop
				if (n % 2 == 0 || n % 3 == 0)
					return false;

				for (int i = 5; i * i <= n; i = i + 6)
					if (n % i == 0 || n % (i + 2) == 0)
						return false;

				return true;
			}

			void run() throws NumberFormatException, IOException {
				in = new FastScanner();
				out = new PrintWriter(System.out);

				solve();

				out.close();
			}

			class FastScanner {
				BufferedReader br;
				StringTokenizer st;

				public FastScanner() {
					br = new BufferedReader(new InputStreamReader(System.in));
				}

				String next() {
					while (st == null || !st.hasMoreTokens()) {
						try {
							st = new StringTokenizer(in.br.readLine());
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					return st.nextToken();
				}

				int nextInt() {
					return Integer.parseInt(next());
				}

				long nextLong() {
					return Long.parseLong(next());
				}

				double nextDouble() {
					return Double.parseDouble(next());
				}
			}

			class Tri{

				Tri[] arr;

				public Tri(){
					arr = new Tri[27];
				}

			}

			public static void main(String[] args) throws NumberFormatException, IOException {
				new Main().run();
			}
		}

		class Node{
			int a;
			int b;

		}

		class MyComp implements Comparator<String>{

			int c = 0;

			MyComp(int d){
				c = d;
			}

			@Override
			public int compare(String a,String b) {

				// < == -1

				String arr[] = a.split(" ");
				String brr[] = b.split(" ");

				return arr[c].compareTo(brr[c]);

			}

		}

		class MyComp2 implements Comparator<String>{

			int c = 0;

			MyComp2(int d){
				c = d;
			}

			@Override
			public int compare(String a,String b) {

				// < == -1

				String arr[] = a.split(" ");
				String brr[] = b.split(" ");

				int aa = Integer.parseInt(arr[c]);
				int bb = Integer.parseInt(brr[c]);

				if(aa>bb){
					return 1;
				}else{
					return -1;
				}

			}

		}

import java.util.*;
public class sequences{

	public static void main(String [] args){
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt();
		int y = sc.nextInt();
		int MOD = (int) 1e9 + 7;
		if (y%x == 0) {
			y /= x;

			List<Integer> n = new ArrayList<>();
			for (int i = 1; 1l * i * i <= y ;i++ ) {
				if (y%i == 0) {
					n.add(i);
					if (y/i!=i) {
						n.add(y/i);
					}

				}
			}
			long[] m = new long[n.size()];
			Collections.sort(n);
			//System.out.println(n);
			for (int i = 0;i<n.size() ;i++ ) {
				int k = n.get(i);
				m[i] = calc(2,k-1,MOD);
				for (int j = 0;j < i ;j++ ) {
					if (k%n.get(j) == 0) {
						m[i]-=m[j];
						if (m[i]<0) {
							m[i] += MOD;
						}
					}
				}

			}
			System.out.println(m[n.size()-1]);
		}else{
			System.out.println("0");
		}
	}
	public static long calc(int base, int exponent, int p) {
		if (exponent == 0) return 1;
		if (exponent == 1) return base % p;
		long m = calc(base, exponent >> 1, p);
		if (exponent % 2 == 0) return (m * m) % p;
		return 1l * base * m  % p * m % p;
	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.StringTokenizer;
import java.io.IOException;
import java.util.InputMismatchException;
import java.io.BufferedReader;
import java.util.Collections;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author amotoma3
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long x = in.nextLong();
            long y = in.nextLong();

            if (y % x != 0) {
                out.println(0);
                return;
            }

            y /= x;

            List<Long> divs = new ArrayList<>();
            for (long i = 1; i * i <= y; i++) {
                if (y % i == 0) {
                    divs.add(i);
                    if (i * i < y) divs.add(y / i);
                }
            }

            Collections.sort(divs);

            long MOD = 1_000_000_007;
            Modulo modulo = new Modulo(MOD);
            int n = divs.size();
            long[] dp = new long[n];
            for (int i = n - 1; i >= 0; i--) {
                dp[i] = modulo.pow(2, y / divs.get(i) - 1);
                for (int j = i + 1; j < n; j++) {
                    if (divs.get(j) % divs.get(i) == 0) {
                        dp[i] = modulo.sub(dp[i], dp[j]);
                    }
                }
            }

            out.println(dp[0]);
        }

    }

    static class InputReader {
        BufferedReader in;
        StringTokenizer tok;

        public String nextString() {
            while (!tok.hasMoreTokens()) {
                try {
                    tok = new StringTokenizer(in.readLine(), " ");
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
            }
            return tok.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(nextString());
        }

        public InputReader(InputStream inputStream) {
            in = new BufferedReader(new InputStreamReader(inputStream));
            tok = new StringTokenizer("");
        }

    }

    static class Modulo {
        long m;

        public Modulo(long m) {
            this.m = m;
        }

        public long sub(long a, long b) {
            return (a - b + m) % m;
        }

        public long pow(long a, long x) {
            long ans = 1;
            while (x > 0) {
                if ((x & 1) != 0) {
                    ans = (ans * a) % m;
                }
                x >>= 1;
                a = (a * a) % m;
            }
            return ans;
        }

    }
}

import java.util.*;

import java.util.Collections;
import java.util.ArrayList;

public class javaapplication1 {

    public static final int MAX = 1000000007;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        ArrayList<Integer> Dividendos = new ArrayList<>();

        int intX = in.nextInt();
        //long longX = (long)intX;
        int intY = in.nextInt();
        //long longY = (long)intY;

        //int[] arrDividendos = new int[intX];

        //No en Comun
        if (intY % intX != 0) {
            System.out.println(0);
        }else{
            intY = intY / intX;

        for (long i = 2; i * i <= intY; i++) {
            //Iniciar si es par
            if (intY % i == 0) {
                Dividendos.add((int) i);
            }
            //Es par pero no es el mismo numero
            if (intY % i == 0 && (intY / i != i)) {
                Dividendos.add(intY / (int) i);
            }
            /*
             if(intY % i == 0 && i !=intX){
                Dividendos.add(intY /x);
            }*/
        }

        if (intY != 1) {
            Dividendos.add(intY);
        } else {
            System.out.println(1);
            return;
        }

        int[] arrAnswer = new int[Dividendos.size()];
        long total = 0;

        Collections.sort(Dividendos);
        int temp = 0;
        for (int i = 0; i < arrAnswer.length; i++) {
            temp = (MAX + potencia(2, Dividendos.get(i) - 1,arrAnswer) - 1);
            //if(temp > intX){
            arrAnswer[i] = temp % MAX;
            //}
        }

        for (int i = 1; i < arrAnswer.length; i++) {
            for (int j = i - 1; j >= 0; j--) {
                if (Dividendos.get(i) % Dividendos.get(j) == 0) {
                    arrAnswer[i] = (int) ((MAX + arrAnswer[i] - (long) arrAnswer[j]) % MAX);
                }
                 /*
                    if(intY % i == 0 && i !=intX){
                    Dividendos.add(intY /x);
                    }*/
            }
            total += arrAnswer[i];
            total = total % MAX;
        }
        System.out.println(arrAnswer[Dividendos.size() - 1]);
        }
    }

    public static int potencia(long x1, int x2, int[] intanswer) {
        long longI = 1;
        while (x2 >= 1) {
            if (x2 % 2 == 1) {
                longI = (longI * x1) % MAX;
            }
            x1 = (x1 * x1) % MAX;
            x2 = x2 /2;

        }
        //else
       //{break;
               // }
        return (int) longI;
    }

}

import java.util.*;

import java.util.Collections;
import java.util.ArrayList;

public class javaapplication1 {

    public static final int MAX = 1000000007;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        ArrayList<Integer> Dividendos = new ArrayList<>();

        int intX = in.nextInt();
        //long longX = (long)intX;
        int intY = in.nextInt();
        //long longY = (long)intY;

        //int[] arrDividendos = new int[intX];

        //No en Comun
        if (intY % intX != 0) {
            System.out.println(0);
        }else{
            intY = intY / intX;

        for (long i = 2; i * i <= intY; i++) {
            //Iniciar si es par
            if (intY % i == 0) {
                Dividendos.add((int) i);
            }
            //Es par pero no es el mismo numero
            if (intY % i == 0 && (intY / i != i)) {
                Dividendos.add(intY / (int) i);
            }
            /*
             if(intY % i == 0 && i !=intX){
                Dividendos.add(intY /x);
            }*/
        }

        if (intY != 1) {
            Dividendos.add(intY);
        } else {
            System.out.println(1);
            return;
        }

        int[] arrAnswer = new int[Dividendos.size()];
        long total = 0;

        Collections.sort(Dividendos);
        int temp = 0;
        for (int i = 0; i < arrAnswer.length; i++) {
            //temp = (MAX + potencia(2, Dividendos.get(i) - 1,arrAnswer) - 1);
            //if(temp > intX){
            arrAnswer[i] = (MAX + potencia(2, Dividendos.get(i) - 1,arrAnswer) - 1) % MAX;
            //}
        }

        for (int i = 1; i < arrAnswer.length; i++) {
            for (int j = i - 1; j >= 0; j--) {
                if (Dividendos.get(i) % Dividendos.get(j) == 0) {
                    arrAnswer[i] = (int) ((MAX + arrAnswer[i] - (long) arrAnswer[j]) % MAX);
                }
                 /*
                    if(intY % i == 0 && i !=intX){
                    Dividendos.add(intY /x);
                    }*/
            }
            total += arrAnswer[i];
            total = total % MAX;
        }
        System.out.println(arrAnswer[Dividendos.size() - 1]);
        }
    }

    public static int potencia(long x1, int x2, int[] intanswer) {
        long longI = 1;
        while (x2 >= 1) {
            if (x2 % 2 == 1) {
                longI = (longI * x1) % MAX;
            }
            x1 = (x1 * x1) % MAX;
            x2 = x2 /2;

        }
        //else
       //{break;
               // }
        return (int) longI;
    }

}

/*Author: Satyajeet Singh, Delhi Technological University*/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;

public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static boolean sieve[];
    static ArrayList<Integer> primes;
    static long factorial[],invFactorial[];
    static HashSet<Pair> graph[];
    static boolean oj = System.getProperty("ONLINE_JUDGE") != null;
/****************************************Solutions Begins***************************************/
    static HashMap<Integer,Long> map;
    static long dfs(int i){
        if(map.containsKey(i)){
            return map.get(i);
        }
        long ans=(modulo(2,i-1,mod)-1+mod)%mod;
        for(int j=2;j*j<=i;j++){
            if(i%j==0){
                ans=(ans-dfs(i/j)+mod)%mod;
                if(i/j!=j){
                    int jj=i/j;
                    ans=(ans-dfs(i/jj)+mod)%mod;
                }
            }
        }
        map.put(i,ans);
        return ans;
    }
    public static void main (String[] args) throws Exception {
        String st[]=nl();
        int x=pi(st[0]);
        int y=pi(st[1]);
        map=new HashMap<>();
        if(y%x!=0){
            out.println(0);
        }
        else{
            map.put(1,1l);
            out.println(dfs(y/x));
        }
        //debug(map);

/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }
/****************************************Template Begins************************************************/
    static String[] nl() throws Exception{
        return br.readLine().split(" ");
    }
    static String[] nls() throws Exception{
        return br.readLine().split("");
    }
    static int pi(String str) {
        return Integer.parseInt(str);
    }
    static long pl(String str){
        return Long.parseLong(str);
    }
    static double pd(String str){
        return Double.parseDouble(str);
    }
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.000000000000000000000");
        out.println(ft.format(d));
    }
/**************************************Bit Manipulation**************************************************/
    static void printMask(long mask){
        System.out.println(Long.toBinaryString(mask));
    }
    static int countBit(int mask){
        int ans=0;
        while(mask!=0){
            if(mask%2==1){
                ans++;
            }
            mask/=2;
        }
        return ans;
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new HashSet[n];
        for(int i=0;i<n;i++){
            graph[i]=new HashSet<>();
        }
    }
    static void addEdge(int a,int b){
        graph[a].add(new Pair(b,1));
    }
    static void addEdge(int a,int b,int c){
        graph[a].add(new Pair(b,c));
    }
/*********************************************PAIR********************************************************/
    static class PairComp implements Comparator<Pair>{
        public int compare(Pair p1,Pair p2){
            return p1.u-p2.u;
        }
    }
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }
        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }
        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }
        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }
        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*******************************************************/
    static class PairCompL implements Comparator<Pairl>{
        public int compare(Pairl p1,Pairl p2){
            if(p1.u-p2.u<0){
                return -1;
            }
            else if(p1.u-p2.u>0){
                return 1;
            }
            else{
                if(p1.v-p2.v<0){
                    return -1;
                }
                else if(p1.v-p2.v>0){
                    return 1;
                }
                else{
                    return 0;
                }
            }
        }
    }
    static class Pairl implements Comparable<Pairl> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }

            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }

            public boolean equals(Object o) {
                Pairl other = (Pairl) o;
                return u == other.u && v == other.v;
            }

            public int compareTo(Pairl other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }

            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o) {
        if(!oj)
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y)
    {
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; // a is greater number
        b = (x < y) ? x : y; // b is smaller number
        r = b;
        while(a % b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/******************************************SIEVE**********************************************************/
    static void sieveMake(int n){
        sieve=new boolean[n];
        Arrays.fill(sieve,true);
        sieve[0]=false;
        sieve[1]=false;
        for(int i=2;i*i<n;i++){
            if(sieve[i]){
                for(int j=i*i;j<n;j+=i){
                    sieve[j]=false;
                }
            }
        }
        primes=new ArrayList<Integer>();
        for(int i=0;i<n;i++){
            if(sieve[i]){
                primes.add(i);
            }
        }
    }
/********************************************End***********************************************************/
}

//>>>BaZ<<<//
import java.util.*;
import java.io.*;
import static java.lang.Math.*;
public class Student
{
    static int dx[] = {-1,1,0,0};
    static int dy[] = {0,0,1,-1};
    static long MOD = 1000000007;
    static int INF = Integer.MAX_VALUE/10;
    static PrintWriter pw;
    static Reader scan;
    //static MyFileReader scan;
    //static MyFileReader1 ss;
    static int ni() throws IOException{return scan.nextInt();}
    static long nl() throws IOException{return scan.nextLong();}
    static double nd() throws IOException{return scan.nextDouble();}
    static void pl() throws IOException{pw.println();}
    static void pl(Object o) throws IOException{pw.println(o);}
    static void p(Object o) throws IOException {pw.print(o+" ");}
    static void psb(StringBuilder sb) throws IOException {pw.print(sb);}
    static Map<Integer,Long> dp = new HashMap();
    public static void main(String[] args){
        new Thread(null,null,"BaZ",99999999)
        {
            public void run()
            {
                try
                {
                    solve();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }
    static void solve() throws IOException
    {
        Calendar CAL1 = Calendar.getInstance();
        CAL1.setTime(new Date());
        scan = new Reader();
        //scan = new MyFileReader();
        //ss = new MyFileReader1();
        pw = new PrintWriter(System.out,true);
        //pw = new PrintWriter(new File("C://Users/Aman deep/Desktop/output.txt"));
        StringBuilder sb = new StringBuilder();
        int x = ni();
        int y = ni();
        if(y%x!=0)
            pl(0);
        else pl(f(y/x));
        Calendar CAL2 = Calendar.getInstance();
        CAL2.setTime(new Date());
        double Execution_Time = (double)(CAL2.getTimeInMillis()-CAL1.getTimeInMillis())/1000.000;
        //System.out.println("Execution time : "+Execution_Time+" seconds");
        pw.flush();
        pw.close();
    }
    static long f(int x)
    {
        if(x==1)
            return 1;
        if(dp.containsKey(x))
            return dp.get(x);
        long total = modpow(2,x-1);
        ArrayList<Integer> divisors = new ArrayList();
        for(int i=1;i*i<=x;++i)
        {
            if(x%i==0)
            {
                if(i!=1)
                    divisors.add(i);
                if(i*i!=x)
                    divisors.add(x/i);
            }
        }
        for(int e:divisors)
            total = (total-f(x/e)+MOD)%MOD;
        dp.put(x,total);
        return total;
    }
    static long modpow(long x,long y)
    {
        if(y==0)
            return 1;
        if((y&1)==0)
            return modpow((x*x)%MOD,y>>1);
        return (x*modpow(x,y-1))%MOD;
    }
    static boolean islong(double d)
    {
        return Math.ceil(d)==d;
    }
    static double roundLikeCpp(double d,double precision)
    {
        if(islong(d))
            return d;
        d*=(long)pow(10,precision+1);
        if(d%10==5)
            d--;
        return d/pow(10,precision+1);
    }
    static class Reader {
    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader() {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException {
        byte[] buf = new byte[64];
        int cnt = 0, c;
        while ((c = read()) != -1) {
            if (c == '\n') break;
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException {
        int ret = 0;
        byte c = read();
        while (c <= ' ') c = read();
        boolean neg = (c == '-');
        if (neg) c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg) return -ret;
        return ret;
    }

    public long nextLong() throws IOException {
        long ret = 0;
        byte c = read();
        while (c <= ' ') c = read();
        boolean neg = (c == '-');
        if (neg) c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg) return -ret;
        return ret;
    }

    public double nextDouble() throws IOException {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ') c = read();
        boolean neg = (c == '-');
        if (neg) c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (c == '.') while ((c = read()) >= '0' && c <= '9') ret += (c - '0') / (div *= 10);
        if (neg) return -ret;
        return ret;
    }

    private void fillBuffer() throws IOException {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1) buffer[0] = -1;
    }

    private byte read() throws IOException {
        if (bufferPointer == bytesRead) fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException {
        if (din == null) return;
        din.close();
    }
}
     static class MyFileReader                                          //File input template
    {
        StringTokenizer st;
        BufferedReader br;
        MyFileReader() throws IOException
        {
            br = new BufferedReader(new FileReader("C://Users/Aman deep/Desktop/input.txt"));
        }
        String nextLine() throws IOException
        {
            return br.readLine();
        }
        String next() throws IOException
        {
            if(st==null || !st.hasMoreTokens())
                st = new StringTokenizer(nextLine());
            return st.nextToken();
        }
        int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
    }
     static class MyFileReader1                                          //File input template
    {
        StringTokenizer st;
        BufferedReader br;
        MyFileReader1() throws IOException
        {
            br = new BufferedReader(new FileReader("C://Users/Aman deep/Desktop/output.txt"));
        }
        String nextLine() throws IOException
        {
            return br.readLine();
        }
        String next() throws IOException
        {
            if(st==null || !st.hasMoreTokens())
                st = new StringTokenizer(nextLine());
            return st.nextToken();
        }
        int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
    }
}

//>>>BaZ<<<//
import java.util.*;
import java.io.*;
import static java.lang.Math.*;
public class Main
{
    static int dx[] = {-1,1,0,0};
    static int dy[] = {0,0,1,-1};
    static long MOD = 1000000007;
    static int INF = Integer.MAX_VALUE/10;
    static PrintWriter pw;
    static Reader scan;
    //static MyFileReader scan;
    //static MyFileReader1 ss;
    static int ni() throws IOException{return scan.nextInt();}
    static long nl() throws IOException{return scan.nextLong();}
    static double nd() throws IOException{return scan.nextDouble();}
    static void pl() throws IOException{pw.println();}
    static void pl(Object o) throws IOException{pw.println(o);}
    static void p(Object o) throws IOException {pw.print(o+" ");}
    static void psb(StringBuilder sb) throws IOException {pw.print(sb);}
    static ArrayList<Integer> fact = new ArrayList();
    static Map<Integer,Long> dp = new HashMap();
    public static void main(String[] args){
        new Thread(null,null,"BaZ",99999999)
        {
            public void run()
            {
                try
                {
                    solve();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }
    static void solve() throws IOException
    {
        Calendar CAL1 = Calendar.getInstance();
        CAL1.setTime(new Date());
        scan = new Reader();
        //scan = new MyFileReader();
        //ss = new MyFileReader1();
        pw = new PrintWriter(System.out,true);
        //pw = new PrintWriter(new File("C://Users/Aman deep/Desktop/output.txt"));
        StringBuilder sb = new StringBuilder();
        int x = ni();
        int y = ni();
        if(y%x!=0)
            pl(0);
        else
        {
            y/=x;
            for(int i=1;i*i<=y;++i)
                if(y%i==0)
                {
                    fact.add(i);
                    if(i*i!=y)
                        fact.add(y/i);
                }
            pl(f(y));
        }
        Calendar CAL2 = Calendar.getInstance();
        CAL2.setTime(new Date());
        double Execution_Time = (double)(CAL2.getTimeInMillis()-CAL1.getTimeInMillis())/1000.000;
        //System.out.println("Execution time : "+Execution_Time+" seconds");
        pw.flush();
        pw.close();
    }
    static long f(int x)
    {
        if(x==1)
            return 1;
        if(dp.containsKey(x))
            return dp.get(x);
        long ans = modpow(2,x-1);
        for(int e:fact)
            if(x%e==0 && e!=1)
                ans = (ans-f(x/e)+MOD)%MOD;
        dp.put(x,ans);
        return ans;
    }
    static long modpow(long x,long y)
    {
        if(y==0)
            return 1;
        if((y&1)==0)
            return modpow((x*x)%MOD,y>>1);
        return (x*modpow(x,y-1))%MOD;
    }
    static boolean islong(double d)
    {
        return Math.ceil(d)==d;
    }
    static double roundLikeCpp(double d,double precision)
    {
        if(islong(d))
            return d;
        d*=(long)pow(10,precision+1);
        if(d%10==5)
            d--;
        return d/pow(10,precision+1);
    }
    static class Reader {
    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader() {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException {
        byte[] buf = new byte[64];
        int cnt = 0, c;
        while ((c = read()) != -1) {
            if (c == '\n') break;
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException {
        int ret = 0;
        byte c = read();
        while (c <= ' ') c = read();
        boolean neg = (c == '-');
        if (neg) c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg) return -ret;
        return ret;
    }

    public long nextLong() throws IOException {
        long ret = 0;
        byte c = read();
        while (c <= ' ') c = read();
        boolean neg = (c == '-');
        if (neg) c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg) return -ret;
        return ret;
    }

    public double nextDouble() throws IOException {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ') c = read();
        boolean neg = (c == '-');
        if (neg) c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (c == '.') while ((c = read()) >= '0' && c <= '9') ret += (c - '0') / (div *= 10);
        if (neg) return -ret;
        return ret;
    }

    private void fillBuffer() throws IOException {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1) buffer[0] = -1;
    }

    private byte read() throws IOException {
        if (bufferPointer == bytesRead) fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException {
        if (din == null) return;
        din.close();
    }
}
     static class MyFileReader                                          //File input template
    {
        StringTokenizer st;
        BufferedReader br;
        MyFileReader() throws IOException
        {
            br = new BufferedReader(new FileReader("C://Users/Aman deep/Desktop/input.txt"));
        }
        String nextLine() throws IOException
        {
            return br.readLine();
        }
        String next() throws IOException
        {
            if(st==null || !st.hasMoreTokens())
                st = new StringTokenizer(nextLine());
            return st.nextToken();
        }
        int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
    }
     static class MyFileReader1                                          //File input template
    {
        StringTokenizer st;
        BufferedReader br;
        MyFileReader1() throws IOException
        {
            br = new BufferedReader(new FileReader("C://Users/Aman deep/Desktop/output.txt"));
        }
        String nextLine() throws IOException
        {
            return br.readLine();
        }
        String next() throws IOException
        {
            if(st==null || !st.hasMoreTokens())
                st = new StringTokenizer(nextLine());
            return st.nextToken();
        }
        int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
    }
}

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import javax.print.attribute.HashAttributeSet;

/*
 public class _900D {

 }

 */
public class _900D {
  public void solve() throws FileNotFoundException {
    InputStream inputStream = System.in;

    InputHelper in = new InputHelper(inputStream);

    // actual solution
    int y = in.readInteger();
    int x = in.readInteger();

    if (x % y != 0) {
      System.out.println("0");
      return;
    }

    x /= y;

    List<Integer> pf = new ArrayList<Integer>();

    int ax = x;
    for (int i = 2; i * i <= ax; i++) {
      if (ax % i == 0) {
        pf.add(i);

        while (ax % i == 0) {
          ax /= i;
        }
      }
    }
    if (ax > 1) {
      pf.add(ax);
    }

    int bn = (1 << pf.size());

    long ans = 0;
    for (int i = 0; i < bn; i++) {

      int cnt = 0;
      int nx = x;
      for (int j = 0; j < pf.size(); j++) {
        if (((1 << j) & i) != 0) {
          cnt++;
          nx /= pf.get(j);
        }
      }

      if (cnt % 2 == 0) {
        ans += pow(nx - 1);
        ans %= mod;
      } else {
        ans -= pow(nx - 1);
        ans += mod;
        ans %= mod;
      }
    }

    System.out.println(ans);
    // end here
  }

  int mod = (int) 1e9 + 7;

  long pow(int t) {
    if (t == 0) {
      return 1;
    }

    long ans = pow(t / 2);

    if (t % 2 == 0) {
      return (ans * ans) % mod;
    } else {
      return (ans * ans * 2) % mod;
    }
  }

  public static void main(String[] args) throws FileNotFoundException {
    (new _900D()).solve();
  }

  class InputHelper {
    StringTokenizer tokenizer = null;
    private BufferedReader bufferedReader;

    public InputHelper(InputStream inputStream) {
      InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
      bufferedReader = new BufferedReader(inputStreamReader, 16384);
    }

    public String read() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          String line = bufferedReader.readLine();
          if (line == null) {
            return null;
          }
          tokenizer = new StringTokenizer(line);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      return tokenizer.nextToken();
    }

    public Integer readInteger() {
      return Integer.parseInt(read());
    }

    public Long readLong() {
      return Long.parseLong(read());
    }
  }
}

import java.util.*;

import javax.security.auth.kerberos.KerberosKey;
import javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener;

import java.awt.font.GraphicAttribute;
import java.io.*;
import java.nio.channels.AcceptPendingException;
import java.time.Period;

public class Main {

	public static void main(String[] args) throws Exception {
            int x=sc.nextInt();
            int y=sc.nextInt();
            if(y%x!=0) {
            	pw.println(0);

            }else {
            	int num=y/x;
            	primeFactors(num);
            	if(primefact.size()==0) {
            		pw.println(1);
            	}else if(primefact.size()==1&&primefact.firstEntry().getValue()==1) {
            		pw.println((Pow(2, num-1, 1000000007)+1000000007-1)%1000000007);
            	}else {
                int subtract=0;
            	int[]z=new int[primefact.size()];
            	int j=0;
            	for(int i:primefact.keySet()) {
            		z[j]=i;
            		j++;
            	}
            	for(int i=1;i<(1<<z.length);i++) {
            		int subsubtrac=1;
            		int n=0;
            	for(j=0;j<32;j++) {
            		if(((i>>j)&1)==1) {
            			subsubtrac*=z[j];
            			n++;
            		}

            	}
            	if(n%2==1) {
            		subtract+=Pow(2, (num/subsubtrac)-1, 1000000007);
            	}else {
					subtract-=Pow(2,(num/subsubtrac)-1, 1000000007);
				}

            	subtract=subtract%1000000007;
            	//pw.println(subtract);

            	}
            //	pw.println(Arrays.toString(z));
            	pw.print((Pow(2, num-1, 1000000007)+1000000007-subtract)%1000000007);
            	}
            }

		pw.close();
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(FileReader r) {
			br = new BufferedReader(r);
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}
		public long[] nextLongArray(int n) throws IOException {
            long[] a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = nextLong();
            return a;
        }
		public int[] nextIntArray(int n) throws IOException {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }
		public Integer[] nextIntegerArray(int n) throws IOException {
            Integer[] a = new Integer[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }
		public boolean ready() throws IOException {
			return br.ready();
		}

	}

	static class pair implements Comparable<pair> {
		int x;
		int y;

		public pair(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return x + " " + y;
		}
		public boolean equals(Object o) {
            if (o instanceof pair) {
                pair p = (pair)o;
                return p.x == x && p.y == y;
            }
            return false;
        }
        public int hashCode() {
            return new Double(x).hashCode() * 31 + new Double(y).hashCode();
        }
        public int compareTo(pair other) {
        	if(this.x==other.x) {
        		return Long.compare(this.y, other.y);
        	}
			return Long.compare(other.x, this.x);
		}
	}

	static class tuble implements Comparable<tuble> {
		int x;
		int y;
		int z;

		public tuble(int x, int y, int z) {
			this.x = x;
			this.y = y;
			this.z = z;
		}

		public String toString() {
			return x + " " + y + " " + z;
		}

		public int compareTo(tuble other) {
			if (this.x == other.x) {
				return this.y - other.y;
			} else {
				return this.x - other.x;
			}
		}
	}

	public static long GCD(long a, long b) {
		if (b == 0)
			return a;
		if (a == 0)
			return b;
		return (a > b) ? GCD(a % b, b) : GCD(a, b % a);
	}

	public static long LCM(long a, long b) {
		return a * b / GCD(a, b);
	}

	static long Pow(long a, long e, long mod) // O(log e)
	{
		a %= mod;
		long res = 1l;
		while (e > 0) {
			if ((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1l;
		}
		return res;
	}

	static long nc(int n, int r) {
		if (n < r)
			return 0;
		long v = fac[n];
		v *= Pow(fac[r], mod - 2, mod);
		v %= mod;
		v *= Pow(fac[n - r], mod - 2, mod);
		v %= mod;
		return v;
	}

	public static boolean isprime(long a) {
		if (a == 0 || a == 1) {
			return false;
		}
		if (a == 2) {
			return true;
		}
		for (int i = 2; i < Math.sqrt(a) + 1; i++) {
			if (a % i == 0) {
				return false;
			}
		}
		return true;
	}

	public static boolean isPal(String s) {
		boolean t = true;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
				t = false;
				break;
			}
		}
		return t;
	}

	public static long RandomPick(long[] a) {
		int n = a.length;
		int r = rn.nextInt(n);
		return a[r];
	}

	public static int RandomPick(int[] a) {
		int n = a.length;
		int r = rn.nextInt(n);
		return a[r];
	}

	public static void PH(String s, boolean reverse) {
		prelen = s.length();
		HashsArray[HashsArrayInd] = new int[prelen + 1];
		prepow = new int[prelen];
		if (HashsArrayInd == 0) {
			int[] mods = { 1173017693, 1173038827, 1173069731, 1173086977, 1173089783, 1173092147, 1173107093,
					1173114391, 1173132347, 1173144367, 1173150103, 1173152611, 1173163993, 1173174127, 1173204679,
					1173237343, 1173252107, 1173253331, 1173255653, 1173260183, 1173262943, 1173265439, 1173279091,
					1173285331, 1173286771, 1173288593, 1173298123, 1173302129, 1173308827, 1173310451, 1173312383,
					1173313571, 1173324371, 1173361529, 1173385729, 1173387217, 1173387361, 1173420799, 1173421499,
					1173423077, 1173428083, 1173442159, 1173445549, 1173451681, 1173453299, 1173454729, 1173458401,
					1173459491, 1173464177, 1173468943, 1173470041, 1173477947, 1173500677, 1173507869, 1173522919,
					1173537359, 1173605003, 1173610253, 1173632671, 1173653623, 1173665447, 1173675577, 1173675787,
					1173684683, 1173691109, 1173696907, 1173705257, 1173705523, 1173725389, 1173727601, 1173741953,
					1173747577, 1173751499, 1173759449, 1173760943, 1173761429, 1173762509, 1173769939, 1173771233,
					1173778937, 1173784637, 1173793289, 1173799607, 1173802823, 1173808003, 1173810919, 1173818311,
					1173819293, 1173828167, 1173846677, 1173848941, 1173853249, 1173858341, 1173891613, 1173894053,
					1173908039, 1173909203, 1173961541, 1173968989, 1173999193};
			mod = RandomPick(mods);
			int[] primes = { 59, 61, 67, 71, 73, 79, 83, 89, 97, 101 };
			prime = RandomPick(primes);
		}
		prepow[0] = 1;
		if (!reverse) {

			for (int i = 1; i < prelen; i++) {
				prepow[i] = (int) ((1l * prepow[i - 1] * prime) % mod);

			}
			for (int i = 0; i < prelen; i++) {
				if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z')
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'a' + 1) * prepow[i]) % mod) % mod);
				else
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'A' + 27) * prepow[i]) % mod) % mod);
			}

		} else {
			for (int i = 1; i < prelen; i++) {
				prepow[i] = (int) ((1l * prepow[i - 1] * prime) % mod);

			}
			for (int i = 0; i < prelen; i++) {
				if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z')
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'a' + 1) * prepow[prelen - 1 - i]) % mod) % mod);
				else
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'A' + 27) * prepow[prelen - 1 - i]) % mod) % mod);
			}

		}

		HashsArrayInd++;

	}

	public static int PHV(int l, int r, int n, boolean reverse) {
		if (l > r) {
			return 0;
		}
		int val = (int) ((1l * HashsArray[n - 1][r] + mod - HashsArray[n - 1][l - 1]) % mod);
		if (!reverse) {

			val = (int) ((1l * val * prepow[prelen - l]) % mod);
		} else {
			val = (int) ((1l * val * prepow[r - 1]) % mod);
		}
		return val;
	}

    public static void genprime(int n) {
    	 boolean prime[] = new boolean[n+1];
         for(int i=0;i<n;i++)
             prime[i] = true;

         for(int p = 2; p*p <=n; p++)
         {
             if(prime[p] == true)
             {
                 for(int i = p*p; i <= n; i += p)
                     prime[i] = false;
             }
         }
         for(int i = 2; i <= n; i++)
         {
             if(prime[i] == true) {
                primes.put(i,primes.size());
                primes2.put(primes2.size(),i);
             }

         }
    }

    public static void primeFactors(int n)
    {
        while (n % 2 == 0) {
            primefact.put(2,primefact.getOrDefault(2, 0)+1);
            n /= 2;
        }

        for (int i = 3; i <= Math.sqrt(n); i += 2) {
            while (n % i == 0) {
                primefact.put(i,primefact.getOrDefault(i, 0)+1);
                n /= i;
            }
        }

        if (n > 2)
            primefact.put(n,primefact.getOrDefault(n, 0)+1);
    }
    public static long LSB(long x) {
		return x&-x;
	}
	static class fenwick {
		long[] arr;
		public fenwick(int[] a) {
			arr=new long[a.length+1];
			for(int i=1;i<=a.length;i++) {
				arr[i]+=a[i-1];
				if(i+LSB(i)<=a.length) {
					arr[(int) (i+LSB(i))]+=arr[i];
				}
			}
		}public fenwick(long[] a) {
			arr=new long[a.length+1];
			for(int i=1;i<=a.length;i++) {
				arr[i]+=a[i];
				if(i+LSB(i)<=a.length) {
					arr[(int) (i+LSB(i))]+=arr[i];
				}
			}
		}
		public void update(int ind,long x) {
			int i=ind;
			while(i<arr.length) {
				arr[i]+=x;
				i+=LSB(i);
			}
		}
		public long PrefixSum(int ind) {
			long sum=0;
			int i=ind;
			while(i>0) {
				sum+=arr[i];
				i=(int) (i-LSB(i));
			}
			return sum;
		}
		public long RangeQuerey(int l,int r) {
			return  this.PrefixSum(r+1)-this.PrefixSum(l);
		}
	}
	static TreeMap<Integer,Integer>primes=new TreeMap<Integer, Integer>();
	static TreeMap<Integer,Integer>primes2=new TreeMap<Integer, Integer>();
    static TreeMap<Integer,Integer>primefact=new TreeMap<Integer, Integer>();
	static int[][] HashsArray;
	static int HashsArrayInd = 0;
	static int[] prepow;
	static int prelen = 0;
	static int prime = 61;
	static long fac[];
	static int mod = 1000000007;
	static Random rn = new Random();
	static Scanner sc = new Scanner(System.in);
	static PrintWriter pw = new PrintWriter(System.out);
}

//package round450;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int x = ni(), y = ni();
		if(y % x != 0){
			out.println(0);
			return;
		}

		// a(n) = sum_{d|n} mu(n/d)*2^(d-1)
		int[] primes = sieveEratosthenes(100000);
		y /= x;
		long ret = 0;
		int mod = 1000000007;
		for(int d = 1;d * d <= y;d++){
			if(y % d == 0){
				ret += mobius(y/d, primes) * pow(2, d-1, mod);
				ret %= mod;
				if(d*d < y){
					ret += mobius(d, primes) * pow(2, y/d-1, mod);
					ret %= mod;
				}
			}
		}
		if(ret < 0)ret += mod;
		out.println(ret);

//		dfs(y/x, 0);
//		tr(ct);
	}

	public static long pow(long a, long n, long mod) {
		//		a %= mod;
		long ret = 1;
		int x = 63 - Long.numberOfLeadingZeros(n);
		for (; x >= 0; x--) {
			ret = ret * ret % mod;
			if (n << 63 - x < 0)
				ret = ret * a % mod;
		}
		return ret;
	}

	public static int mobius(long n, int[] primes)
	{
		int mob = 1;
		for(int p : primes){
			if((long)p*p > n)break;
			if(n % ((long)p*p) == 0)return 0;
			if(n % p == 0){
				while(n % p == 0)n /= p;
				mob = -mob;
			}
		}
		if(n != 1)mob = -mob;
		return mob;
	}

	public static int[] sieveEratosthenes(int n) {
		if (n <= 32) {
			int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
			for (int i = 0; i < primes.length; i++) {
				if (n < primes[i]) {
					return Arrays.copyOf(primes, i);
				}
			}
			return primes;
		}

		int u = n + 32;
		double lu = Math.log(u);
		int[] ret = new int[(int) (u / lu + u / lu / lu * 1.5)];
		ret[0] = 2;
		int pos = 1;

		int[] isnp = new int[(n + 1) / 32 / 2 + 1];
		int sup = (n + 1) / 32 / 2 + 1;

		int[] tprimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
		for (int tp : tprimes) {
			ret[pos++] = tp;
			int[] ptn = new int[tp];
			for (int i = (tp - 3) / 2; i < tp << 5; i += tp)
				ptn[i >> 5] |= 1 << (i & 31);
			for (int j = 0; j < sup; j += tp) {
				for (int i = 0; i < tp && i + j < sup; i++) {
					isnp[j + i] |= ptn[i];
				}
			}
		}

		// 3,5,7
		// 2x+3=n
		int[] magic = { 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, 31, 22, 28, 18, 26, 10, 7, 12, 21, 17,
				9, 6, 16, 5, 15, 14 };
		int h = n / 2;
		for (int i = 0; i < sup; i++) {
			for (int j = ~isnp[i]; j != 0; j &= j - 1) {
				int pp = i << 5 | magic[(j & -j) * 0x076be629 >>> 27];
				int p = 2 * pp + 3;
				if (p > n)
					break;
				ret[pos++] = p;
				if ((long) p * p > n)
					continue;
				for (int q = (p * p - 3) / 2; q <= h; q += p)
					isnp[q >> 5] |= 1 << q;
			}
		}

		return Arrays.copyOf(ret, pos);
	}

	int ct = 0;

	void dfs(int rem, int g)
	{
		if(rem == 0){
			if(g == 1)ct++;
			return;
		}
		for(int i = 1;i <= rem;i++){
			dfs(rem-i, gcd(g, i));
		}
	}

	public static int gcd(int a, int b) {
		while (b > 0) {
			int c = a;
			a = b;
			b = c % b;
		}
		return a;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new D().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

public final class round_450_b
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long mod=(long)(1e9+7);

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

    public static void main(String args[]) throws Exception
    {
		long x=sc.nextLong(),y=sc.nextLong();

		List<Long> divs=new ArrayList<>();

		for(long i=1;i*i<=y;i++)
		{
			if(y%i==0)
			{
				divs.add(i);

				if(i!=(y/i))
				{
					divs.add(y/i);
				}
			}
		}

		if(y%x!=0)
		{
			out.println(0);
		}

		else
		{
			List<Pair> list=new ArrayList<>();

			for(long z:divs)
			{
				if(z>=x)
				{
					long now=pow(2,(y/z)-1);

					list.add(new Pair(z,now));
				}
			}

			Collections.sort(list);

			for(int i=list.size()-1;i>=0;i--)
			{
				long now=list.get(i).val;

				for(int j=i+1;j<list.size();j++)
				{
					if(list.get(j).idx%list.get(i).idx==0)
					{
						now=(now-list.get(j).val+mod)%mod;
					}
				}

				Pair p=new Pair(list.get(i).idx,now);

				list.set(i,p);
			}

			out.println(list.get(0).val);
		}

		out.close();
    }

	private static class Pair implements Comparable<Pair>
	{
		long idx,val;

		public Pair(long idx,long val)
		{
			this.idx=idx;this.val=val;
		}

		public int compareTo(Pair x)
		{
			return Long.compare(this.idx,x.idx);
		}
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

import java.io.*;
import java.util.*;
import java.math.BigInteger;

public class D {

	// gcd(a_1, a_2, ...) = x
	// so all a_i values are multiples of x:
	//    a_i = b_i * x for some b_i >= 1
	// But there can't be a common factor in b_i ! So gcd(b_i) must be 1.
	// sum a_i = y
	//    sum a_i = x * sum b_i = y
	//    sum b_i = y/x (if x divides y)
	// So, given y/x = c.
	// Take sequences of length 1, 2, ...:
	// length 1: c  WRONG if c > 1, because gcd(b_i) = c > 1
	// length 2:
	//     1, c-1
	//     2, c-2   Only ok if gcd(2,c-2) = 1
	//     ...
	//     c/2, c-c/2
	// length 3:
	//     1, 1, c-2
	//     1, 2, c-3
	//     ...
	//     1, (c-1)/2, c-1-(c-1)/2
	//     2, 2, c-4
	//     2, 3, c-5
	//     ...
	//     2, (c-2)/2, c-2-(c-2)/2
	// If ok, add number of permutations
	// Let's look at it differently:
	//   total number of distributions of y = t(y) = 2^(y-1)
	//   now number of distributions of y with gcd 1 = d(y)
	//       total number of distributions - distributions with gcd > 1
	// distributions with gcd > 1   = SUM_g distributions of y with gcd g = SUM_g d(y/g)   where g divides y, g > 1
	//       suppose y=5, gcd=3, 3 does not divide 5, that could never work.
	// distributions of y with gcd g = distributions of y/g with gcd 1 = d(y/g)
	// so d(y) = 2^(y-1) - SUM_g|y d(y/g)
	// d(1) = 2^0 - 0 = 1                          -> 1
	// d(2) = 2^1 - [d(1)] = 2 - 1 = 1             -> 1+1
	// d(3) = 2^2 - [d(1)] = 4 - 1 = 3             -> 1+2, 2+1, 1+1+1
	// d(4) = 2^3 - [d(2)+d(1)] = 8 - 1 - 1 = 6    -> 1+3, 3+1, 1+1+2, 1+2+1, 2+1+1, 1+1+1+1

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(System.in)));

		int x = sc.nextInt();
		int y = sc.nextInt();

		if (y%x != 0) {
			System.out.println("0");
		} else {
			y = y/x;
			int result = getD(y);
			System.out.println(result+"");
		}
	}

	private static List<Integer> getDivisors(int a) {
		int sqrt = (int)Math.floor(Math.sqrt(a));
		ArrayList<Integer> result = new ArrayList<>();
		for (int i=1; i <= sqrt; i++) {
			if (a%i==0) {
				result.add(i);
				if (i != (a/i)) result.add(a/i);
			}
		}
		Collections.sort(result);
		//System.out.println(String.format("%d -> %s", a, result));
		return result;
	}

	private static HashMap<Integer, Integer> d = new HashMap<>();
	private static int m = 1_000_000_007;
	private static BigInteger M = new BigInteger(m+"");
	private static BigInteger TWO = new BigInteger(2+"");

	private static int getD(int a) {
		if (d.containsKey(a)) return d.get(a);

		int result = pow(a-1);
		for (int g : getDivisors(a)) {
			if (g > 1) {
				result = result - getD(a/g);
				result = ((result%m)+m)%m;
			}
		}

		d.put(a, result);
		//System.out.println(String.format("%d -> %d", a, result));
		return result;
	}

	private static int pow(int a) {
		int result = TWO.modPow(new BigInteger(a+""), M).intValue();
		//System.out.println(String.format("%d -> %d", a, result));
		return result;
	}

}

import java.io.*;
import java.util.*;

public class Prob_900D {

	static final int TEST_CASES = 2;
	static HashMap<Long, Long> func;
	static final long MOD = 1000000007L;

	public static void main(String[] args) {

//		test(TEST_CASES);

		Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
		solve(sc);
		sc.close();

	}

	static void test(int T) {

		for (int i = 0; i < T; ++i) {
			System.out.println(String.format("*****Case #%d*****", i));
			try {
				Scanner sc = new Scanner(new FileReader(String.format("LessThan1000Solved/%d.in", i)));
				solve(sc);
				sc.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

	}

	static void solve(Scanner sc) {

		long x = sc.nextLong();
		long y = sc.nextLong();

		if (x > y || y % x != 0) {
			System.out.println("0");
			return;
		}

		func = new HashMap<Long, Long>();
		func.put(0L, 1L);
		func.put(1L, 1L);

		System.out.println(getVal(y/x));

	}

	static long getVal(long v) {

		if (func.containsKey(v))
			return func.get(v);

		long ans = twoToPow(v - 1L) - 1L;

		for (long u = 2L; u * u <= v; ++u) {

			if (v % u != 0)
				continue;

			ans -= getVal(u);
			if (u * u != v)
				ans -= getVal(v / u);

			ans = ans % MOD;

		}

		ans = (ans + MOD) % MOD;
		func.put(v, ans);
		return ans;

	}

	static long twoToPow(long pow) {
		if (pow == 0)
			return 1;
		if (pow == 1)
			return 2;

		long sub = twoToPow(pow / 2);

		if (pow % 2 == 0)
			return (sub * sub) % MOD;
		else
			return (sub * sub * 2) % MOD;

	}

}

import java.util.*;
import java.io.*;

public class CFA {
  BufferedReader br;
  PrintWriter out;
  StringTokenizer st;
  boolean eof;
  private static final long MOD = 1000L * 1000L * 1000L + 7;
  private static final int[] dx = {0, -1, 0, 1};
  private static final int[] dy = {1, 0, -1, 0};
  private static final String yes = "Yes";
  private static final String no = "No";

  void solve() {
//    int T = nextInt();
    int T = 1;
    for (int i = 0; i < T; i++) {
      helper();
    }
  }

  void helper() {
    // https://codeforces.com/contest/900/problem/D
    int x = nextInt();
    int y = nextInt();
    if (y % x != 0) {
      outln(0);
      return;
    } else if (y == x) {
      outln(1);
      return;
    }

    int div = y / x;
    List<Integer> fact = new ArrayList<>();
    for (int i = 1; i * i <= div; i++) {
      if (div % i == 0) {
        if (i * i == div) {
          fact.add(i);
        } else {
          fact.add(i);
          fact.add(div / i);
        }
      }
    }

    long res = 0;
    for (int v : fact) {
      List<Integer> factors = primeFactor(v);
      long tmp = 1;
      for (int t : factors) {
        tmp = tmp * t;
      }
      if (tmp != v) {
        continue;
      }
      if (factors.size() % 2 == 0) {
        res += powMod(2, div / v - 1, MOD);
        res = res % MOD;
      } else {
        res -= powMod(2, div / v - 1, MOD);
        res += MOD;
        res = res % MOD;
      }
    }
    outln(res);
  }

  List<Integer> primeFactor(int v) {
    Set<Integer> ls = new HashSet<>(factor(v));
    return new ArrayList<>(ls);
  }

  public boolean isPrime(int val) {
    for (int i = 2; i * i <= val; i++) {
      if (val % i == 0) {
        return false;
      }
    }
    return true;
  }

  // factorization of a long num
  public List<Integer> factor(int N) {
    List<Integer> res = new ArrayList<>();
    for (int i = 2; i * i <= N; i++) {
      while (N % i == 0) {
        res.add(i);
        N = N / i;
      }
    }
    if (N != 1L) {
      res.add(N);
    }

    return res;
  }

  // Power Calculate N^M % MOD, N and M can be long (up to 2^64, ~10^18)
  public long powMod(long N, long M, long MOD){//N^M % MOD
    if(M == 0L)
      return 1L;
    long[] hp = new long[64];
    boolean[] bp = new boolean[64];
    hp[0] = N;
    for(int i = 1; i < hp.length; i++) {
      hp[i] = (hp[i - 1] * hp[i - 1]) % MOD;
    }
    for(int j = 0; j < hp.length; j++) {
      if((M & (1L << j)) != 0)
        bp[j] = true;
    }
    long res = 1;
    for(int i = 0;i < bp.length; i++){
      if(bp[i]) {
        res = (res * hp[i]) % MOD;
      }
    }
    return res;
  }

  void shuffle(long[] a) {
    int n = a.length;
    for(int i = 0; i < n; i++) {
      int r = i + (int) (Math.random() * (n - i));
      long tmp = a[i];
      a[i] = a[r];
      a[r] = tmp;
    }
  }

  int gcd(int a, int b) {
    while(a != 0 && b != 0) {
      int c = b;
      b = a % b;
      a = c;
    }
    return a + b;
  }
  private void outln(Object o) {
    out.println(o);
  }
  private void out(Object o) {
    out.print(o);
  }
  private void formatPrint(double val) {
    outln(String.format("%.9f%n", val));
  }
  public CFA() {
    br = new BufferedReader(new InputStreamReader(System.in));
    out = new PrintWriter(System.out);
    solve();
    out.close();
  }
  public static void main(String[] args) {
    new CFA();
  }

  public long[] nextLongArr(int n) {
    long[] res = new long[n];
    for(int i = 0; i < n; i++)
      res[i] = nextLong();
    return res;
  }
  public int[] nextIntArr(int n) {
    int[] res = new int[n];
    for(int i = 0; i < n; i++)
      res[i] = nextInt();
    return res;
  }
  public String nextToken() {
    while (st == null || !st.hasMoreTokens()) {
      try {
        st = new StringTokenizer(br.readLine());
      } catch (Exception e) {
        eof = true;
        return null;
      }
    }
    return st.nextToken();
  }
  public String nextString() {
    try {
      return br.readLine();
    } catch (IOException e) {
      eof = true;
      return null;
    }
  }
  public int nextInt() {
    return Integer.parseInt(nextToken());
  }
  public long nextLong() {
    return Long.parseLong(nextToken());
  }
  public double nextDouble() {
    return Double.parseDouble(nextToken());
  }
}

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.InputMismatchException;
import java.util.List;

public class Main {

	private static final String NO = "NO";
	private static final String YES = "YES";
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	private static final long MOD = 1000000007;

	void solve() {
		int T = 1;
		for (int i = 0; i < T; i++)
			solve(i);
	}

	void solve(int T) {
		int n = ni();
		int y = ni();
		if (y % n != 0) {
			out.print(0);
			return;
		}
		y /= n;

		List<Integer> l = new ArrayList<Integer>();
		for (int i = 1; i * i <= y; i++) {
			if (y % i == 0) {
				l.add(i);
				if (i * i != y)
					l.add(y / i);
			}
		}
		Collections.sort(l);
		long ans = 0;
		long dp[] = new long[l.size()];
		for (int i = l.size() - 1; i >= 0; i--) {
			dp[i] = power(2, y / l.get(i) - 1);
			for (int j = l.size() - 1; j > i; j--)
				if (l.get(j) % l.get(i) == 0)
					dp[i] -= dp[j];
			dp[i] %= MOD;
		}
		out.println((dp[0] + MOD) % MOD);
	}

	// a^b
	long power(long a, long b) {
		long x = 1, y = a;
		while (b > 0) {
			if (b % 2 != 0) {
				x = (x * y) % MOD;
			}
			y = (y * y) % MOD;
			b /= 2;
		}
		return x % MOD;
	}

	private long gcd(long a, long b) {
		while (a != 0) {
			long tmp = b % a;
			b = a;
			a = tmp;
		}
		return b;
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;
	private boolean vis[];

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n) {
			if (!(isSpaceChar(b)))
				buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private List<Integer> na2(int n) {
		List<Integer> a = new ArrayList<Integer>();
		for (int i = 0; i < n; i++)
			a.add(ni());
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long[] nl(int n) {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = nl();
		return a;
	}

	private long[][] nl(int n, int m) {
		long[][] a = new long[n][];
		for (int i = 0; i < n; i++)
			a[i] = nl(m);
		return a;
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}

	public class Pair<K, V> {

		/**
		 * Key of this Pair.
		 */
		private K key;

		/**
		 * Gets the key for this pair.
		 *
		 * @return key for this pair
		 */
		public K getKey() {
			return key;
		}

		/**
		 * Value of this this Pair.
		 */
		private V value;

		/**
		 * Gets the value for this pair.
		 *
		 * @return value for this pair
		 */
		public V getValue() {
			return value;
		}

		/**
		 * Creates a new pair
		 *
		 * @param key   The key for this pair
		 * @param value The value to use for this pair
		 */
		public Pair(K key, V value) {
			this.key = key;
			this.value = value;
		}

		/**
		 *

		 * String representation of this Pair.
		 *

		 *
		 *

		 * The default name/value delimiter '=' is always used.
		 *

		 *
		 * @return String representation of this Pair
		 */
		@Override
		public String toString() {
			return key + "=" + value;
		}

		/**
		 *

		 * Generate a hash code for this Pair.
		 *

		 *
		 *

		 * The hash code is calculated using both the name and the value of the
		 * Pair.
		 *

		 *
		 * @return hash code for this Pair
		 */
		@Override
		public int hashCode() {
			// name's hashCode is multiplied by an arbitrary prime number (13)
			// in order to make sure there is a difference in the hashCode between
			// these two parameters:
			// name: a value: aa
			// name: aa value: a
			return key.hashCode() * 13 + (value == null ? 0 : value.hashCode());
		}

		/**
		 *

		 * Test this Pair for equality with another Object.
		 *

		 *
		 *

		 * If the Object to be tested is not a Pair or is
		 * null, then this method returns false.
		 *

		 *
		 *

		 * Two Pairs are considered equal if and only if both the names and
		 * values are equal.
		 *

		 *
		 * @param o the Object to test for equality with this
		 *          Pair
		 * @return true if the given Object is equal to this
		 *         Pair else false
		 */
		@Override
		public boolean equals(Object o) {
			if (this == o)
				return true;
			if (o instanceof Pair) {
				Pair pair = (Pair) o;
				if (key != null ? !key.equals(pair.key) : pair.key != null)
					return false;
				if (value != null ? !value.equals(pair.value) : pair.value != null)
					return false;
				return true;
			}
			return false;
		}
	}

}

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:b>=a?gcd(b%a,a):gcd(b,a);
	}
	ArrayList<Integer> rec=new ArrayList<>();
	HashMap<Integer,Long> map=new HashMap<>();
	void work() {
		int a=in.nextInt(),b=in.nextInt();
		if(b%a!=0) {
			out.println(0);
			return;
		}
		b/=a;
		if(b==1) {
			out.println(1);
			return;
		}
		for(int i=2;i*i<=b;i++) {
			if(b%i==0) {
				rec.add(i);
				if(i!=b/i)rec.add(b/i);
			}
		}
		out.println(find(b));
	}
	private long find(int b) {
		if(map.get(b)!=null)return map.get(b);
		long r=(pow(2,b-1)-1+mod)%mod;
		for(int k:rec) {
			if(b%k==0) {
				r-=find(b/k);
				r=(r+mod)%mod;
			}
		}
		map.put(b,r);
		return r;
	}
	private long pow(long a, long b) {
		long r=1;
		while(b>0) {
			if(b%2==1) {
				r*=a;
				r%=mod;
			}
			b/=2;
			a*=a;
			a%=mod;
		}
		return r;
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt()
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

import java.io.*;
import java.util.*;
import java.math.BigInteger;
import java.util.Map.Entry;

import static java.lang.Math.*;

public class D extends PrintWriter {

    long mod = 1_000_000_000 + 7;

    long solve(int d, int b) {

        return ((mu(b) + mod) % mod * pow(2, d - 1)) % mod;
    }

    long solve(int sum) {

        long ans = 0;

        for (int d = 1; d * d <= sum; d++) {
            if (sum % d == 0) {
                int b = sum / d;
                ans = (ans + solve(d, b)) % mod;
                if (b != d) {
                    ans = (ans + solve(b, d)) % mod;
                }
            }
        }

        return ans;
    }

    int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    long pow(long a, long b) {
        long c = 1;

        for (; b > 0; b /= 2) {
            if (b % 2 == 1) {
                c = (c * a) % mod;
            }
            a = (a * a) % mod;
        }

        return c;
    }

    int mu(int num) {
        int cnt = 1;

        for (int d = 2; d * d <= num; d++) {
            int cur = 0;

            while (num % d == 0) {
                ++cur;
                num /= d;
            }

            if (cur > 1) {
                return 0;
            }

            if (cur == 1) {
                ++cnt;
            }
        }

        if (num > 1) {
            ++cnt;
        }

        return (cnt % 2) * 2 - 1;
    }

    void run() {

        int x = nextInt(), y = nextInt();
        if (y % x == 0) {
            println(solve(y / x));
        } else {
            println(0);
        }
    }

    boolean skip() {
        while (hasNext()) {
            next();
        }
        return true;
    }

    int[][] nextMatrix(int n, int m) {
        int[][] matrix = new int[n][m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                matrix[i][j] = nextInt();
        return matrix;
    }

    String next() {
        while (!tokenizer.hasMoreTokens())
            tokenizer = new StringTokenizer(nextLine());
        return tokenizer.nextToken();
    }

    boolean hasNext() {
        while (!tokenizer.hasMoreTokens()) {
            String line = nextLine();
            if (line == null) {
                return false;
            }
            tokenizer = new StringTokenizer(line);
        }
        return true;
    }

    int[] nextArray(int n) {
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = nextInt();
        }
        return array;
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException err) {
            return null;
        }
    }

    public D(OutputStream outputStream) {
        super(outputStream);
    }

    static BufferedReader reader;
    static StringTokenizer tokenizer = new StringTokenizer("");
    static Random rnd = new Random();
    static boolean OJ;

    public static void main(String[] args) throws IOException {
        OJ = System.getProperty("ONLINE_JUDGE") != null;
        D solution = new D(System.out);
        if (OJ) {
            reader = new BufferedReader(new InputStreamReader(System.in));
            solution.run();
        } else {
            reader = new BufferedReader(new FileReader(new File(D.class.getName() + ".txt")));
            long timeout = System.currentTimeMillis();
            while (solution.hasNext()) {
                solution.run();
                solution.println();
                solution.println("----------------------------------");
            }
            solution.println("time: " + (System.currentTimeMillis() - timeout));
        }
        solution.close();
        reader.close();
    }
}

import javafx.util.Pair;

import java.io.*;
import java.util.*;

public class codeforces450D {
    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        TaskD solver = new TaskD();
        solver.solve(in, out);
        out.close();
    }

    static class TaskD {
        public void solve(InputReader in, PrintWriter out) {
            int x = in.nextInt();
            int y = in.nextInt();
            int MOD = (int) 1e9 + 7;
            HashMap<Integer, Integer> memo = new HashMap<>();
            if(y%x != 0){
                out.println("0");
            }else {
                out.println(solve(y/x, MOD, memo));
            }
        }

        ArrayList<Integer> divisors(int y){
            ArrayList<Integer> divisors = new ArrayList<>();
            for(int i = 1; i*i<=y; i++){
                if(y%i==0){
                    divisors.add(i);
                    if(i*i != y){
                        divisors.add(y/i);
                    }
                }
            }
            return divisors;
        }

        public int solve(int y, int MOD, HashMap<Integer, Integer> memo){
            if(memo.containsKey(y)) {
                return memo.get(y);
            }
            int sum = (int) calc(2,y-1,MOD);
            ArrayList<Integer> divisors = divisors(y);
            for(int d : divisors){
                if(d != 1) {
                    sum -= solve(y/d, MOD, memo);
                    if (sum < 0) sum += MOD;
                }
            }
            memo.put(y, sum);
            return sum;
        }

        //calculates 2^exponent % p very efficient
        public static long calc(int base, int exponent, int p) {
            if (exponent == 0) return 1;
            if (exponent == 1) return base % p;
            long m = calc(base, exponent >> 1, p);
            if (exponent % 2 == 0) return (m * m) % p;
            return 1L * base * m  % p * m % p;
        }
    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer stt;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
        }

        public String nextLine() {
            try {
                return reader.readLine();
            } catch (IOException e) {
                return null;
            }
        }

        public String next() {
            while (stt == null || !stt.hasMoreTokens()) {
                stt = new StringTokenizer(nextLine());
            }
            return stt.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

//package Codeforces450;

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * Created by Pranav ps on 16-12-2017.
 */

/**
 * This is the template for all coding problems
 */
public class D {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, in, out);
        out.close();
    }
    static class Task {
        private long MOD = (long)(1e9+7);
        private HashMap<Long,Long> hm;
        private ArrayList<Long> divisors;
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long x = in.nextLong();
            long y = in.nextLong();
            if(y%x != 0){
                out.println(0);
                return;
            }
            y /= x;
            hm = new HashMap<>();
            divisors = fDivisors(y);

            out.println(dp(y));
        }

        private long dp(long y) {
            if(y==1)
                return 1;
            if(hm.containsKey(y))
                return hm.get(y);
            long ans = pow(y-1);
            for (Long d: divisors) {
                if(d>y)
                    break;
                if(y%d == 0)
                    ans = (ans - dp(y/d) + MOD)%MOD;
            }
            hm.put(y,ans);
            return ans;
        }

        private long pow(long l) {
            if(l == 0)
                return 1;
            long ans = 1;
            if(l%2 == 1)
                ans *= 2;
            long local = pow(l/2);
            local = (local*local)%MOD;
            ans = (ans*local)%MOD;
            return ans;
        }

        private ArrayList<Long> fDivisors(long y) {
            ArrayList<Long> al = new ArrayList<>();
            for (long i = 2; i*i <= y; i++) {
                if(i*i == y)
                    al.add(i);
                else if(y%i == 0) {
                    al.add(i);
                    al.add(y/i);
                }
            }
            al.add(y);
            Collections.sort(al);
            return al;
        }
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}

import java.util.*;
import java.io.*;
import java.math.*;
public class A{
    class Node implements Comparable<Node> {
        int id;
        int d;
        public Node(int id,int d){
            this.id=id;
            this.d=d;
        }
        public int compareTo(Node c){
            return this.id-c.id;
        }
    }
    void solve(){
        long x=nl(); long y=nl();
        if(y%x!=0){
            pw.println(0);
            return;
        }
        y/=x;
        long ans=0;
        for(long i=1;i*i<=y;i++){

            if(y%i==0){
                ans=(ans+((mobius(i)+M)%M * modPow(2,y/i-1,M)%M)%M)%M;

                if(y/i!=i){
                    long d=y/i;
                    ans=(ans+((mobius(d)+M)%M * modPow(2,y/d-1,M)%M)%M)%M;
                }
            }
        }
        pw.println(ans);

    }
    int mobius(long n){
        int cnt=0;
        for(int i=2;i*i<=n;i++){
            if(n%i==0){
                cnt++;
                n/=i;
                if(n%i==0)return 0;
            }
        }
        if(n>1)cnt++;
        if(cnt%2==0)return 1;
        else return -1;
    }
    static long modPow(long x,long y,long M){
        if(y==0) return 1;
        if(y%2==0) return modPow((x*x)%M,y/2,M)%M;
        else return (x*modPow((x*x)%M,(y-1)/2,M))%M;
    }

    long M=(long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";
    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception { new A().run(); }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private void tr(Object... o) { if(INPUT.length() > 0)System.out.println(Arrays.deepToString(o)); }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.stream.Stream;

public class TestClass implements Runnable {

	static final double time = 1e9;
	static final int MOD = (int) 1e9 + 7;
	static final long mh = Long.MAX_VALUE;
	static final Reader in = new Reader();
	static final PrintWriter out = new PrintWriter(System.out);
	StringBuilder answer = new StringBuilder();

	public static void main(String[] args) {
		new Thread(null, new TestClass(), "persefone", 1 << 28).start();
	}

	@Override
	public void run() {
		long start = System.nanoTime();
		solve();
		printf();
		long elapsed = System.nanoTime() - start;
//		out.println("stamp : " + elapsed / time);
//		out.println("stamp : " + TimeUnit.SECONDS.convert(elapsed, TimeUnit.NANOSECONDS));
		close();
	}

	void solve() {
		int x = in.nextInt();
		int y = in.nextInt();

		if (y % x != 0) {
			printf(0);
			return;
		}

		y /= x;

		List<Integer> divisors = new ArrayList<>();
		for (int i = 1; 1l * i * i <= y; i++) {
			if (y % i == 0) {
				divisors.add(i);
				if (y / i != i)
					divisors.add(y / i);
			}
		}

		Collections.sort(divisors);

		int n = divisors.size();
		long[] dp = new long[n];

		for (int i = 0; i < n; i++) {
			int k = divisors.get(i);
			dp[i] = calc(2, k - 1, MOD);
			for (int j = 0; j < i; j++) {
				if (k % divisors.get(j) == 0) {
					dp[i] -= dp[j];
					if (dp[i] < 0) dp[i] += MOD;
				}
			}
		}

		printf(dp[n - 1]);
	}

	int pow(int a, int b, int p) {
		long ans = 1, base = a;
		while (b > 0){
			if ((b & 1) > 0) {
				ans *= base %= p;
			}
			base *= base %= p;
			b >>= 1;
		}
		return (int)ans;
	}

	public static int[] enumLowestPrimeFactors(int n) {
		int tot = 0;
		int[] lpf = new int[n + 1];
		int u = n + 32;
		double lu = Math.log(u);
		int[] primes = new int[(int) (u / lu + u / lu / lu * 1.5)];
		for (int i = 2; i <= n; i++)
			lpf[i] = i;
		for (int p = 2; p <= n; p++) {
			if (lpf[p] == p)
				primes[tot++] = p;
			int tmp;
			for (int i = 0; i < tot && primes[i] <= lpf[p] && (tmp = primes[i] * p) <= n; i++) {
				lpf[tmp] = primes[i];
			}
		}
		return lpf;
	}

	public static int[] enumNumDivisorsFast(int n, int[] lpf)
	{
		int[] nd = new int[n+1];
		nd[1] = 1;
		for(int i = 2;i <= n;i++){
			int j = i, e = 0;
			while(j % lpf[i] == 0){
				j /= lpf[i];
				e++;
			}
			nd[i] = nd[j] * (e+1);
		}
		return nd;
	}

	boolean isPrime(long n) {

		for (int i = 2; 1l * i * i <= n; i++)
			if (n % i == 0)
				return false;
		return true;
	}

	void printf() {
		out.print(answer);
	}

	void close() {
		out.close();
	}

	void printf(Stream<?> str) {
		str.forEach(o -> add(o, " "));
		add("\n");
	}

	void printf(Object... obj) {
		printf(false, obj);
	}

	void printfWithDescription(Object... obj) {
		printf(true, obj);
	}

	private void printf(boolean b, Object... obj) {

		if (obj.length > 1) {
			for (int i = 0; i < obj.length; i++) {
				if (b) add(obj[i].getClass().getSimpleName(), " - ");
				if (obj[i] instanceof Collection<?>) {
					printf((Collection<?>) obj[i]);
				} else if (obj[i] instanceof int[][]) {
					printf((int[][])obj[i]);
				} else if (obj[i] instanceof long[][]) {
					printf((long[][])obj[i]);
				} else if (obj[i] instanceof double[][]) {
					printf((double[][])obj[i]);
				} else printf(obj[i]);
			}
			return;
		}

		if (b) add(obj[0].getClass().getSimpleName(), " - ");
		printf(obj[0]);
	}

	void printf(Object o) {
		if (o instanceof int[])
			printf(Arrays.stream((int[]) o).boxed());
		else if (o instanceof char[])
			printf(new String((char[]) o));
		else if (o instanceof long[])
			printf(Arrays.stream((long[]) o).boxed());
		else if (o instanceof double[])
			printf(Arrays.stream((double[]) o).boxed());
		else if (o instanceof boolean[]) {
			for (boolean b : (boolean[]) o) add(b, " ");
			add("\n");
		}
		else
			add(o, "\n");
	}

	void printf(int[]... obj) {
		for (int i = 0; i < obj.length; i++) printf(obj[i]);
	}

	void printf(long[]... obj) {
		for (int i = 0; i < obj.length; i++) printf(obj[i]);
	}

	void printf(double[]... obj) {
		for (int i = 0; i < obj.length; i++) printf(obj[i]);
	}

	void printf(boolean[]... obj) {
		for (int i = 0; i < obj.length; i++) printf(obj[i]);
	}

	void printf(Collection<?> col) {
		printf(col.stream());
	}

	<T, K> void add(T t, K k) {
		if (t instanceof Collection<?>) {
			((Collection<?>) t).forEach(i -> add(i, " "));
		} else if (t instanceof Object[]) {
			Arrays.stream((Object[]) t).forEach(i -> add(i, " "));
		} else
			add(t);
		add(k);
	}

	<T> void add(T t) {
		answer.append(t);
	}

	@SuppressWarnings("unchecked")
	<T extends Comparable<? super T>> T min(T... t) {
		if (t.length == 0)
			return null;
		T m = t[0];
		for (int i = 1; i < t.length; i++)
			if (t[i].compareTo(m) < 0)
				m = t[i];
		return m;
	}

	@SuppressWarnings("unchecked")
	<T extends Comparable<? super T>> T max(T... t) {
		if (t.length == 0)
			return null;
		T m = t[0];
		for (int i = 1; i < t.length; i++)
			if (t[i].compareTo(m) > 0)
				m = t[i];
		return m;
	}

	int gcd(int a, int b) {
		return (b == 0) ? a : gcd(b, a % b);
	}

	long gcd(long a, long b) {
		return (b == 0) ? a : gcd(b, a % b);
	}

	long lcm(int a, int b) {
		return (1l * a * b / gcd(a, b));
	}

	long lcm(long a, long b) {
		if (a > Long.MAX_VALUE / b) throw new RuntimeException();
		return a * b / gcd(a, b);
	}

	// c = gcd(a, b) -> extends gcd method: ax + by = c <----> (b % a)p + q = c;
	int[] ext_gcd(int a, int b) {
		if (b == 0) return new int[] {a, 1, 0 };
		int[] vals = ext_gcd(b, a % b);
		int d = vals[0]; // gcd
	    int p = vals[2]; //
		int q = vals[1] - (a / b) * vals[2];
		return new int[] { d, p, q };
	}

	// find any solution of the equation: ax + by = c using extends gcd
	boolean find_any_solution(int a, int b, int c, int[] root) {
		int[] vals = ext_gcd(Math.abs(a), Math.abs(b));
		if (c % vals[0] != 0) return false;
		printf(vals);
		root[0] = c * vals[1] / vals[0];
		root[1] = c * vals[2] / vals[0];
		if (a < 0) root[0] *= -1;
		if (b < 0) root[1] *= -1;
		return true;
	}

	int mod(int x) { return x % MOD; }

	int mod(int x, int y) { return mod(mod(x) + mod(y)); }

	long mod(long x) { return x % MOD; }

	long mod (long x, long y) { return mod(mod(x) + mod(y)); }

	int lw(long[] f, int l, int r, long k) {
		int R = r, m = 0;
		while (l <= r) {
			m = l + r >> 1;
		    if (m == R) return m;
		    if (f[m] >= k) r = m - 1; else l = m + 1;
		}
		return l;
	}

	int up(long[] f, int l, int r, long k) {
		int R = r, m = 0;
		while (l <= r) {
			m = l + r >> 1;
		    if (m == R) return m;
		    if (f[m] > k) r = m - 1; else l = m + 1;
		}
		return l;
	}

	int lw(int[] f, int l, int r, int k) {
		int R = r, m = 0;
		while (l <= r) {
			m = l + r >> 1;
		    if (m == R) return m;
		    if (f[m] >= k) r = m - 1; else l = m + 1;
		}
		return l;
	}

	int up(int[] f, int l, int r, int k) {
		int R = r, m = 0;
		while (l <= r) {
			m = l + r >> 1;
		    if (m == R) return m;
		    if (f[m] > k) r = m - 1; else l = m + 1;
		}
		return l;
	}

	<K extends Comparable<K>> int lw(List<K> li, int l, int r, K k) {
		int R = r, m = 0;
		while (l <= r) {
			m = l + r >> 1;
		    if (m == R) return m;
		    if (li.get(m).compareTo(k) >= 0)
		    	r = m - 1;
		    else
		    	l = m + 1;
		}
		return l;
	}

	<K extends Comparable<K>> int up(List<K> li, int l, int r, K k) {
		int R = r, m = 0;
		while (l <= r) {
			m = l + r >> 1;
		    if (m == R) return m;
		    if (li.get(m).compareTo(k) > 0)
		    	r = m - 1;
		    else
		    	l = m + 1;
		}
		return l;
	}

	<K extends Comparable<K>> int bs(List<K> li, int l, int r, K k) {
		while (l <= r) {
			int m = l + r >> 1;
		    if (li.get(m) == k) return m;
		    else if (li.get(m).compareTo(k) < 0)
		    	l = m + 1;
		    else
		    	r = m - 1;
		}
		return -1;
	}

	long calc(int base, int exponent, int p) {
		if (exponent == 0) return 1;
		if (exponent == 1) return base % p;
		long m = calc(base, exponent >> 1, p);
		if (exponent % 2 == 0) return (m * m) % p;
		return 1l * base * m  % p * m % p;
	}

	long calc(int base, long exponent, int p) {
		if (exponent == 0) return 1;
		if (exponent == 1) return base % p;
		long m = calc(base, exponent >> 1, p);
		if (exponent % 2 == 0) return (m * m) % p;
		return 1l * base * m  % p * m % p;
	}

	long calc(long base, long exponent, int p) {
		if (exponent == 0) return 1;
		if (exponent == 1) return base % p;
		long m = calc(base, exponent >> 1, p);
		if (exponent % 2 == 0) return (m * m) % p;
		return base * m  % p * m % p;
	}

	long power(int base, int exponent) {
		if (exponent == 0) return 1;
		long m = power(base, exponent / 2);
		if (exponent % 2 == 0) return m * m;
		return base * m * m;
	}

	void swap(int[] a, int i, int j) {
		a[i] ^= a[j];
		a[j] ^= a[i];
		a[i] ^= a[j];
	}

	void swap(long[] a, int i, int j) {
		long tmp = a[i];
		a[i] = a[j];
		a[j] = tmp;
	}

	static class Pair<K extends Comparable<? super K>, V extends Comparable<? super V>>
			implements Comparable<Pair<K, V>> {
		private K k;
		private V v;

		Pair() {}

		Pair(K k, V v) {
			this.k = k;
			this.v = v;
		}

		K getK() { return k; }

		V getV() { return v; }

		void setK(K k) { this.k = k; }

		void setV(V v) { this.v = v; }

		void setKV(K k, V v) {
			this.k = k;
			this.v = v;
		}

		@SuppressWarnings("unchecked")
		@Override
		public boolean equals(Object o) {
			if (this == o) return true;
			if (o == null || !(o instanceof Pair)) return false;
			Pair<K, V> p = (Pair<K, V>) o;
			return k.compareTo(p.k) == 0 && v.compareTo(p.v) == 0;
		}

		@Override
		public int hashCode() {
			int hash = 31;
			hash = hash * 89 + k.hashCode();
			hash = hash * 89 + v.hashCode();
			return hash;
		}

		@Override
		public int compareTo(Pair<K, V> pair) {
			return k.compareTo(pair.k) == 0 ? v.compareTo(pair.v) : k.compareTo(pair.k);
		}

		@Override
		public Pair<K, V> clone() {
			return new Pair<K, V>(this.k, this.v);
		}

		@Override
		public String toString() {
			return String.valueOf(k).concat(" ").concat(String.valueOf(v)).concat("\n");
		}
	}

	static class Reader {
		private BufferedReader br;
		private StringTokenizer st;

		Reader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			try {
				while (st == null || !st.hasMoreTokens()) {
					st = new StringTokenizer(br.readLine());
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		int[] nextIntArray(int n) {
			int[] arr = new int[n];
			for (int i = 0; i < n; i++)
				arr[i] = nextInt();
			return arr;
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		String nextLine() {
			String s = "";
			try {
				s = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return s;
		}
	}
}

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.List;
 import java.util.*;
public  class realfast implements Runnable
  {
    private static final int INF = (int) 1e9;
    long in= (long)Math.pow(10,9)+7;
    long fac[]= new long[3000];
    public  void solve() throws IOException
    {
         long m = in;

       int x = readInt();
       int y = readInt();

       if((y%x)!=0)
        out.println(0);
       else
       {
            int len =y/x;

            int root = (int)Math.pow(len,0.5);
            ArrayList<Integer> arr = new ArrayList<>();
            for(int i =1;i<=root;i++)
            {
                if(len%i==0)
                {
                    int j = len/i;
                    arr.add(i);
                    if(j!=i)
                        arr.add(j);
                }
            }
            Collections.sort(arr);
            long dp[]= new long[arr.size()];
            dp[arr.size()-1]=1;
            for(int i=arr.size()-2;i>=0;i--)
            {
                int yo = arr.get(i);
                dp[i]= pow(2,len/yo-1,in);
                for(int j=i+1;j<arr.size();j++)
                {
                    int sal = arr.get(j);
                    if(sal%yo==0)
                    dp[i]= (dp[i]%in-dp[j]%in+in)%in;
                }
            }
            out.println(dp[0]);
       }

    }
    public int gcd(int a , int b )
    {
      if(a<b)
      {
        int t =a;
        a=b;
        b=t;
      }
      if(a%b==0)
        return b ;
      return gcd(b,a%b);
    }
    public long pow(long n , long p,long m)
    {
         if(p==0)
            return 1;
        long val = pow(n,p/2,m);;
        val= (val*val)%m;
        if(p%2==0)
            return val;
        else
            return (val*n)%m;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public static void main(String[] args) {
        new Thread(null, new realfast(), "", 128 * (1L << 20)).start();
    }

    private static final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;
    private BufferedReader reader;
    private StringTokenizer tokenizer;
    private PrintWriter out;

    @Override
    public void run() {
        try {
            if (ONLINE_JUDGE || !new File("input.txt").exists()) {
                reader = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                reader = new BufferedReader(new FileReader("input.txt"));
                out = new PrintWriter("output.txt");
            }
            solve();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                // nothing
            }
            out.close();
        }
    }

    private String readString() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }

    @SuppressWarnings("unused")
    private int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    @SuppressWarnings("unused")
    private long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    @SuppressWarnings("unused")
    private double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }
}
class edge implements Comparable<edge>{
    int val ;
    int color;

    edge(int u, int v)
    {
       this.val=u;
       this.color=v;
    }
    public int compareTo(edge e)
    {
        return this.val-e.val;
    }
}

import java.io.*;
import java.util.*;

public class Main {

	static long modPow(long x, long y, long mod) {
		long res = 1;
		x = x % mod;
		while (y > 0) {
			if ((y & 1) > 0)
				res = (res * x) % mod;
			y = y >> 1; // y = y/2
			x = (x * x) % mod;
		}
		return res;
	}

	static int mod = (int) 1e9 + 7;

	static long add(long x, long y) {
		x += y;
		if (x >= mod)
			return x - mod;
		return x;
	}

	static long sub(long x, long y) {
		x -= y;
		if (x < 0)
			return x + mod;
		return x;
	}

	static long mul(long x, long y) {
		x *= y;
		return x % mod;
	}

	public static void main(String args[]) throws Exception {

		FastReader sc = new FastReader();
		PrintWriter out = new PrintWriter(System.out);
		int x = sc.nextInt();
		int y = sc.nextInt();
		ArrayList<Integer> l = new ArrayList<>();
		if (y % x != 0) {
			System.out.println(0);
			return;
		}
		int t = y / x;
		int i = 0;
		for (i = 1; i * i < t; i++) {
			if (t % i == 0) {
				l.add(i);
				l.add(t / i);
			}
		}
		if (i * i == t)
			l.add(i);

		Integer d[] = l.stream().toArray(Integer[]::new);
		Arrays.sort(d);
		//System.out.println(Arrays.toString(d));
		int dp[] = new int[d.length];
		dp[0] = 1;
		for (i = 1; i < d.length; i++) {
			dp[i] = (int) modPow(2, d[i] - 1, mod);

			for (int j = 0; j < i; j++) {
				if (d[i] % d[j] == 0) {
					// System.out.println("vv");
					dp[i] = (dp[i] - dp[j] + mod) % mod;

				}
			}
		}
		//System.out.println(Arrays.toString(dp));
		System.out.println(dp[d.length - 1]);
		out.close();

	}

	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

		public FastReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Scanner;
import java.util.StringTokenizer;

public class a {
	static int n,m;
	static boolean[] match;
	static int[] rs;
	static long MOD = (long) (1e9+7);
	public static void main(String[] args) throws IOException {
		FastScanner in = new FastScanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int x = in.nextInt(), y = in.nextInt();
		if(y % x != 0) {
			System.out.println(0);
			return;
		}
		y /= x;
		ArrayList<Integer> divs = new ArrayList<>();
		for(int i=1;i*(long)i<=y;i++) {
			if(y % i != 0) continue;
			divs.add(i);
			if(i*i != y)
				divs.add(y/i);
		}
		Collections.sort(divs);
		int[] mu = new int[divs.size()];
		mu[0] = 1;
		long ans = 0;
		for(int i=0;i<divs.size();i++) {
			ans += fastpow(2, y/divs.get(i)-1) * mu[i];
			ans %= MOD;
			int di = divs.get(i);
			for(int j=i+1;j<divs.size();j++) {
				if(divs.get(j) % di == 0) {
					mu[j] -= mu[i];
					mu[j] %= MOD;
				}
			}
		}
		if(ans < 0)
			ans += MOD;
		System.out.println(ans);
	}
	static long fastpow(long base, long exp) {
		long ans = 1;
		while(exp > 0) {
			if((exp & 1) == 1) {
				ans *= base;
				ans %= MOD;
			}
			base *= base;
			base %= MOD;
			exp /= 2;
		}
		return ans;
	}
	static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(InputStream i) {
			br = new BufferedReader(new InputStreamReader(i));
			st = null;
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			if (st == null) {
				st = new StringTokenizer(br.readLine());
			}
			String line = st.nextToken("\n");
			st = null;
			return line;
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}
	}
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class D
{
	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();
		ArrayList<Integer> div = new ArrayList<Integer>();
		for (int i = 1; i*i <= y; i++)
		{
			if(y%i == 0)
			{
				div.add(i);
				if(i != y/i)
					div.add(y/i);
			}
		}

		if(y%x != 0)
		{
			System.out.println(0);
			return;
		}
		int n = y/x;
		int ans = calc(n);

		Collections.sort(div);
		int[] occ = new int[div.size()];
		for (int i = 0; i < occ.length; i++)
			if(div.get(i)%x == 0)
				occ[i]++;
		for (int i = 0; i < occ.length; i++)
		{
			if(occ[i] != 0)
			{
				int v = div.get(i);
				if(v % x == 0 && v > x)
				{
					ans = minus(ans, mul(occ[i], calc(y/v)));
					for (int j = i+1; j < occ.length; j++)
					{
						if(div.get(j)%v == 0)
							occ[j] -= occ[i];
					}
				}
			}
		}

		System.out.println(ans);
		pw.flush();
		pw.close();
	}

	private static int mul(int a, int b)
	{
		return (int)(((long)a*b)%MOD);
	}

	private static int minus(int a, int b)
	{
		int ans = a-b;
		ans =  (ans%MOD);
		if(ans < 0)
			ans += MOD;
		return ans;

	}

	static int MOD = 1000000007;
	static int calc(int n)
	{
		return (int)modPow(2, n-1, MOD);
	}

	static long modPow(long a, long e, int mod)	// O(log e)
	{
		a %= mod;
		long res = 1;
		while(e > 0)
		{
			if((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s)
		{
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException
		{
			br = new BufferedReader(new FileReader(new File((s))));
		}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException
		{
			return br.readLine();
		}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else
				{
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException
		{
			return br.ready();
		}
	}
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.StringTokenizer;

public class D
{
	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();
		ArrayList<Integer> div = new ArrayList<Integer>();
		for (int i = 1; i*i <= y; i++)
		{
			if(y%i == 0)
			{
				div.add(i);
				if(i != y/i)
					div.add(y/i);
			}
		}

		if(y%x != 0)
		{
			System.out.println(0);
			return;
		}
		int n = y/x;
		int ans = calc(n);

		Collections.sort(div);
		int[] occ = new int[div.size()];
		for (int i = 0; i < occ.length; i++)
			if(div.get(i)%x == 0)
				occ[i]++;
		boolean[] taken = new boolean[div.size()];
		for (int i = 0; i < taken.length; i++)
		{
			if(occ[i] != 0)
			{
				int v = div.get(i);
				if(v % x == 0 && v > x)
				{
//					ans -= calc(y/v);
					ans = minus(ans, mul(occ[i], calc(y/v)));
//					if(ans < 0)
//						ans += MOD;
					int mm = occ[i];
					for (int j = i; j < taken.length; j++)
					{
						if(div.get(j)%v == 0)
//							taken[j] = true;
							occ[j] -= mm;
					}
				}
			}
		}

		System.out.println(ans);
		pw.flush();
		pw.close();
	}

	private static int mul(int a, int b)
	{
		return (int)(((long)a*b)%MOD);
	}

	private static int minus(int a, int b)
	{
		int ans = a-b;
		ans =  (ans%MOD);
		if(ans < 0)
			ans += MOD;
		return ans;

	}

	static int MOD = 1000000007;
	static int calc(int n)
	{
		return (int)modPow(2, n-1, MOD);
	}

	static long modPow(long a, long e, int mod)	// O(log e)
	{
		a %= mod;
		long res = 1;
		while(e > 0)
		{
			if((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s)
		{
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException
		{
			br = new BufferedReader(new FileReader(new File((s))));
		}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException
		{
			return br.readLine();
		}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else
				{
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException
		{
			return br.ready();
		}
	}
}

import javax.swing.plaf.synth.SynthEditorPaneUI;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Contest1 {
    static int [] fac, count;
    static void sivie(int n ){
        fac= new int[n+1];
        count= new int[n+1];
        Arrays.fill(fac,1);
        for (int i =2;i<=n;i++){
            if (fac[i]==1){
                fac[i]=i;
                count[i]=1;
                for (int j = i*2;j<=n;j+=i) {
                    fac[j] *= i;
                    count[j]++;
                }
            }
        }
    }
    static int mod = (int)1e9+7;
    static long modpow(long a ,long ex ){
        long res=1;
        while (ex>0){
            if (ex%2==1)
                res=(res*a)%mod;
            a*=a;
            a%=mod;
            ex>>=1;
        }
        return res;
    }
    static long get(int x,int f){
        if ( f<=1)
            return 0;
        if (f<fac.length){
            if (f!=fac[f])
                return 0;
            long ret = modpow(2,x-1);
            return ret*(count[f]%2==0?1:-1);
        }
        else {
            ArrayList<Integer>facs = new ArrayList<>();
            int c = f;
            long val=1;
            for (int j =2;1l*j*j<=f;j++){
                if (c%j==0){
                    facs.add(j);
                    val*=j;
                    while (c%j==0){
                        c/=j;
                    }
                }
            }
            if (c!=1){
                val*=c;
                facs.add(c);
            }
            if (val!=f)
                return 0;
            long here = modpow(2,x-1);
            return here*(facs.size()%2==0?1:-1);
        }
    }
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        sivie((int)1e5);
        int x = sc.nextInt();
        int y = sc.nextInt();

        if (y%x!=0){
            pw.println(0);
        }
        else {
            long ans = modpow(2,y/x -1)+get(1,y/x);
            ans+=mod;
            ans%=mod;
            int v = y/x;
            for (int j =2;1l*j*j<=v;j++){
                if (v%j==0){
                    long c= get(v/j,j);
                    ans+=c+mod;
                    ans%=mod;
                    if (j!=v/j)
                        ans+=get(j,v/j);
                    ans+=mod;
                    ans%=mod;
                }
            }
            pw.println(ans);
        }
        pw.flush();
    }
    static long gcd(long a,long b){
        if (a==0)
            return b;
        return gcd(b%a,a);
    }
    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(FileReader r) {
            br = new BufferedReader(r);
        }

        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public String nextLine() throws IOException {
            return br.readLine();
        }

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++)
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec)
                        f *= 10;
                }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

        public boolean ready() throws IOException {
            return br.ready();
        }
    }
}

import java.util.*;
import java.io.*;

public class D450 {
    public static void main(String[] args) {
        MyScanner sc = new MyScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
        long x = sc.nextLong(); long y = sc.nextLong();
        if (y % x != 0) {
            out.println(0);
            out.close();
            return;
        }
        long a = y / x;
        ArrayList<Long> f = new ArrayList<>();
        for (long i = 2; i * i <= a; i++) {
            if (a % i == 0) {
                f.add(i);
                if (a / i != i)
                    f.add(a / i);
            }
        }
        f.add(1L); f.add(a);
        Collections.sort(f);
        Map<Long, ArrayList<Long>> adj = new HashMap<>();
        for (int i = 0; i < f.size(); i++) {
            for (int j = i + 1; j < f.size(); j++) {
                if (!adj.containsKey(f.get(i))) adj.put(f.get(i), new ArrayList<>());
                if (!adj.containsKey(f.get(j))) adj.put(f.get(j), new ArrayList<>());
                if (f.get(j) % f.get(i) == 0)
                    adj.get(f.get(j)).add(f.get(i));
            }
        }
        Map<Long, Long> dp = new HashMap<>();
        dp.put(1L, (long) 1);
        for (Long i : f) {
            if (i == 1) continue;
            long total = pow(2, i - 1);
            for (Long prev: adj.get(i)) {
                total = (total - dp.get(prev)) % mod;
                if (total < 0) total += mod;
            }
            dp.put(i, total);
        }
        out.println(dp.get(a));
        out.close();
    }

    static long[] fac;
    static long mod = (long) 1e9 + 7;

    static void initFac(long n) {
        fac = new long[(int)n + 1];
        fac[0] = 1;
        for (int i = 1; i <= n; i++) {
            fac[i] = (fac[i - 1]  * i) % mod;
        }
    }

    static long nck(int n, int k) {
        if (n < k)
            return 0;
        long den = inv((int) (fac[k] * fac[n - k] % mod));
        return fac[n] * den % mod;
    }

    static long pow(long b, long e) {
        long ans = 1;
        while (e > 0) {
            if (e % 2 == 1)
                ans = ans * b % mod;
            e >>= 1;
            b = b * b % mod;
        }
        return ans;
    }

    static long inv(long x) {
        return pow(x, mod - 2);
    }

    //-----------MyScanner class for faster input----------
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }

}

import java.io.*;
import java.util.*;

public class CODEFORCES
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static long mod = (long) 1e9 + 7;

	static long pow(long a, long b)
	{
		long ans = 1;
		while (b > 0)
		{
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	static ArrayList<Integer> primes = new ArrayList<Integer>();

	static int mobius(int p)
	{
		if (p == 1)
			return 1;
		int c = 0;
		for (int i : primes)
		{
			if (p % i == 0)
				c++;
			if (p % (i * i) == 0)
				return 0;
		}
		return ((c & 1) == 1) ? -1 : 1;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
		{
			out.println("0");
			return;
		}
		y /= x;
		int m = y;
		for (int i = 2; i * i <= y; i++)
		{
			if (y % i == 0)
				primes.add(i);
			while (y % i == 0)
				y /= i;
		}
		if (y != 1)
			primes.add(y);
		long ans = 0;
		for (int i = 1; i * i <= m; i++)
		{
			if (m % i != 0)
				continue;
			int c = mobius(i);
			ans += pow(2, m / i - 1) * c;
			if (i * i != m)
			{
				c = mobius(m / i);
				ans += pow(2, i - 1) * c;
			}
		}
		ans %= mod;
		out.println(ans);
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	// To Get Input
	// Some Buffer Methods
	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.math.*;
import java.security.KeyStore.Entry;
import java.util.*;

public class SPOJANDCC
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static int mod = (int) 1e9 + 7;

	static int pow(long x, long y)
	{
		long ans = 1;
		while (y > 0)
		{
			if ((y & 1) == 1)
				ans = (ans * x) % mod;
			x = (x * x) % mod;
			y >>= 1;
		}
		return (int) ans;
	}

	static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

	static int cnt(int n)
	{
		if (map.containsKey(n))
			return map.get(n);
		int ans = pow(2, n - 1) - 1;
		if (ans < 0)
			ans += mod;
		for (int i = 2; i * i <= n; i++)
		{
			if (n % i == 0)
			{
				ans = ans - cnt(n / i);
				if (ans < 0)
					ans += mod;
				if (i * i != n)
				{
					ans = ans - cnt(i);
					if (ans < 0)
						ans += mod;
				}
			}
		}
		map.put(n, ans);
		return ans;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
			out.println("0");
		else
			out.println(cnt(y / x));
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.math.*;
import java.security.KeyStore.Entry;
import java.util.*;

public class SPOJANDCC
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static int mod = (int) 1e9 + 7;

	static int pow(long x, long y)
	{
		long ans = 1;
		while (y > 0)
		{
			if ((y & 1) == 1)
				ans = (ans * x) % mod;
			x = (x * x) % mod;
			y >>= 1;
		}
		return (int) ans;
	}

	static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

	static int cnt(int n)
	{
		if (map.containsKey(n))
			return map.get(n);
		int ans = pow(2, n - 1) - 1;
		if (ans < 0)
			ans += mod;
		for (int i = 2; i * i <= n; i++)
		{
			if (n % i == 0)
			{
				ans = ans - cnt(n / i);
				if (ans < 0)
					ans += mod;
			}
			if (i * i != n)
			{
				ans = ans - cnt(i);
				if (ans < 0)
					ans += mod;
			}
		}
		map.put(n, ans);
		return ans;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
			out.println("-1");
		else
			out.println(cnt(y / x));
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.util.*;

public class CODEFORCES
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static long mod = (long) 1e9 + 7;

	static long pow(long a, long b)
	{
		long ans = 1;
		while (b > 0)
		{
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	static ArrayList<Integer> primes = new ArrayList<Integer>();

	static int mobius(int p)
	{
		if (p == 1)
			return -1;
		int c = 0;
		for (int i : primes)
		{
			if (p % i == 0)
				c++;
			if (i * i == p)
				return 0;
		}
		return (c & 1) == 1 ? -1 : 1;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
		{
			out.println("0");
			return;
		}
		y /= x;
		for (int i = 2; i * i <= y; i++)
		{
			if (y % i == 0)
			{
				primes.add(i);
				if (i * i != y)
					primes.add(y / i);
			}
		}
		if (y != 0)
			primes.add(y);
		long ans = pow(2, y - 1);
		for (int i : primes)
		{
			int c = mobius(i);
			ans += pow(2, y / i - 1) * c;
		}
		ans %= mod;
		out.println(ans);
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	// To Get Input
	// Some Buffer Methods
	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.util.*;

public class CODEFORCES
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static long mod = (long) 1e9 + 7;

	static long pow(long a, long b)
	{
		long ans = 1;
		while (b > 0)
		{
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	static ArrayList<Integer> primes = new ArrayList<Integer>();

	static int mobius(int p)
	{
		if (p == 1)
			return -1;
		int c = 0;
		for (int i : primes)
		{
			if (p % i == 0)
				c++;
			if (i * i == p)
				return 0;
		}
		return (c & 1) == 1 ? -1 : 1;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
		{
			out.println("No");
			return;
		}
		y /= x;
		for (int i = 2; i * i <= y; i++)
		{
			if (y % i == 0)
			{
				primes.add(i);
				if (i * i != y)
					primes.add(y / i);
			}
		}
		if (y != 0)
			primes.add(y);
		long ans = pow(2, y - 1);
		for (int i : primes)
		{
			int c = mobius(i);
			ans += pow(2, y / i - 1) * c;
		}
		ans %= mod;
		out.println(ans);
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	// To Get Input
	// Some Buffer Methods
	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.math.*;
import java.security.KeyStore.Entry;
import java.util.*;

public class SPOJANDCC
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static int mod = (int) 1e9 + 7;

	static int pow(long x, long y)
	{
		long ans = 1;
		while (y > 0)
		{
			if ((y & 1) == 1)
				ans = (ans * x) % mod;
			x = (x * x) % mod;
			y >>= 1;
		}
		return (int) ans;
	}

	static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

	static int cnt(int n)
	{
		if (map.containsKey(n))
			return map.get(n);
		int ans = pow(2, n - 1) - 1;
		if (ans < 0)
			ans += mod;
		for (int i = 2; i * i <= n; i++)
		{
			if (n % i == 0)
			{
				ans = ans - cnt(n / i);
				if (ans < 0)
					ans += mod;
			}
			if (i * i != n)
			{
				ans = ans - cnt(i);
				if (ans < 0)
					ans += mod;
			}
		}
		map.put(n, ans);
		return ans;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
			out.println("0");
		else
			out.println(cnt(y / x));
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.util.*;

public class CODEFORCES
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static long mod = (long) 1e9 + 7;

	static long pow(long a, long b)
	{
		long ans = 1;
		while (b > 0)
		{
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	static ArrayList<Integer> primes = new ArrayList<Integer>();

	static int mobius(int p)
	{
		if (p == 1)
			return -1;
		int c = 0;
		for (int i : primes)
		{
			if (p % i == 0)
				c++;
			if (i * i == p)
				return 0;
			while (p % i == 0)
				p /= i;
		}
		return (c & 1) == 1 ? -1 : 1;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
		{
			out.println("0");
			return;
		}
		y /= x;
		for (int i = 2; i * i <= y; i++)
		{
			if (y % i == 0)
			{
				primes.add(i);
				if (i * i != y)
					primes.add(y / i);
			}
		}
		if (y != 0)
			primes.add(y);
		long ans = pow(2, y - 1);
		for (int i : primes)
		{
			int c = mobius(i);
			ans += pow(2, y / i - 1) * c;
		}
		ans %= mod;
		out.println(ans);
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	// To Get Input
	// Some Buffer Methods
	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.math.*;
import java.security.KeyStore.Entry;
import java.util.*;

public class SPOJANDCC
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static long mod = (long) 1e9 + 7;

	static long pow(long a, long b)
	{
		long ans = 1;
		while (b > 0)
		{
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
			out.println("0");
		else
			out.println((pow(2, y / x - 1) - 1 + mod) % mod);
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import java.io.*;
import java.math.*;
import java.security.KeyStore.Entry;
import java.util.*;

public class SPOJANDCC
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static long mod = (long) 1e9 + 7;

	static long pow(long a, long b)
	{
		long ans = 1;
		while (b > 0)
		{
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
			out.println("0");
		else
			out.println(pow(2, y / x - 1) - 1);
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

//
// Untitled 2.java
// Created by Alister Estrada Cueto on 9/25/18.
import java.util.*;
import java.lang.*;
public class  UnusualSequences {

		public static void main(String[] args)
		{

			Scanner sc = new Scanner(System.in);

			int x,y;

			x = sc.nextInt();
			y = sc.nextInt();

			System.out.println(gcd(x,y));

		}

	public static int gcd(int a, int b) {
		if (a == 0)
			return b;

		return gcd(b%a, a);
	}

}

import java.io.*;
import java.util.*;
public class Main {
    static int mod=(int)(1e9+7);
    static HashMap<Integer,Long>map;
    public static void main(String[] args) {
        FastScanner sc=new FastScanner();
        PrintWriter pw=new PrintWriter(System.out);
        while(sc.hasNext()){
            int x=sc.nextInt();
            int y=sc.nextInt();
            ArrayList<Integer>list=fenjie(y);
            map=new HashMap<>();
            map.put(1,1L);
            if(y%x!=0)pw.println(0);
            else{
                pw.println(dfs(y/x));
            }
            pw.flush();
        }
    }
    static long quickmod(long a,int n){
        long res=1;
        while(n>0){
            if(n%2!=0)res=(res*a)%mod;
            a=(a*a)%mod;
            n/=2;
        }
        return res;
    }
    static long dfs(int n){
        if(map.containsKey(n))return map.get(n);
        long sum=0;
        for(int i=2;i<=Math.sqrt(n);i++){
            if(n%i==0) {
                sum = (sum - dfs(n / i)) % mod;
                while(n%i==0)n/=i;
            }
        }
        if(n!=1)sum = (sum - 1) % mod;
        sum=(sum%mod+quickmod(2,n-1)+mod)%mod;
        map.put(n,sum);
        return sum;
    }
    static ArrayList<Integer> fenjie(int n){
        ArrayList<Integer>list=new ArrayList<>();
        for(int i=2;i<=Math.sqrt(n);i++){
            if(n%i==0){
                list.add(i);
                while(n%i==0){
                    n/=i;
                }
            }
        }
        if(n!=1)list.add(n);
        return list;
    }

}
class FastScanner{
    BufferedReader br;
    StringTokenizer st;
    FastScanner(){
        br=new BufferedReader(new InputStreamReader(System.in));
        st=new StringTokenizer("");
    }

    String nextLine(){
        String s="";
        try {
            s=br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return s;
    }
    boolean hasNext(){
        String s="";
        while(!st.hasMoreTokens()){
            s=nextLine();
            if(s==null)return false;
            st=new StringTokenizer(s);
        }
        return true;
    }
    String next(){
        String s="";
        while(!st.hasMoreTokens()){
            s=nextLine();
            st=new StringTokenizer(s);
        }
        return st.nextToken();
    }
    int nextInt(){
        return Integer.valueOf(next());
    }
    long nextLong(){
        return Long.valueOf(next());
    }
    double nextDouble(){
        return Double.valueOf(next());
    }
}

import java.io.*;
import java.util.*;
public class C {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
        static class TaskE {
         long mod=(long)(1E9)+7;
         long rpe(long a,long b){
          long ans=1;
          while(b!=0){
           if(b%2!=0)ans=(ans*a)%mod;
           a=(a*a)%mod;b/=2;
          }return ans;
         }
         public void solve(int testNumber, InputReader in, PrintWriter out) {
          long x=in.nextLong(),y=in.nextLong();
          if(y%x==0)y/=x;else{out.print(0);return;}
          long ans=rpe(2,y-1);
          for(int i=2;i*i<=y;i++){
           if(y%i==0){
            ans=(ans-rpe(2,y/i-1)+mod)%mod;
            if(y/i!=i)ans=(ans-rpe(2,i-1)+mod)%mod;
           }
          }if(y!=1)ans=(ans-rpe(2,0)+mod)%mod;out.print(ans);
         }
    }
    static class InputReader {
        BufferedReader br;
        StringTokenizer st;
        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
            st = null;
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
        public double nextDouble() {
            return Double.parseDouble(next());
        }
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.io.InputStreamReader;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.Writer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Asgar Javadov
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        FastWriter out = new FastWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        Map<Integer, Integer> memo = new HashMap<>();

        public void solve(int testNumber, InputReader in, FastWriter out) {
            int x = in.nextInt();
            int y = in.nextInt();

            if (y % x != 0) {
                out.println(0);
                return;
            }

            int sum = y / x;
            out.println(f(sum));
        }

        private int f(int n) {
            Integer res = memo.get(n);
            if (res != null)
                return res;

            res = NumberTheory.pow(2, n - 1) - 1;
            for (int i = 2; i * i <= n; ++i) {
                if (n % i == 0) {
                    res = NumberTheory.subtract(res, f(i));
                    int other = n / i;
                    if (other != i)
                        res = NumberTheory.subtract(res, f(other));
                }
            }
            memo.put(n, res);
            return res;
        }

    }

    static class InputReader extends BufferedReader {
        StringTokenizer tokenizer;

        public InputReader(InputStream inputStream) {
            super(new InputStreamReader(inputStream), 32768);
        }

        public InputReader(String filename) {
            super(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(filename)));
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(readLine());
                } catch (IOException e) {
                    throw new RuntimeException();
                }
            }
            return tokenizer.nextToken();
        }

        public Integer nextInt() {
            return Integer.valueOf(next());
        }

    }

    static class NumberTheory {
        public static final int MODULO = 1_000_000_007;

        public static int subtract(int a, int b) {
            if (a >= b)
                return a - b;
            else
                return a - b + MODULO;
        }

        public static int pow(int a, long n) {
            return pow(a, n, MODULO);
        }

        public static int pow(int a, long n, int mod) {
            long res = 1L;
            long half = a;
            while (n != 0) {
                if ((n & 1) == 1)
                    res = res * half % mod;
                half = half * half % mod;
                n >>= 1;
            }
            return (int) res;
        }

    }

    static class FastWriter extends PrintWriter {
        public FastWriter(OutputStream outputStream) {
            super(outputStream);
        }

        public FastWriter(Writer writer) {
            super(writer);
        }

        public FastWriter(String filename) throws FileNotFoundException {
            super(filename);
        }

    }
}

import java.util.*;
import java.io.*;

public class ProblemG
{

    static int mod = (int) (1e9+7);
    static InputReader in;
    static PrintWriter out;

    static int brute(int n, int sum, int gcd){
        if(sum > n) return 0;
        if(sum == n) return (gcd == 1) ? 1 : 0;
        int ans = 0;

        for(int i = 1; i <= n; i++)
            ans += brute(n, sum + i, gcd(gcd,i));

        return ans;
    }

    static void solve()
    {
        in = new InputReader(System.in);
        out = new PrintWriter(System.out);

        //debug(brute(8, 0, 0));
        int x = in.nextInt();
        int y = in.nextInt();
        ArrayList<Integer> prime = new ArrayList<>();
        int maxn = 100000;
        boolean[] p = new boolean[maxn];
        for(int i = 2; i < maxn; i++){
            if(p[i]) continue;
            prime.add(i);
            for(int j = i + i; j < maxn; j += i)
                p[j] = true;
        }

        if(y % x == 0){
            y = y / x;
            ArrayList<Integer> list = new ArrayList<>();
            for(int i = 1; i <= Math.sqrt(y); i++){
                if(y % i == 0){
                    list.add(i);
                    if(i * i != y) list.add(y / i);
                }
            }
            long ans = 0;
            HashMap<Integer,Integer> map = new HashMap<>();
            for(int m: list){
                int k = m;
                if(k == 1){
                    map.put(1, 1);
                    continue;
                }
                int c = 0;
                int xx = -1;
                for(int pp : prime){
                    if(k % pp != 0) continue;
                    int c1 = 0;
                    while(k % pp == 0){
                        k /= pp;
                        c1++;
                    }
                    if(c1 > 1){
                        map.put(m, 0);
                        xx = 0;
                        break;
                    }
                    c++;
                }
                if(xx == 0) continue;
                map.put(m, (c % 2 == 0) ? 1 : -1);
            }
            //debug(map);
            for(int k : list){
                long tmp = pow(2, k - 1, mod);
                //debug(y/k,k,map.get(y/k),tmp);
                tmp = map.get(y / k) * tmp;
                ans = (ans + tmp + mod) % mod;
            }
            out.println(ans);
        }
        else out.println(0);

        out.close();
    }

    public static void main(String[] args)
    {
        new Thread(null ,new Runnable(){
            public void run(){
                try{
                    solve();
                } catch(Exception e){
                    e.printStackTrace();
                }
            }
        },"1",1<<26).start();

    }

    static class Pair implements Comparable<Pair>
    {

        int x;
        long y;
        int i;

        Pair (int x,long y)
        {
                this.x = x;
                this.y = y;
        }

        Pair (int x,int y, int i)
        {
                this.x = x;
                this.y = y;
                this.i = i;
        }

        public int compareTo(Pair o)
        {
            return Long.compare(this.y,o.y);
                //return 0;
        }

        public boolean equals(Object o)
        {
            if (o instanceof Pair)
            {
                Pair p = (Pair)o;
                return p.x == x && p.y==y;
            }
            return false;
        }

        @Override
        public String toString()
        {
            return x + " "+ y + " "+i;
        }

        /*public int hashCode()
        {
            return new Long(x).hashCode() * 31 + new Long(y).hashCode();
        }*/

    }

    static long add(long a,long b){
        long x=(a+b);
        while(x>=mod) x-=mod;
        return x;
    }

    static long sub(long a,long b){
        long x=(a-b);
        while(x<0) x+=mod;
        return x;
    }

    static long mul(long a,long b){
        long x=(a*b);
        while(x>=mod) x-=mod;
        return x;
    }

    static String rev(String s){
        StringBuilder sb=new StringBuilder(s);
        sb.reverse();
        return sb.toString();
    }

    static long gcd(long x,long y)
    {
        if(y==0)
                return x;
        else
                return gcd(y,x%y);
    }

    static int gcd(int x,int y)
    {
        if(y==0)
                return x;
        else
                return gcd(y,x%y);
    }

    static long pow(long n,long p,long m)
    {
         long  result = 1;
          if(p==0){
            return 1;
          }

        while(p!=0)
        {
            if(p%2==1)
                result *= n;
            if(result >= m)
               result %= m;
            p >>=1;
            n*=n;
            if(n >= m)
                n%=m;
        }

        return result;
    }

    static long pow(long n,long p)
    {
        long  result = 1;
          if(p==0)
            return 1;

        while(p!=0)
        {
            if(p%2==1)
                result *= n;
            p >>=1;
            n*=n;
        }
        return result;
    }

    static void debug(Object... o)
    {
            System.out.println(Arrays.deepToString(o));
    }

    static class InputReader
    {

        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
                this.stream = stream;
        }

        public int snext()
        {
                if (snumChars == -1)
                        throw new InputMismatchException();
                if (curChar >= snumChars)
                {
                        curChar = 0;
                        try
                        {
                                snumChars = stream.read(buf);
                        } catch (IOException e)
                        {
                                throw new InputMismatchException();
                        }
                        if (snumChars <= 0)
                                return -1;
                }
                return buf[curChar++];
        }

        public int nextInt()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                int sgn = 1;
                if (c == '-')
                {
                        sgn = -1;
                        c = snext();
                }
                int res = 0;
                do
                {
                        if (c < '0' || c > '9')
                                throw new InputMismatchException();
                        res *= 10;
                        res += c - '0';
                        c = snext();
                } while (!isSpaceChar(c));
                return res * sgn;
        }

        public long nextLong()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                int sgn = 1;
                if (c == '-')
                {
                        sgn = -1;
                        c = snext();
                }
                long res = 0;
                do
                {
                        if (c < '0' || c > '9')
                                throw new InputMismatchException();
                        res *= 10;
                        res += c - '0';
                        c = snext();
                } while (!isSpaceChar(c));
                return res * sgn;
        }

        public int[] nextIntArray(int n)
        {
                int a[] = new int[n];
                for (int i = 0; i < n; i++)
                {
                        a[i] = nextInt();
                }
                return a;
        }

        public long[] nextLongArray(int n)
        {
                long a[] = new long[n];
                for (int i = 0; i < n; i++)
                {
                        a[i] = nextLong();
                }
                return a;
        }

        public String readString()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                StringBuilder res = new StringBuilder();
                do
                {
                        res.appendCodePoint(c);
                        c = snext();
                } while (!isSpaceChar(c));
                return res.toString();
        }

        public String nextLine()
        {
                int c = snext();
                while (isSpaceChar(c))
                        c = snext();
                StringBuilder res = new StringBuilder();
                do
                {
                        res.appendCodePoint(c);
                        c = snext();
                } while (!isEndOfLine(c));
                return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
                if (filter != null)
                        return filter.isSpaceChar(c);
                return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
                return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter
        {
                public boolean isSpaceChar(int ch);
        }

    }
}

// Let f(x) = # of sequences a_i such that gcd() = 1, sum(a_i)=x. We want f(y - x). This is a hard AF function to calculate: easiest recurrence would be sum(f_i) where i<t, gcd(t,i)=1,
// but that's not fast enough at all.

// Trick from editorial: Relate a function to an easier function with a relationship IN EITHER DIRECTION. Here, let g(t) = # of sequences w/o gcd()=1 condition.
// Then, we realize that a_i can onyl have so many gcd's, so g(t)=sum_(d|t) f(t/d), f(t)=g(t)-sum_(d|t, d not t) f(t).

// Notice the repeats in f(t). That means we can DP it. Let's code!

import java.util.*;
public class Unusual {
	private static final int N = 1000000007;
	public static int pow(int n) {
		if (n == 0) return 1;
		long x = pow(n / 2);
		x = (x * x) % N;
		if (n % 2 == 1) x = (x * 2) % N;
		return (int) x;
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int x = in.nextInt(), y = in.nextInt(), t = y / x, i;
		if (y % x != 0) {
			System.out.println(0);
			System.exit(0);
		}
		ArrayList<Integer> divisors = new ArrayList<Integer>();
		for (i = 1; i * i < t; i++) {
			if (t % i == 0) {
				divisors.add(i); divisors.add(t / i);
			}
		}
		if (i * i == t) divisors.add(i);
		int[] d = new int[divisors.size()];
		for (i = 0; i < d.length; i++) {
			d[i] = divisors.get(i);
		}
		Arrays.sort(d);
		int[] f = new int[divisors.size()];
		f[0] = 1;
		for (i = 1; i < d.length; i++) {
			f[i] = pow(d[i] - 1);
			for (int j = 0; j < i; j++) {
				if (d[i] % d[j] == 0) f[i] -= f[j];
			}
		}
//		System.out.println(Arrays.toString(d));
//		System.out.println(Arrays.toString(f));
		System.out.println(f[d.length - 1]);
	}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;

import com.sun.javafx.collections.MappingChange.Map;

public class E {

	static StringTokenizer st;
	static BufferedReader br;
	static PrintWriter pw;
	static int mod = (int) (1e9+7);
	static HashMap<Integer, Integer> map;
	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int x = nextInt();
		int y = nextInt();
		if (y % x != 0) {
			System.out.println(0);
			return;
		}
		int n = y / x;
		if (n==1) {
			System.out.println(1);
			return;
		}
		map = new HashMap<Integer, Integer>();
		long ans = calc(n);

		System.out.println(ans);
		pw.close();
	}
	private static int calc(int n) {
		if (map.containsKey(n))
			return map.get(n);
		int res = (int) (binPow(2, n-1)-1);
		if (res < 0)
			res += mod;
		for (int i = 2; i*i <= n; i++) {
			if (n % i==0) {
				res -= calc(i);
				if (res < 0)
					res -= mod;
				if (i*i != n) {
					res -= calc(n / i);
					if (res < 0)
						res += mod;
				}
			}
		}
		map.put(n, res);
		return res;
	}
	private static long binPow(long a, int n) {
		long b = 1;
		while (n > 0) {
			if (n % 2==1)
				b = b * a % mod;
			n /= 2;
			a = a * a % mod;
		}
		return b;
	}
	private static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}
	private static long nextLong() throws IOException {
		return Long.parseLong(next());
	}
	private static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	private static String next() throws IOException {
		while (st==null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;

import com.sun.javafx.collections.MappingChange.Map;

public class E {

	static StringTokenizer st;
	static BufferedReader br;
	static PrintWriter pw;
	static int mod = (int) (1e9+7);
	static HashMap<Integer, Integer> map;
	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int x = nextInt();
		int y = nextInt();
		if (y % x != 0) {
			System.out.println(0);
			return;
		}
		int n = y / x;
		if (n==1) {
			System.out.println(1);
			return;
		}
		map = new HashMap<Integer, Integer>();
		long ans = calc(n);

		for (int i = 2; i*i <= n; i++) {
			if (n % i==0) {
				ans -= calc(i);
				if (ans < 0)
					ans += mod;
				if (i*i != n) {
					ans -= calc(n / i);
					if (ans < 0)
						ans += mod;
				}
			}
		}
		System.out.println(ans);
		pw.close();
	}
	private static int calc(int n) {
		if (map.containsKey(n))
			return map.get(n);
		int res = (int) (binPow(2, n-1)-1);
		if (res < 0)
			res += mod;
		for (int i = 2; i*i <= n; i++) {
			if (n % i==0) {
				res -= calc(i);
				if (res < 0)
					res -= mod;
				if (i*i != n) {
					res -= calc(n / i);
					if (res < 0)
						res += mod;
				}
			}
		}
		map.put(n, res);
		return res;
	}
	private static long binPow(long a, int n) {
		long b = 1;
		while (n > 0) {
			if (n % 2==1)
				b = b * a % mod;
			n /= 2;
			a = a * a % mod;
		}
		return b;
	}
	private static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}
	private static long nextLong() throws IOException {
		return Long.parseLong(next());
	}
	private static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	private static String next() throws IOException {
		while (st==null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class E {

	static StringTokenizer st;
	static BufferedReader br;
	static PrintWriter pw;
	static int mod = (int) (1e9+7);
	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int x = nextInt();
		int y = nextInt();
		if (y % x != 0) {
			System.out.println(0);
			return;
		}
		int n = y / x;
		if (n==1) {
			System.out.println(1);
			return;
		}
		long ans = calc(n);
		for (int i = 2; i*i < n; i++) {
			if (n % i==0) {
				ans -= calc(i);
				if (ans < 0)
					ans += mod;
				if (i*i != n) {
					ans -= calc(n / i);
					if (ans < 0)
						ans += mod;
				}
			}
		}
		System.out.println(ans);
		pw.close();
	}
	private static long calc(int n) {
		return (binPow(2, n-1)-1 + mod) % mod;
	}
	private static long binPow(long a, int n) {
		long b = 1;
		while (n > 0) {
			if (n % 2==1)
				b = b * a % mod;
			n /= 2;
			a = a * a % mod;
		}
		return b;
	}
	private static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}
	private static long nextLong() throws IOException {
		return Long.parseLong(next());
	}
	private static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	private static String next() throws IOException {
		while (st==null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class E {

	static StringTokenizer st;
	static BufferedReader br;
	static PrintWriter pw;
	static int mod = (int) (1e9+7);
	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int x = nextInt();
		int y = nextInt();
		if (y % x != 0) {
			System.out.println(0);
			return;
		}
		int n = y / x;
		if (n==1) {
			System.out.println(0);
			return;
		}
		long ans = calc(n);
		for (int i = 2; i*i <= n; i++) {
			if (n % i==0) {
				ans -= calc(i);
				if (ans < 0)
					ans += mod;
				if (i*i != n) {
					ans -= calc(n / i);
					if (ans < 0)
						ans += mod;
				}
			}
		}
		System.out.println(ans);
		pw.close();
	}
	private static long calc(int n) {
		return (binPow(2, n-1)-1 + mod) % mod;
	}
	private static long binPow(long a, int n) {
		long b = 1;
		while (n > 0) {
			if (n % 2==1)
				b = b * a % mod;
			n /= 2;
			a = a * a % mod;
		}
		return b;
	}
	private static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}
	private static long nextLong() throws IOException {
		return Long.parseLong(next());
	}
	private static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	private static String next() throws IOException {
		while (st==null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class E {

	static StringTokenizer st;
	static BufferedReader br;
	static PrintWriter pw;
	static int mod = (int) (1e9+7);
	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int x = nextInt();
		int y = nextInt();
		if (y % x != 0) {
			System.out.println(0);
			return;
		}
		int n = y / x;
		if (n==1) {
			System.out.println(1);
			return;
		}
		long ans = calc(n);
		for (int i = 2; i*i <= n; i++) {
			if (n % i==0) {
				ans -= calc(i);
				if (ans < 0)
					ans += mod;
				if (i*i != n) {
					ans -= calc(n / i);
					if (ans < 0)
						ans += mod;
				}
			}
		}
		System.out.println(ans);
		pw.close();
	}
	private static long calc(int n) {
		return (binPow(2, n-1)-1 + mod) % mod;
	}
	private static long binPow(long a, int n) {
		long b = 1;
		while (n > 0) {
			if (n % 2==1)
				b = b * a % mod;
			n /= 2;
			a = a * a % mod;
		}
		return b;
	}
	private static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}
	private static long nextLong() throws IOException {
		return Long.parseLong(next());
	}
	private static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	private static String next() throws IOException {
		while (st==null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}
}

import java.io.*;
import java.util.*;

public class Solution {

    static MyScanner sc;
    private static PrintWriter out;
    static long M2 = 1_000_000_000L + 7;

    private static HashMap<Long, Long>[] mods;

    public static void main(String[] s) throws Exception {
        StringBuilder stringBuilder = new StringBuilder();
        if (stringBuilder.length() == 0) {
            sc = new MyScanner(System.in);
        } else {
            sc = new MyScanner(new BufferedReader(new StringReader(stringBuilder.toString())));
        }

        out = new PrintWriter(new OutputStreamWriter(System.out));

        initData();
        solve();
        out.flush();
    }

    static int n = 100000;
    static int[] m = new int[n + 1];

    private static void initData() {
        m[1] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = 2 * i; j <= n; j += i) {
                m[j] -= m[i];
            }
        }

    }

    private static void solve() throws IOException {
        int k = sc.nextInt();
        int r = sc.nextInt();
        if (r % k != 0) {
            out.println(-1);
            return;
        }
        r /= k;

        int t = r;
        int d = 2;
        ArrayList<Integer> div = new ArrayList<>();
        while (d * d <= t) {
            if (t % d != 0) {
                d++;
                continue;
            }
            div.add(d);
            t /= d;
        }
        if (t != 1) {
            div.add(t);
        }

        long res = 0;
        for (int mt = 1; (long) mt * mt <= r; mt++) {
            if (r % mt != 0) continue;
            int l1 = mt;
            int l2 = r / mt;
            res = add(res, l2, l1, div);
            if (l1 != l2) {
                res = add(res, l1, l2, div);
            }
        }
        out.println(res);
    }

    private static long add(long res, int l1, int l2, ArrayList<Integer> div) {
        int a = 1;
        int sum = l2;
        for (int i : div) {
            if (sum % (1L * i * i) == 0) {
                return res;
            }
            if ((sum % i) == 0) {
                a = -a;
                sum /= i;
            }
        }

        long x = pow(2, l1 - 1, M2);

        res += a * x;
        if (res < 0) {
            res += M2;
        }
        return res % M2;
    }

    private static long mob(int l2) {
        return m[l2];
    }

    private static boolean solve(int n, int p, int p1, int i) {
        return false;
    }

    private static boolean isset(long i, int k) {
        return (i & (1 << k)) > 0;
    }

    private static void solveT() throws IOException {
        int t = sc.nextInt();
        while (t-- > 0) {
            solve();
        }
    }

    private static long gcd(long l, long l1) {
        if (l > l1) return gcd(l1, l);
        if (l == 0) return l1;
        return gcd(l1 % l, l);
    }

    private static long pow(long a, long b, long m) {
        if (b == 0) return 1;
        if (b == 1) return a;
        long pp = pow(a, b / 2, m);
        pp *= pp;
        pp %= m;
        return (pp * (b % 2 == 0 ? 1 : a)) % m;
    }

    static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        MyScanner(BufferedReader br) {
            this.br = br;
        }

        public MyScanner(InputStream in) {
            this(new BufferedReader(new InputStreamReader(in)));
        }

        void findToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        String next() {
            findToken();
            return st.nextToken();
        }

        Integer[] nab(int n) {
            Integer[] k = new Integer[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.fi();
            }
            return k;
        }

        int[] na(int n) {
            int[] k = new int[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.fi();
            }
            return k;
        }

        long[] nl(int n) {
            long[] k = new long[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.nextLong();
            }
            return k;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        int fi() {
            String t = next();
            int cur = 0;
            boolean n = t.charAt(0) == '-';
            for (int a = n ? 1 : 0; a < t.length(); a++) {
                cur = cur * 10 + t.charAt(a) - '0';
            }
            return n ? -cur : cur;
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }
    }

}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Vadim
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        r450D solver = new r450D();
        solver.solve(1, in, out);
        out.close();
    }

    static class r450D {
        long mod = (int) 1e9 + 7;
        Long[] memo;
        int MAX = 1_000_000;

        private long subsolve(int x, int y) {
            if (y % x != 0)
                return 0;
            y = y / x;
            x = 1;
            if (y < MAX && memo[y] != null)
                return memo[y];
            long total = IntegerUtils.pow(2, y - 1, mod); // all compositions
            long discard = 0; // discard all where x != 1;
            int div = 2;
            for (; div * div < y; div++) {
                if (y % div == 0) {
                    discard = (discard + subsolve(div, y) + subsolve(y / div, y)) % mod;
                }
            }
            if (div * div == y)
                discard = (discard + subsolve(div, y)) % mod;
//        System.out.print("x = " + x);
//        System.out.print(" y = " + y);
//        System.out.print(" total = " + total);
//        System.out.println(" discard = " + discard);
            long res = (total - discard + 2 * mod - 1) % mod; // -1 discard x == y
            if (y < MAX)
                memo[y] = res;
            return res;
        }

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int x = in.ni(), y = in.ni();
            memo = new Long[MAX];
//        getCompositions(y, x);
            long res = subsolve(x, y);
//        System.out.println("res = " + res);
            out.println(res);
        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String ns() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int ni() {
            return Integer.parseInt(ns());
        }

    }

    static class IntegerUtils {
        public static long pow(long a, long p, long mod) {
            if (p == 0) {
                return 1;
            }

            long t = pow(a, p / 2, mod);

            if (p % 2 != 0) {
                return (((t * t) % mod) * a) % mod;
            } else {
                return (t * t) % mod;
            }
        }

    }
}

import org.omg.CORBA.INTERNAL;

import java.io.*;
import java.math.*;
import java.util.*;
import java.lang.*;

public class Main implements Runnable {
    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;
        private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();

            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }

                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
            return res * sgn;
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return readString();
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    public static void main(String args[]) throws Exception {
        new Thread(null, new Main(), "Main", 1 << 26).start();
    }

    static long gcd(long a, long b) {
        if (b == 0) return a;
        return gcd(b, a % b);
    }

    static int gcd(int a, int b) {
        if (b == 0) return a;
        return gcd(b, a % b);
    }

    static long modPow(long a, long p, long m) {
        if (a == 1) return 1;
        long ans = 1;
        while (p > 0) {
            if (p % 2 == 1) ans = (ans * a) % m;
            a = (a * a) % m;
            p >>= 1;
        }
        return ans;
    }

    static long modInv(long a, long m) {
        return modPow(a, m - 2, m);
    }

    static class Radix {

        static int getMax(int arr[], int n) {
            int mx = arr[0];
            for (int i = 1; i < n; i++)
                if (arr[i] > mx)
                    mx = arr[i];
            return mx;
        }

        static void countSort(int arr[], int n, int exp) {
            int output[] = new int[n];
            int i;
            int count[] = new int[10];
            Arrays.fill(count, 0);

            for (i = 0; i < n; i++)
                count[(arr[i] / exp) % 10]++;

            for (i = 1; i < 10; i++)
                count[i] += count[i - 1];

            for (i = n - 1; i >= 0; i--) {
                output[count[(arr[i] / exp) % 10] - 1] = arr[i];
                count[(arr[i] / exp) % 10]--;
            }

            for (i = 0; i < n; i++)
                arr[i] = output[i];
        }

        static void radixsort(int arr[], int n) {
            int m = getMax(arr, n);

            for (int exp = 1; m / exp > 0; exp *= 10)
                countSort(arr, n, exp);
        }

    }

    class DSU {
        int par[], size[], connectedComponent;

        DSU(int n) {
            par = new int[n];
            size = new int[n];
            for (int i = 0; i < n; i++) {
                size[i] = 1;
                par[i] = i;
            }
            connectedComponent = n;
        }

        int root(int n) {
            if (n == par[n]) return n;
            return par[n] = root(par[n]);
        }

        boolean union(int u, int v) {
            return f_union(root(u), root(v));
        }

        boolean f_union(int u, int v) {
            if (u == v) return false;
            if (size[u] > size[v]) {
                size[u] += size[v];
                par[v] = u;
            } else {
                size[v] += size[u];
                par[u] = v;
            }
            connectedComponent--;
            return true;
        }

        DSU clone_DSU() {
            DSU t = new DSU(par.length);
            t.connectedComponent = connectedComponent;
            for (int i = 0; i < par.length; i++) {
                t.par[i] = par[i];
                t.size[i] = size[i];
            }
            return t;
        }
    }

    class segmentTree {
        long query(int cur, int l, int r, int start, int end, long tree[], long a[], long[] lazy) {
            if (l > end || r < start) return 0;
            if (lazy[cur] != 0) {
                tree[cur] += lazy[cur];
                if (l != r) {
                    lazy[2 * cur + 1] += lazy[cur];
                    lazy[2 * cur + 2] += lazy[cur];
                }
                lazy[cur] = 0;
            }
            if (l >= start && r <= end) return tree[cur];
            int mid = (l + r) >> 1;
            long p1 = query(2 * cur + 1, l, mid, start, end, tree, a, lazy);
            long p2 = query(2 * cur + 2, mid + 1, r, start, end, tree, a, lazy);
            return p1 + p2;
        }

        void build(int cur, int l, int r, long tree[], long a[]) {
            if (l == r) {
                tree[cur] = a[l];
                return;
            }
            int mid = (l + r) >> 1;
            build(2 * cur + 1, l, mid, tree, a);
            build(2 * cur + 2, mid + 1, r, tree, a);
            tree[cur] = tree[2 * cur + 1] + tree[2 * cur + 2];
        }

        void update(int cur, int start, int end, long val, int l, int r, long tree[], long a[], long[] lazy) {
            if (l > end || r < start) return;
            if (lazy[cur] != 0) {
                tree[cur] += (r - l + 1) * lazy[cur];
                if (l != r) {
                    lazy[2 * cur + 1] += lazy[cur];
                    lazy[2 * cur + 2] += lazy[cur];
                }
                lazy[cur] = 0;
            }
            if (l >= start && r <= end) {
                tree[cur] += (r - l + 1) * val;
                if (l != r) {
                    lazy[cur * 2 + 1] += val;
                    lazy[cur * 2 + 2] += val;
                }
                return;
            }
            int mid = (l + r) >> 1;
            update(2 * cur + 1, start, end, val, l, mid, tree, a, lazy);
            update(2 * cur + 2, start, end, val, mid + 1, r, tree, a, lazy);
            tree[cur] = tree[2 * cur + 1] + tree[2 * cur + 2];
        }
    }

    public void run() {
        InputReader sc = new InputReader(System.in);
        // Scanner sc=new Scanner(System.in);
        //  Random sc=new Random();
        PrintWriter out = new PrintWriter(System.out);

        int x=sc.nextInt();
        int y=sc.nextInt();
        if(y%x!=0){
            out.println(0);
            out.close();return;
        }
        dp=new HashMap<>();
        out.println(f(y/x));

        out.close();
    }

    long mod=1000000007;
    HashMap<Integer,Long> dp;

    long f(int n){
        if(dp.containsKey(n))return dp.get(n);
        if(n==1){
            dp.put(1,1L);
            return 1;
        }
        long ans=modPow(2,n-1,mod);
        int i;
        for (i = 2; i*i<n ; i++) {
            if(n%i==0){
                ans=(ans-f(i)+mod)%mod;
                ans=(ans-f(n/i)+mod)%mod;
            }
        }
        if(i*i==n){
            ans=(ans-f(n/i)+mod)%mod;
        }
        dp.put(n,ans);
        return ans;
    }

}

import java.io.*;
import java.util.*;

public class Mainn {
	FastReader scn;
	PrintWriter out;
	String INPUT = "2 12";

	void solve() {
		int x = scn.nextInt(), y = scn.nextInt(), mod = (int) 1e9 + 7;
		if (y % x != 0) {
			out.println(0);
			return;
		}
		int k = y / x;

		HashMap<Integer, Long> map = new HashMap<>();
		map.put(1, 1L);
		map.put(2, 1L);

		long ans = func(k, map, mod);
		ans = (power(2, k - 1, mod) - ans + mod) % mod;
		out.println(ans);
	}

	long func(int k, HashMap<Integer, Long> map, int mod) {
		long rv = 1;
		for (int i = 2; i * i <= k; i++) {
			if (k % i != 0) {
				continue;
			}
			if (map.containsKey(i)) {
				rv += map.get(i);
			} else {
				long x = (power(2, i - 1, mod) - func(i, map, mod) + mod) % mod;
				map.put(i, x);
				rv += x;
			}
			if (i * i != k) {
				if (map.containsKey(k / i)) {
					rv += map.get(k / i);
				} else {
					long x = (power(2, k / i - 1, mod) - func(k / i, map, mod) + mod) % mod;
					map.put(k / i, x);
					rv += x;
				}
			}
			rv %= mod;
		}

		return rv;
	}

	long power(long a, long x, long mod) {
		if (x == 0) {
			return 1;
		}
		long p = power(a, x / 2, mod);
		p *= p;
		p %= mod;
		if (x % 2 == 1) {
			p *= a;
			p %= mod;
		}
		return p;
	}

	void run() throws Exception {
		boolean oj = System.getProperty("ONLINE_JUDGE") != null;
		out = new PrintWriter(System.out);
		scn = new FastReader(oj);
		long time = System.currentTimeMillis();
		solve();
		out.flush();
		if (!oj) {
			System.out.println(Arrays.deepToString(new Object[] { System.currentTimeMillis() - time + " ms" }));
		}
	}

	public static void main(String[] args) throws Exception {
		new Mainn().run();
	}

	class FastReader {
		InputStream is;

		public FastReader(boolean onlineJudge) {
			is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());

		}

		byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		char nextChar() {
			return (char) skip();
		}

		String next() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		char[] next(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		char[][] nextMatrix(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = next(m);
			return map;
		}

		int[] nextArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		int nextInt() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		long nextLong() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		int[] shuffle(int[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				arr[i] = arr[i] ^ arr[j];
				arr[j] = arr[i] ^ arr[j];
				arr[i] = arr[i] ^ arr[j];
			}
			return arr;
		}
	}
}

import java.io.*;
import java.util.*;

public class Mainn {
	FastReader scn;
	PrintWriter out;
	String INPUT = "";

	void solve() {
		int x = scn.nextInt(), y = scn.nextInt(), mod = (int) 1e9 + 7;
		if (y % x != 0) {
			out.println(0);
			return;
		}
		int k = y / x;

		HashMap<Integer, Long> map = new HashMap<>();
		map.put(1, 1L);

		long ans = func(k, map, mod);
		ans = (power(2, k - 1, mod) - ans + mod) % mod;
		out.println(ans);
	}

	long func(int k, HashMap<Integer, Long> map, int mod) {
		long rv = 1;
		for (int i = 2; i * i <= k; i++) {
			if (k % i != 0) {
				continue;
			}
			if (map.containsKey(i)) {
				rv += map.get(i);
			} else {
				long x = func(i, map, mod);
				map.put(i, x);
				rv += x;
			}
			if (i * i != k) {
				if (map.containsKey(k / i)) {
					rv += map.get(k / i);
				} else {
					long x = func(k / i, map, mod);
					map.put(k / i, x);
					rv += x;
				}
			}
			rv %= mod;
		}

		return rv;
	}

	long power(long a, long x, long mod) {
		if (x == 0) {
			return 1;
		}
		long p = power(a, x / 2, mod);
		p *= p;
		p %= mod;
		if (x % 2 == 1) {
			p *= a;
			p %= mod;
		}
		return p;
	}

	void run() throws Exception {
		boolean oj = System.getProperty("ONLINE_JUDGE") != null;
		out = new PrintWriter(System.out);
		scn = new FastReader(oj);
		long time = System.currentTimeMillis();
		solve();
		out.flush();
		if (!oj) {
			System.out.println(Arrays.deepToString(new Object[] { System.currentTimeMillis() - time + " ms" }));
		}
	}

	public static void main(String[] args) throws Exception {
		new Mainn().run();
	}

	class FastReader {
		InputStream is;

		public FastReader(boolean onlineJudge) {
			is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());

		}

		byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		char nextChar() {
			return (char) skip();
		}

		String next() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		char[] next(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		char[][] nextMatrix(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = next(m);
			return map;
		}

		int[] nextArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		int nextInt() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		long nextLong() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		int[] shuffle(int[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				arr[i] = arr[i] ^ arr[j];
				arr[j] = arr[i] ^ arr[j];
				arr[i] = arr[i] ^ arr[j];
			}
			return arr;
		}
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class A {

	public static final int MOD = 1000000007;

	public static int poo(long b, int p) {
		long rt = 1;
		for(;p>0;p=p/2,b=b*b%MOD) if(p % 2 == 1) {
			rt = rt * b % MOD;
		}
		return (int) rt;
	}

	public static int calc(int x, int y) {
		if (y % x > 0) {
			return 0;
		} else {
			int sum = y / x;
			int ans = poo(2, sum - 1);
			// for(int i=2;i<=sum;i++) ans -= calc(i, sum - i);

			for(int i=1;((long) i) * i <= sum;i++) if(sum % i == 0){
				int lo = sum / i; int hi = i;
				ans -= calc(lo, sum - lo);
				if(lo != hi && hi > 1) ans -= calc(hi, sum - hi);
			}

			return ans;
		}
	}

	public static void main(String[] args) throws IOException {
		FastScanner sc = new FastScanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();

		pw.println(calc(x, y));

		pw.close();
		sc.close();
	}

}

class FastScanner {
	BufferedReader br;
	StringTokenizer st;

	public FastScanner(InputStream is) {
		br = new BufferedReader(new InputStreamReader(is));
		st = null;
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	public long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public void close() throws IOException {
		br.close();
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class A {

	public static final int MOD = 1000000007;

	static Map<Integer, Integer> memo;

	public static int poo(long b, int p) {
		long rt = 1;
		for(;p>0;p=p/2,b=b*b%MOD) if(p % 2 == 1) {
			rt = rt * b % MOD;
		}
		return (int) rt;
	}

	public static int calc(int x, int y) {
		if(y == 0) {
			return 0;
		} else if (y % x > 0) {
			return 0;
		} else if(x > 1) {
			return calc(1, y / x);
		} else {
			if(memo.containsKey(y)) {
				return memo.get(y);
			} else {
				int ans = poo(2, y - 1);

				for(int i=2;((long) i) * i <= y;i++) if(y % i == 0){
					int lo = y / i; int hi = i;
					ans -= calc(lo, y);
					if(lo != hi) ans -= calc(hi, y);
				}

				if(y > 1) ans -= calc(y, y);

				memo.put(y, ans);

				return ans;
			}

		}
	}

	public static void main(String[] args) throws IOException {
		FastScanner sc = new FastScanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();

		memo = new HashMap<Integer, Integer>();

		pw.println(calc(x, y));

		pw.close();
		sc.close();
	}

}

class FastScanner {
	BufferedReader br;
	StringTokenizer st;

	public FastScanner(InputStream is) {
		br = new BufferedReader(new InputStreamReader(is));
		st = null;
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	public long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public void close() throws IOException {
		br.close();
	}
}

import static java.util.Arrays.*;
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import java.util.*;
import java.math.*;
import java.io.*;

public class Main implements Runnable {

	boolean TEST = System.getProperty("ONLINE_JUDGE") == null;

    void solve() throws IOException {
    	int x = nextInt(), y = nextInt();
    	if (y % x != 0) {
    		out.println(0);
    		return;
    	}
    	out.println(f(y / x));
    }

    int MOD = (int)1e9 + 7;
    long f(int t) {
    	long res = pow(2, t - 1, MOD);
    	for (int i = 2; i * i <= t; i++)
    		if (t % i == 0) {
    			res = (res + MOD - f(i)) % MOD;
    			if (i * i != t) res = (res + MOD - f(t / i)) % MOD;
    		}
    	return (res + MOD - 1) % MOD;
    }

    long pow(long a, long p, int MOD) {
    	if (p == 0) return 1;
    	long b = pow(a, p / 2, MOD);
    	if (p % 2 == 0) return b * b % MOD;
    	return b * b % MOD * a % MOD;
    }

    String next() throws IOException {
        while(st == null || !st.hasMoreTokens()) st = new StringTokenizer(input.readLine());
        return st.nextToken();
    }

    int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    long nextLong() throws IOException {
        return Long.parseLong(next());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }

    void debug(Object... o) {
        System.out.println(deepToString(o));
    }

    void gcj(Object o) {
        String s = String.valueOf(o);
        out.println("Case #" + test + ": " + s);
        System.out.println("Case #" + test + ": " + s);
    }

    BufferedReader input;
    PrintWriter out;
    StringTokenizer st;
    int test;

    void init() throws IOException {
        if (TEST) input = new BufferedReader(new FileReader("input.in"));
        else input = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(new BufferedOutputStream(System.out));
    }

    public static void main(String[] args) throws IOException {
        new Thread(null, new Main(), "", 1 << 20).start();
    }

    public void run() {
        try {
            init();
            if (TEST) {
                int runs = nextInt();
                for(int i = 0; i < runs; i++) solve();
            } else solve();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        int mod = 1000000007;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int x = in.readInt();
            int y = in.readInt();

            if (y % x != 0) {
                out.println(0);
                return;
            }
            y /= x;

            ArrayList<Integer> div = new ArrayList<>();

            for (long i = 2; i * i <= y; i++) {
                if (y % i == 0) div.add((int) i);
                if (y % i == 0 && y / i != i) div.add(y / (int) i);
            }

            Collections.sort(div);

            int[] f = new int[div.size()];
            long total = 0;

            for (int i = 0; i < f.length; i++) f[i] = pow(2, div.get(i) - 1);

            for (int i = 1; i < f.length; i++) {
                for (int j = i - 1; j >= 0; j--) {
                    if (div.get(i) % div.get(j) == 0) {
                        f[i] = (int) ((mod + f[i] - (long) f[j]) % mod);
                    }
                }
                total += f[i];
                total = total % mod;
            }
            out.println((mod * 2L + pow(2, y - 1) - total - 1) % mod);

        }

        int pow(long a, int b) {
            long ans = 1;
            while (b >= 1) {
                if (b % 2 == 1) ans = (ans * a) % mod;
                a = (a * a) % mod;
                b /= 2;
            }
            return (int) ans;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        int mod = 1000000007;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int x = in.readInt();
            int y = in.readInt();

            if (y % x != 0) {
                out.println(0);
                return;
            }
            y /= x;

            ArrayList<Integer> div = new ArrayList<>();

            for (long i = 2; i * i <= y; i++) {
                if (y % i == 0) div.add((int) i);
                if (y % i == 0 && y / i != i) div.add(y / (int) i);
            }

            if (y != 1) div.add(y);

            Collections.sort(div);

            int[] f = new int[div.size()];

            for (int i = 0; i < f.length; i++) f[i] = pow(2, div.get(i) - 1);

            for (int i = 1; i < f.length; i++) {
                for (int j = i - 1; j >= 0; j--) {
                    if (div.get(i) % div.get(j) == 0) {
                        f[i] = (int) ((mod + f[i] - (long) f[j]) % mod);
                    }
                }
            }
            out.println(f[f.length - 1] - 1);

        }

        int pow(long a, int b) {
            long ans = 1;
            while (b >= 1) {
                if (b % 2 == 1) ans = (ans * a) % mod;
                a = (a * a) % mod;
                b /= 2;
            }
            return (int) ans;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Pradyumn
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, FastReader in, PrintWriter out) {
            long x = in.nextInt();
            long y = in.nextInt();
            if (y % x != 0) {
                out.println(0);
                return;
            } else {
                long n = y / x;
                long ans = (long) ((2 + Math.sqrt(13)) * NT.powerMod((long) (1 + Math.sqrt(13)), n, NT.MOD7I));
                ans -= (2 - Math.sqrt(13)) * NT.powerMod((long) (1 - Math.sqrt(13)), n, NT.MOD7I);
                ans /= (3 * NT.powerMod(2, n, NT.MOD7I) * Math.sqrt(13));
                out.println(ans);
            }
        }

    }

    static class NT {
        public static final int MOD7I = (int) 1e9 + 7;

        public static long powerMod(long a, long n, long mod) {
            //    a %= mod;
            long ret = 1;
            int x = 63 - Long.numberOfLeadingZeros(n);
            for (; x >= 0; x--) {
                ret = ret * ret % mod;
                if (n << 63 - x < 0) ret = ret * a % mod;
            }
            return ret;
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar;
        private int pnumChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(InputStream stream) {
            this.stream = stream;
        }

        private int pread() {
            if (pnumChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= pnumChars) {
                curChar = 0;
                try {
                    pnumChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (pnumChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = pread();
            while (isSpaceChar(c))
                c = pread();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = pread();
            }
            int res = 0;
            do {
                if (c == ',') {
                    c = pread();
                }
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = pread();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        private boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        private static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        Map<Integer, Integer> cache;
        ArrayList<Integer> divs;
        int MOD = (int) 1e9 + 7;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int X = in.nextInt();
            int Y = in.nextInt();

            if (Y % X != 0) {
                out.println(0);
                return;
            }

            cache = new HashMap<>();

            Y /= X;

            divs = divisors(Y);

            out.println(F(Y));
        }

        private int F(int num) {
            if (cache.containsKey(num)) {
                return cache.get(num);
            }

            int ans = (int) pow(2, num - 1);

            for (int d : divs) {
                if (d > 1 && d <= num) {
                    ans = add(ans, -F(num / d));
                }
            }

            cache.put(num, ans);
            return ans;
        }

        private int add(long a, long b) {
            return (int) ((((a + b) % MOD) + MOD) % MOD);
        }

        private long pow(long n, long k) {
            if (k == 0) return 1;
            if (k % 2 == 0) return pow(n * n % MOD, k / 2);
            return pow(n, k - 1) * n % MOD;
        }

        private ArrayList<Integer> divisors(int num) {
            ArrayList<Integer> ans = new ArrayList<>();
            for (int x = 1; x * x <= num; x++) {
                if (num % x == 0) {
                    ans.add(x);
                    if (x * x != num) {
                        ans.add(num / x);
                    }
                }
            }
            Collections.sort(ans);
            return ans;
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

import java.util.*;
import java.io.*;
public class EdB {

	public static void main(String[] args) throws Exception{
		long num = 1000000007;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);

	 	StringTokenizer st = new StringTokenizer(bf.readLine());
	 	int x = Integer.parseInt(st.nextToken());
	 	int y = Integer.parseInt(st.nextToken());
	 	if (y%x != 0){
	 		out.println(0);
	 	}
	 	else{
		 	Set<Long> divisors = new HashSet<Long>();
		 	for(long j = 1;j*j<=y/x;j++){
		 		if ((y/x)%j == 0){
		 			divisors.add(j);
		 			divisors.add((y/x)/j);
		 		}
		 	}
		 	long ans = power(2, y/x-1, num);
		 	for(long j : divisors){
		 		if (j!= y/x){
		 			ans-=(power(2, j-1, num)-1);
		 			ans%=num;
		 			ans+=num;
		 			ans%=num;
		 		}
		 	}
		 	out.println(ans-1);
	 	}

 		out.println();

 		out.close();

 	}
	public static int power(long x, long y, long mod){
		long ans = 1;
		while(y>0){
			if (y%2==1)
				ans = (ans*x)%mod;
			x = (x*x)%mod;
			y/=2;
		}
		return (int)(ans);
	}
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is

import java.util.*;
import java.io.*;
public class EdC {

	public static void main(String[] args) throws Exception{
		long num = 1000000007;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);
 		StringTokenizer st = new StringTokenizer(bf.readLine());
 		int x = Integer.parseInt(st.nextToken());
 		int y = Integer.parseInt(st.nextToken());
 		int n = y/x;
 		int[] isPrime = new int[n+1];
		Arrays.fill(isPrime, 1);
		int[] mu = new int[n+1];
		Arrays.fill(mu,  1);
		for(int i = 2;i<=n;i++){
			for(int j = i;j<n;j+=i){
				if (j > i)
					isPrime[j] = 0;
				if (j%(i*i) == 0)
					mu[j] = 0;
				mu[j] = -mu[j];
			}
		}
 		long sum = 0;
		for(int j = 1;j<=n;j++){
			if (n%j == 0){
				sum+=(((mu[n/j]*power(2, j-1, num))%num+num)%num);
				sum%=num;
			}
		}

 		if (y%x == 0)
 			out.println(sum);
 		else
 			out.println(0);

 		out.close();

 	}
	public static long power(long x, long y, long mod){
		long ans = 1;
		while(y>0){
			if (y%2==1)
				ans = (ans*x)%mod;
			x = (x*x)%mod;
			y/=2;
		}
		return ans;
	}
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is

import java.util.*;
import java.io.*;
public class EdC {

	public static void main(String[] args) throws Exception{
		long num = 1000000007;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);
 		StringTokenizer st = new StringTokenizer(bf.readLine());
 		int x = Integer.parseInt(st.nextToken());
 		int y = Integer.parseInt(st.nextToken());
 		int n = y/x;
 		int[] isPrime = new int[n+1];
		Arrays.fill(isPrime, 1);
		int[] mu = new int[n+1];
		Arrays.fill(mu,  1);
		for(int i = 2;i<=n;i++){
			for(int j = i;j<=n;j+=i){
				if (j > i)
					isPrime[j] = 0;
				if (j%(i*i) == 0)
					mu[j] = 0;
				mu[j] = -mu[j];
			}
		}
 		long sum = 0;
		for(int j = 1;j<=n;j++){
			if (n%j == 0){
				sum+=(((mu[n/j]*power(2, j-1, num))%num+num)%num);
				sum%=num;
			}
		}

 		if (y%x == 0)
 			out.println(sum);
 		else
 			out.println(0);

 		out.close();

 	}
	public static long power(long x, long y, long mod){
		long ans = 1;
		while(y>0){
			if (y%2==1)
				ans = (ans*x)%mod;
			x = (x*x)%mod;
			y/=2;
		}
		return ans;
	}
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is

import java.util.*;
import java.io.*;
public class EdB {

	public static void main(String[] args) throws Exception{
		long num = 1000000007;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);

	 	StringTokenizer st = new StringTokenizer(bf.readLine());
	 	int x = Integer.parseInt(st.nextToken());
	 	int y = Integer.parseInt(st.nextToken());
	 	if (y%x != 0){
	 		out.println(0);
	 	}
	 	else{
		 	Set<Long> divisors = new HashSet<Long>();
		 	long numb = y/x;
		 	for(long j = 2;j*j<=numb;j++){
		 		while (numb%j == 0){
		 			numb/=j;
		 			divisors.add(j);
		 		}
		 	}
		 	if (numb!=1){
		 		divisors.add(numb);
		 	}
		 	long ans = power(2, y/x-1, num)-1;
		 	for(long j : divisors){
		 		if (j!= y/x){
		 			ans-=(power(2, (y/(j*x))-1, num)-1);
		 			ans%=num;
		 			ans+=num;
		 			ans%=num;
		 		}
		 	}
		 	out.println(ans);
	 	}

 		out.println();

 		out.close();

 	}
	public static int power(long x, long y, long mod){
		long ans = 1;
		while(y>0){
			if (y%2==1)
				ans = (ans*x)%mod;
			x = (x*x)%mod;
			y/=2;
		}
		return (int)(ans);
	}
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is

import java.util.*;
import java.io.*;
public class EdC {

	public static void main(String[] args) throws Exception{
		long num = 1000000007;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);
 		StringTokenizer st = new StringTokenizer(bf.readLine());
 		int x = Integer.parseInt(st.nextToken());
 		int y = Integer.parseInt(st.nextToken());
 		int n = y/x;
 		int[] isPrime = new int[n+1];
		Arrays.fill(isPrime, 1);
		int[] mu = new int[n+1];
		Arrays.fill(mu,  1);
		for(int i = 2;i<=n+1;i++){
			for(int j = i;j<=n;j+=i){
				if (j > i)
					isPrime[j] = 0;
				if (j%(i*i) == 0)
					mu[j] = 0;
				mu[j] = -mu[j];
			}
		}
 		long sum = 0;
		for(int j = 1;j<=n;j++){
			if (n%j == 0){
				sum+=(((mu[n/j]*power(2, j-1, num))%num+num)%num);
				sum%=num;
			}
		}

 		if (y%x == 0)
 			out.println(sum);
 		else
 			out.println(0);

 		out.close();

 	}
	public static long power(long x, long y, long mod){
		long ans = 1;
		while(y>0){
			if (y%2==1)
				ans = (ans*x)%mod;
			x = (x*x)%mod;
			y/=2;
		}
		return ans;
	}
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is

import java.util.*;
import java.io.*;
public class EdB {

	public static void main(String[] args) throws Exception{
		long num = 1000000007;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);

	 	StringTokenizer st = new StringTokenizer(bf.readLine());
	 	int x = Integer.parseInt(st.nextToken());
	 	int y = Integer.parseInt(st.nextToken());
	 	if (y%x != 0){
	 		out.println(0);
	 	}
	 	else if (y == x)
	 		out.println(1);
	 	else{
		 	Set<Long> divisors = new HashSet<Long>();
		 	long numb = y/x;
		 	for(long j = 2;j*j<=numb;j++){
		 		while (numb%j == 0){
		 			numb/=j;
		 			divisors.add(j);
		 		}
		 	}
		 	if (numb!=1){
		 		divisors.add(numb);
		 	}
		 	long ans = power(2, y/x-1, num)-1;
		 	for(long j : divisors){
		 		if (j!= y/x){
		 			ans-=(power(2, (y/(j*x))-1, num)-1);
		 			ans%=num;
		 			ans+=num;
		 			ans%=num;
		 		}
		 	}
		 	out.println(ans);
	 	}

 		out.println();

 		out.close();

 	}
	public static int power(long x, long y, long mod){
		long ans = 1;
		while(y>0){
			if (y%2==1)
				ans = (ans*x)%mod;
			x = (x*x)%mod;
			y/=2;
		}
		return (int)(ans);
	}
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is

import java.util.*;
import java.io.*;
public class EdB {

	public static void main(String[] args) throws Exception{
		long num = 1000000007;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);

	 	StringTokenizer st = new StringTokenizer(bf.readLine());
	 	int x = Integer.parseInt(st.nextToken());
	 	int y = Integer.parseInt(st.nextToken());
	 	if (y%x != 0){
	 		out.println(0);
	 	}
	 	else{
		 	Set<Long> divisors = new HashSet<Long>();
		 	for(long j = 1;j*j<=y/x;j++){
		 		if ((y/x)%j == 0){
		 			divisors.add(j);
		 			divisors.add((y/x)/j);
		 		}
		 	}
		 	long ans = power(2, y/x-1, num);
		 	for(long j : divisors){
		 		if (j!= y/x){
		 			ans-=power(2, j-1, num);
		 			ans%=num;
		 			ans+=num;
		 			ans%=num;
		 		}
		 	}
		 	out.println(ans);
	 	}

 		out.println();

 		out.close();

 	}
	public static int power(long x, long y, long mod){
		long ans = 1;
		while(y>0){
			if (y%2==1)
				ans = (ans*x)%mod;
			x = (x*x)%mod;
			y/=2;
		}
		return (int)(ans);
	}
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is

import java.io.*;
import java.util.*;

public class MathCode {
	public static void main(String[] args) throws Exception{
			int MOD = 1000000007;
			BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
			StringTokenizer st = new StringTokenizer(bf.readLine());
			int x = Integer.parseInt(st.nextToken());
			int y = Integer.parseInt(st.nextToken());
			if (y%x != 0){
				System.out.println("0");
				return;

			}
			int k = y/x;
			ArrayList<Integer> divisors = new ArrayList<Integer>();
			double squareroot = Math.sqrt(k+0.0);
			for (int i = 1;i<squareroot;i++){
				if (k % i == 0){
					divisors.add(i);
					divisors.add(k/i);
				}
			}
			if (squareroot == (int)(squareroot))
				divisors.add((int)(squareroot));
			Collections.sort(divisors);
			int[] tempArray = new int[divisors.size()];
			tempArray[0] = 1;
			int sum = 1;
			for(int i = 1;i<divisors.size();i++){
				tempArray[i] = power(2, divisors.get(i)-1) - sum;
				if (tempArray[i] < 0)
					tempArray[i] += MOD;

				sum+=tempArray[i];
			}

			System.out.println(tempArray[divisors.size()-1]);
	}
	public static int power(int a, int b){
		int prod = 1;
		int MOD = 1000000007;
		for (int i = 0;i<b;i++){
			prod*=a;
			prod%=MOD;
		}
		return prod;
	}
}

		import java.awt.List;
		import java.io.*;
		import java.util.*;

		/*
		 *
		 * daiict
		 *
		 *
		 *
		 */

		public class Main {
			FastScanner in;
			PrintWriter out;

			static ArrayList[] adj;

			static int n;
			static int m;
			static int visited[][];
			static int[][] arr;
			static int[][] brr;
			static int[][] ans;
			static int array[];
			static int pref[];
			static int sum = 0;
		//for dfs do not delete
			static int dir[][] ={{1,0},{0,1},{0,-1}};
			static HashMap<Long,Long> map;

			static long an = 0;
			static long bn = 0;
			static int p = 0;
			static int ta = -1;
			static int tb = -1;
			static Stack<Integer> st;
			static int k;
			static long mod = (long)1e9 + 7;
			static long[] seg;

			static class Pair implements Comparable<Pair>
		    {
				int x;
				boolean y;
				String s = "";
				String val;
		        Pair(int l, boolean b, String p,String q) {

		        	this.x = l;
		            this.y = b;
		           this.s = p;
		           this.val = q;
		        }
		        @Override
		        public int compareTo(Pair p) {

		        	String arr[] = val.split(" ");
		        	String brr[] = p.val.split(" ");

		        	if(s.equals("numeric")){
		        		int aa = Integer.parseInt(arr[x]);
						int bb = Integer.parseInt(brr[x]);

						if(aa>bb && this.y){
							return 1;
						}else if(this.y){
							return -1;
						}else if(aa >= bb && ! this.y){
							return -1;
						}else{
							return 1;
						}
		        	}else{
		        		if(this.y){
		        			return arr[x].compareTo(brr[x]);
		        		}else{
		        			return brr[x].compareTo(arr[x]);
		        		}
		        	}

		        }

		        public String toString(){
		        	return x + " " + y;
		        }

		        public boolean equals(Object o){
		        	if(o instanceof Pair){
		        		Pair a = (Pair)o;

		        		return this.x == a.x;
		        	}

		        	return false;
		        }

//		        public int hashCode(){
//		        	return new Long(x).hashCode()*31 + new Long(y).hashCode();
//		        }

		    }

			public static int gcd(int a, int b) {
				if (b == 0) return a;
				return gcd(b, a%b);
			}

			void build(int n) {  // build the tree
				  for (int i = n - 1; i > 0; --i) seg[i] = Math.min(seg[i<<1],seg[i<<1|1]);
				}

			public static void modify(int p, long val,int n) {  // set value at position p
				  for (seg[p += n] = val; p > 1; p >>= 1) seg[p>>1] = Math.min(seg[p],seg[p^1]);
				}

				long query(int l, int r,int n) {  // sum on interval [l, r)
				  long res = Long.MAX_VALUE;
				  for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
				    if ((l&1) == 1) res = (long) Math.min(res,seg[l++]);
				    if ((r&1) == 1) res = (long)Math.min(res,seg[--r]);
				  }
				  return res;
				}

				 static long bC(int n, int k)
				    {
				    long C[][] = new long[n+1][k+1];
				    int i, j;

				        // Calculate  value of Binomial Coefficient in bottom up manner
				    for (i = 0; i <= n; i++)
				    {
				        for (j = 0; j <= Math.min(i, k); j++)
				        {
				            // Base Cases
				            if (j == 0 || j == i)
				                C[i][j] = 1;

				            // Calculate value using previosly stored values
				            else
				                C[i][j] = C[i-1][j-1] + C[i-1][j];
				          }
				     }

				    return C[n][k];
				    }

		    void solve() throws NumberFormatException, IOException {

		    	Scanner in = new Scanner(System.in);

		    	long x = in.nextLong();
		    	long y = in.nextLong();
		    	int f = 0;

		    	if(y%x != 0 || x>y){
		    		out.println(0);
		    		return;
		    	}
		    	long n = y/x;

		    	map = new HashMap();
		    	map.put(1L, 1L);
		    	long ans = call(n);

		    	out.println(ans);
		    }

		    public static long call(long n){
		    	if(map.containsKey(n)){
		    		return map.get(n);
		    	}

		    	long ans = (pow(2,n-1,mod) - 1)%mod;

		    	for(int i = 2;i*i<=n;i++){
		    		if(n%i == 0){
		    			//removal of number whose gcd after removing i is n/i that is map.get(i)
		    			ans =(ans-call(i))%mod;

		    			// if i*i = n then n/i = i
			    		//else

			    		if(i*i != n){
			    			ans = (ans-call(n/i))%mod;

			    		}

		    		}

		    	}

		    	map.put(n,ans);
		    	return ans;

		    }

		    public static void dfs(int i,int j,int d){

		    	System.out.println(i + " " + j + " " +d);

		    	if(d <= ans[i][j]){
		    		return;
		    	}

		    	if(i == n-1 && j == m-1){
		    		p = Math.max(p,d);
		    		ans[i][j] = p;
		    		arr = brr;
		    		return;
		    	}

		    	ans[i][j] = d;
		    	int temp = arr[i][j];
		    	arr[i][j] = 0;

		    	for(int p= 0;p<3;p++){
		    		int x = i + dir[p][0];
		    		int y = j + dir[p][1];

		    		if(x < 0 || x >=n || y < 0 || y >=m){
		    			continue;
		    		}else{

		    			dfs(x,y,d+arr[x][y]);

		    		}
		    	}
		    	//arr[i][j] = temp;

		    }

		    public static int Floor(int[] dp, int low, int high, long x)
		    {
		        // If low and high cross each other
		        if (low > high)
		            return -1;

		        // If last element is smaller than x
		        if (x >= dp[high])
		            return high;

		        // Find the middle point
		        int mid = (low+high)/2;

		        // If middle point is floor.
		        if (dp[mid] == x)
		            return mid;

		        // If x lies between mid-1 and mid
		        if (mid > 0 && dp[mid-1] <= x && x < dp[mid])
		            return mid-1;

		        // If x is smaller than mid, floor must be in
		        // left half.
		        if (x < dp[mid])
		            return Floor(dp, low, mid-1, x);

		        // If mid-1 is not floor and x is greater than
		        // arr[mid],
		        return Floor(dp, mid+1, high, x);
		    }

		    public static String[] reverse(String arr[]){

		    	for(int i = 0;i<arr.length/2;i++){
		    		String temp = arr[i];
		    		arr[i] = arr[arr.length-i-1];
		    		arr[arr.length-1-i] = temp;
		    	}

		    	return arr;

		    }

		    static long inv(long x , long mod)
			{
				long r,y;
				for(r=1,y=mod-2;y!=0;x=x*x%mod,y>>=1)
				{
					if((y&1)==1)
						r=r*x%mod;

				}
				return r;
			}

		    public static long sum(long x){
		    	return x<10?x:x%10 + sum(x/10);
		    }

			public static long gcd(long x, long y) {
				if (x == 0)
					return y;
				else
					return gcd( y % x,x);
			}

			public static long pow(long x,long y,long n){
				if(y==0)
					return 1%n;
				if(y%2==0){
					long z=pow(x,y/2,n);
					return (z*z)%n;
				}
				return ((x%n)*pow(x,y-1,n))%n;
			}

			public static boolean isPrime(int n) {
				// Corner cases
				if (n <= 1)
					return false;
				if (n <= 3)
					return true;

				// This is checked so that we can skip
				// middle five numbers in below loop
				if (n % 2 == 0 || n % 3 == 0)
					return false;

				for (int i = 5; i * i <= n; i = i + 6)
					if (n % i == 0 || n % (i + 2) == 0)
						return false;

				return true;
			}

			void run() throws NumberFormatException, IOException {
				in = new FastScanner();
				out = new PrintWriter(System.out);

				solve();

				out.close();
			}

			class FastScanner {
				BufferedReader br;
				StringTokenizer st;

				public FastScanner() {
					br = new BufferedReader(new InputStreamReader(System.in));
				}

				String next() {
					while (st == null || !st.hasMoreTokens()) {
						try {
							st = new StringTokenizer(in.br.readLine());
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					return st.nextToken();
				}

				int nextInt() {
					return Integer.parseInt(next());
				}

				long nextLong() {
					return Long.parseLong(next());
				}

				double nextDouble() {
					return Double.parseDouble(next());
				}
			}

			class Tri{

				Tri[] arr;

				public Tri(){
					arr = new Tri[27];
				}

			}

			public static void main(String[] args) throws NumberFormatException, IOException {
				new Main().run();
			}
		}

		class Node{
			int a;
			int b;

		}

		class MyComp implements Comparator<String>{

			int c = 0;

			MyComp(int d){
				c = d;
			}

			@Override
			public int compare(String a,String b) {

				// < == -1

				String arr[] = a.split(" ");
				String brr[] = b.split(" ");

				return arr[c].compareTo(brr[c]);

			}

		}

		class MyComp2 implements Comparator<String>{

			int c = 0;

			MyComp2(int d){
				c = d;
			}

			@Override
			public int compare(String a,String b) {

				// < == -1

				String arr[] = a.split(" ");
				String brr[] = b.split(" ");

				int aa = Integer.parseInt(arr[c]);
				int bb = Integer.parseInt(brr[c]);

				if(aa>bb){
					return 1;
				}else{
					return -1;
				}

			}

		}

import java.util.*;
public class sequences{

	public static void main(String [] args){
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt();
		int y = sc.nextInt();
		int MOD = (int) 1e9 + 7;
		if (y%x == 0) {
			int div = y/x;

			LinkedList<Integer> n = new LinkedList<Integer>();
			for (int i = 1;i < (int)(Math.sqrt(div)+1) ;i++ ) {
				if (div%i == 0) {
					n.add(i);
					n.add(div/i);
				}
			}
			long[] m = new long[n.size()];
			Collections.sort(n);
			//System.out.println(n);
			for (int i = 0;i<n.size() ;i++ ) {
				int k = n.get(i);
				m[i] = (long)Math.pow(2,k-1)%MOD;
				for (int j = 0;j < i ;j++ ) {
					if (k%n.get(j) == 0) {
						m[i]-=m[j];
						if (m[i]<0) {
							m[i] += MOD;
						}
					}
				}

			}
			System.out.println(m[n.size()-1]);
		}else{
			System.out.println("0");
		}
	}
}

import java.util.*;
public class sequences{

	public static void main(String [] args){
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt();
		int y = sc.nextInt();
		int MOD = (int) 1e9 + 7;
		if (y%x == 0) {
			int div = y/x;

			List<Integer> n = new ArrayList<>();
			for (int i = 1; 1l * i * i <= div ;i++ ) {
				if (div%i == 0) {
					n.add(i);
					if (div/i!=i) {
						n.add(div/i);
					}

				}
			}
			long[] m = new long[n.size()];
			Collections.sort(n);
			//System.out.println(n);
			for (int i = 0;i<n.size() ;i++ ) {
				int k = n.get(i);
				m[i] = (long)Math.pow(2,k-1)%MOD;
				for (int j = 0;j < i ;j++ ) {
					if (k%n.get(j) == 0) {
						m[i]-=m[j];
						if (m[i]<0) {
							m[i] += MOD;
						}
					}
				}

			}
			System.out.println(m[n.size()-1]);
		}else{
			System.out.println("0");
		}
	}
}

/*Author: Satyajeet Singh, Delhi Technological University*/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;

public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static boolean sieve[];
    static ArrayList<Integer> primes;
    static long factorial[],invFactorial[];
    static HashSet<Pair> graph[];
    static boolean oj = System.getProperty("ONLINE_JUDGE") != null;
/****************************************Solutions Begins***************************************/
    static HashMap<Integer,Long> map;
    static long dfs(int i){
        if(map.containsKey(i)){
            return map.get(i);
        }
        long ans=(modulo(2,i-1,mod)-1+mod)%mod;
        for(int j=2;j*j<=i;j++){
            if(i%j==0){
                ans=(ans-dfs(i/j)+mod)%mod;
                if(i/j!=j){
                    int jj=i/j;
                    ans=(ans-dfs(i/jj)+mod)%mod;
                }
            }
        }
        map.put(i,ans);
        return ans;
    }
    public static void main (String[] args) throws Exception {
        String st[]=nl();
        int x=pi(st[0]);
        int y=pi(st[1]);
        map=new HashMap<>();
        if(y%x!=0){
            out.println(0);
        }
        else{
            out.println(dfs(y/x));
        }
/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }
/****************************************Template Begins************************************************/
    static String[] nl() throws Exception{
        return br.readLine().split(" ");
    }
    static String[] nls() throws Exception{
        return br.readLine().split("");
    }
    static int pi(String str) {
        return Integer.parseInt(str);
    }
    static long pl(String str){
        return Long.parseLong(str);
    }
    static double pd(String str){
        return Double.parseDouble(str);
    }
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.000000000000000000000");
        out.println(ft.format(d));
    }
/**************************************Bit Manipulation**************************************************/
    static void printMask(long mask){
        System.out.println(Long.toBinaryString(mask));
    }
    static int countBit(int mask){
        int ans=0;
        while(mask!=0){
            if(mask%2==1){
                ans++;
            }
            mask/=2;
        }
        return ans;
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new HashSet[n];
        for(int i=0;i<n;i++){
            graph[i]=new HashSet<>();
        }
    }
    static void addEdge(int a,int b){
        graph[a].add(new Pair(b,1));
    }
    static void addEdge(int a,int b,int c){
        graph[a].add(new Pair(b,c));
    }
/*********************************************PAIR********************************************************/
    static class PairComp implements Comparator<Pair>{
        public int compare(Pair p1,Pair p2){
            return p1.u-p2.u;
        }
    }
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }
        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }
        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }
        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }
        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*******************************************************/
    static class PairCompL implements Comparator<Pairl>{
        public int compare(Pairl p1,Pairl p2){
            if(p1.u-p2.u<0){
                return -1;
            }
            else if(p1.u-p2.u>0){
                return 1;
            }
            else{
                if(p1.v-p2.v<0){
                    return -1;
                }
                else if(p1.v-p2.v>0){
                    return 1;
                }
                else{
                    return 0;
                }
            }
        }
    }
    static class Pairl implements Comparable<Pairl> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }

            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }

            public boolean equals(Object o) {
                Pairl other = (Pairl) o;
                return u == other.u && v == other.v;
            }

            public int compareTo(Pairl other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }

            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o) {
        if(!oj)
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y)
    {
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; // a is greater number
        b = (x < y) ? x : y; // b is smaller number
        r = b;
        while(a % b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/******************************************SIEVE**********************************************************/
    static void sieveMake(int n){
        sieve=new boolean[n];
        Arrays.fill(sieve,true);
        sieve[0]=false;
        sieve[1]=false;
        for(int i=2;i*i<n;i++){
            if(sieve[i]){
                for(int j=i*i;j<n;j+=i){
                    sieve[j]=false;
                }
            }
        }
        primes=new ArrayList<Integer>();
        for(int i=0;i<n;i++){
            if(sieve[i]){
                primes.add(i);
            }
        }
    }
/********************************************End***********************************************************/
}

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import javax.print.attribute.HashAttributeSet;

/*
 public class _900D {

 }

 */
public class _900D {
  public void solve() throws FileNotFoundException {
    InputStream inputStream = System.in;

    InputHelper in = new InputHelper(inputStream);

    // actual solution
    int y = in.readInteger();
    int x = in.readInteger();

    if (x % y != 0) {
      System.out.println(-1);
      return;
    }

    x /= y;

    List<Integer> pf = new ArrayList<Integer>();

    int ax = x;
    for (int i = 2; i * i <= ax; i++) {
      if (ax % i == 0) {
        pf.add(i);

        while (ax % i == 0) {
          ax /= i;
        }
      }
    }
    if (ax > 1) {
      pf.add(ax);
    }

    int bn = (1 << pf.size());

    long ans = 0;
    for (int i = 0; i < bn; i++) {

      int cnt = 0;
      int nx = x;
      for (int j = 0; j < pf.size(); j++) {
        if (((1 << j) & i) != 0) {
          cnt++;
          nx /= pf.get(j);
        }
      }

      if (cnt % 2 == 0) {
        ans += pow(nx - 1);
        ans %= mod;
      } else {
        ans -= pow(nx - 1);
        ans += mod;
        ans %= mod;
      }
    }

    System.out.println(ans);
    // end here
  }

  int mod = (int) 1e9 + 7;

  long pow(int t) {
    if (t == 0) {
      return 1;
    }

    long ans = pow(t / 2);

    if (t % 2 == 0) {
      return (ans * ans) % mod;
    } else {
      return (ans * ans * 2) % mod;
    }
  }

  public static void main(String[] args) throws FileNotFoundException {
    (new _900D()).solve();
  }

  class InputHelper {
    StringTokenizer tokenizer = null;
    private BufferedReader bufferedReader;

    public InputHelper(InputStream inputStream) {
      InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
      bufferedReader = new BufferedReader(inputStreamReader, 16384);
    }

    public String read() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          String line = bufferedReader.readLine();
          if (line == null) {
            return null;
          }
          tokenizer = new StringTokenizer(line);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      return tokenizer.nextToken();
    }

    public Integer readInteger() {
      return Integer.parseInt(read());
    }

    public Long readLong() {
      return Long.parseLong(read());
    }
  }
}

import java.util.*;

import javax.security.auth.kerberos.KerberosKey;
import javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener;

import java.awt.font.GraphicAttribute;
import java.io.*;
import java.nio.channels.AcceptPendingException;
import java.time.Period;

public class Main {

	public static void main(String[] args) throws Exception {
            int x=sc.nextInt();
            int y=sc.nextInt();
            if(y%x!=0) {
            	pw.println(0);

            }else {
            	int num=y/x;
            	primeFactors(num);
            	if(primefact.size()==0) {
            		pw.println(1);
            	}else if(primefact.size()==1) {
            		pw.println((Pow(2, num-1, 1000000007)+1000000007-1)%1000000007);
            	}else {
                int subtract=0;
            	int[]z=new int[primefact.size()];
            	int j=0;
            	for(int i:primefact.keySet()) {
            		z[j]=i;
            		j++;
            	}
            	for(int i=1;i<(1<<z.length);i++) {
            		int subsubtrac=1;
            		int n=0;
            	for(j=0;j<32;j++) {
            		if(((i>>j)&1)==1) {
            			subsubtrac*=z[j];
            			n++;
            		}

            	}
            	if(n%2==1) {
            		subtract+=Pow(2, (num/subsubtrac)-1, 1000000007);
            	}else {
					subtract-=Pow(2,(num/subsubtrac)-1, 1000000007);
				}

            	subtract=subtract%1000000007;
            	//pw.println(subtract);

            	}
            //	pw.println(Arrays.toString(z));
            	pw.print((Pow(2, num-1, 1000000007)+1000000007-subtract)%1000000007);
            	}
            }

		pw.close();
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(FileReader r) {
			br = new BufferedReader(r);
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}
		public long[] nextLongArray(int n) throws IOException {
            long[] a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = nextLong();
            return a;
        }
		public int[] nextIntArray(int n) throws IOException {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }
		public Integer[] nextIntegerArray(int n) throws IOException {
            Integer[] a = new Integer[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }
		public boolean ready() throws IOException {
			return br.ready();
		}

	}

	static class pair implements Comparable<pair> {
		int x;
		int y;

		public pair(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return x + " " + y;
		}
		public boolean equals(Object o) {
            if (o instanceof pair) {
                pair p = (pair)o;
                return p.x == x && p.y == y;
            }
            return false;
        }
        public int hashCode() {
            return new Double(x).hashCode() * 31 + new Double(y).hashCode();
        }
        public int compareTo(pair other) {
        	if(this.x==other.x) {
        		return Long.compare(this.y, other.y);
        	}
			return Long.compare(other.x, this.x);
		}
	}

	static class tuble implements Comparable<tuble> {
		int x;
		int y;
		int z;

		public tuble(int x, int y, int z) {
			this.x = x;
			this.y = y;
			this.z = z;
		}

		public String toString() {
			return x + " " + y + " " + z;
		}

		public int compareTo(tuble other) {
			if (this.x == other.x) {
				return this.y - other.y;
			} else {
				return this.x - other.x;
			}
		}
	}

	public static long GCD(long a, long b) {
		if (b == 0)
			return a;
		if (a == 0)
			return b;
		return (a > b) ? GCD(a % b, b) : GCD(a, b % a);
	}

	public static long LCM(long a, long b) {
		return a * b / GCD(a, b);
	}

	static long Pow(long a, long e, long mod) // O(log e)
	{
		a %= mod;
		long res = 1l;
		while (e > 0) {
			if ((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1l;
		}
		return res;
	}

	static long nc(int n, int r) {
		if (n < r)
			return 0;
		long v = fac[n];
		v *= Pow(fac[r], mod - 2, mod);
		v %= mod;
		v *= Pow(fac[n - r], mod - 2, mod);
		v %= mod;
		return v;
	}

	public static boolean isprime(long a) {
		if (a == 0 || a == 1) {
			return false;
		}
		if (a == 2) {
			return true;
		}
		for (int i = 2; i < Math.sqrt(a) + 1; i++) {
			if (a % i == 0) {
				return false;
			}
		}
		return true;
	}

	public static boolean isPal(String s) {
		boolean t = true;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
				t = false;
				break;
			}
		}
		return t;
	}

	public static long RandomPick(long[] a) {
		int n = a.length;
		int r = rn.nextInt(n);
		return a[r];
	}

	public static int RandomPick(int[] a) {
		int n = a.length;
		int r = rn.nextInt(n);
		return a[r];
	}

	public static void PH(String s, boolean reverse) {
		prelen = s.length();
		HashsArray[HashsArrayInd] = new int[prelen + 1];
		prepow = new int[prelen];
		if (HashsArrayInd == 0) {
			int[] mods = { 1173017693, 1173038827, 1173069731, 1173086977, 1173089783, 1173092147, 1173107093,
					1173114391, 1173132347, 1173144367, 1173150103, 1173152611, 1173163993, 1173174127, 1173204679,
					1173237343, 1173252107, 1173253331, 1173255653, 1173260183, 1173262943, 1173265439, 1173279091,
					1173285331, 1173286771, 1173288593, 1173298123, 1173302129, 1173308827, 1173310451, 1173312383,
					1173313571, 1173324371, 1173361529, 1173385729, 1173387217, 1173387361, 1173420799, 1173421499,
					1173423077, 1173428083, 1173442159, 1173445549, 1173451681, 1173453299, 1173454729, 1173458401,
					1173459491, 1173464177, 1173468943, 1173470041, 1173477947, 1173500677, 1173507869, 1173522919,
					1173537359, 1173605003, 1173610253, 1173632671, 1173653623, 1173665447, 1173675577, 1173675787,
					1173684683, 1173691109, 1173696907, 1173705257, 1173705523, 1173725389, 1173727601, 1173741953,
					1173747577, 1173751499, 1173759449, 1173760943, 1173761429, 1173762509, 1173769939, 1173771233,
					1173778937, 1173784637, 1173793289, 1173799607, 1173802823, 1173808003, 1173810919, 1173818311,
					1173819293, 1173828167, 1173846677, 1173848941, 1173853249, 1173858341, 1173891613, 1173894053,
					1173908039, 1173909203, 1173961541, 1173968989, 1173999193};
			mod = RandomPick(mods);
			int[] primes = { 59, 61, 67, 71, 73, 79, 83, 89, 97, 101 };
			prime = RandomPick(primes);
		}
		prepow[0] = 1;
		if (!reverse) {

			for (int i = 1; i < prelen; i++) {
				prepow[i] = (int) ((1l * prepow[i - 1] * prime) % mod);

			}
			for (int i = 0; i < prelen; i++) {
				if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z')
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'a' + 1) * prepow[i]) % mod) % mod);
				else
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'A' + 27) * prepow[i]) % mod) % mod);
			}

		} else {
			for (int i = 1; i < prelen; i++) {
				prepow[i] = (int) ((1l * prepow[i - 1] * prime) % mod);

			}
			for (int i = 0; i < prelen; i++) {
				if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z')
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'a' + 1) * prepow[prelen - 1 - i]) % mod) % mod);
				else
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'A' + 27) * prepow[prelen - 1 - i]) % mod) % mod);
			}

		}

		HashsArrayInd++;

	}

	public static int PHV(int l, int r, int n, boolean reverse) {
		if (l > r) {
			return 0;
		}
		int val = (int) ((1l * HashsArray[n - 1][r] + mod - HashsArray[n - 1][l - 1]) % mod);
		if (!reverse) {

			val = (int) ((1l * val * prepow[prelen - l]) % mod);
		} else {
			val = (int) ((1l * val * prepow[r - 1]) % mod);
		}
		return val;
	}

    public static void genprime(int n) {
    	 boolean prime[] = new boolean[n+1];
         for(int i=0;i<n;i++)
             prime[i] = true;

         for(int p = 2; p*p <=n; p++)
         {
             if(prime[p] == true)
             {
                 for(int i = p*p; i <= n; i += p)
                     prime[i] = false;
             }
         }
         for(int i = 2; i <= n; i++)
         {
             if(prime[i] == true) {
                primes.put(i,primes.size());
                primes2.put(primes2.size(),i);
             }

         }
    }

    public static void primeFactors(int n)
    {
        while (n % 2 == 0) {
            primefact.put(2,primefact.getOrDefault(2, 0)+1);
            n /= 2;
        }

        for (int i = 3; i <= Math.sqrt(n); i += 2) {
            while (n % i == 0) {
                primefact.put(i,primefact.getOrDefault(i, 0)+1);
                n /= i;
            }
        }

        if (n > 2)
            primefact.put(n,primefact.getOrDefault(n, 0)+1);
    }
    public static long LSB(long x) {
		return x&-x;
	}
	static class fenwick {
		long[] arr;
		public fenwick(int[] a) {
			arr=new long[a.length+1];
			for(int i=1;i<=a.length;i++) {
				arr[i]+=a[i-1];
				if(i+LSB(i)<=a.length) {
					arr[(int) (i+LSB(i))]+=arr[i];
				}
			}
		}public fenwick(long[] a) {
			arr=new long[a.length+1];
			for(int i=1;i<=a.length;i++) {
				arr[i]+=a[i];
				if(i+LSB(i)<=a.length) {
					arr[(int) (i+LSB(i))]+=arr[i];
				}
			}
		}
		public void update(int ind,long x) {
			int i=ind;
			while(i<arr.length) {
				arr[i]+=x;
				i+=LSB(i);
			}
		}
		public long PrefixSum(int ind) {
			long sum=0;
			int i=ind;
			while(i>0) {
				sum+=arr[i];
				i=(int) (i-LSB(i));
			}
			return sum;
		}
		public long RangeQuerey(int l,int r) {
			return  this.PrefixSum(r+1)-this.PrefixSum(l);
		}
	}
	static TreeMap<Integer,Integer>primes=new TreeMap<Integer, Integer>();
	static TreeMap<Integer,Integer>primes2=new TreeMap<Integer, Integer>();
    static TreeMap<Integer,Integer>primefact=new TreeMap<Integer, Integer>();
	static int[][] HashsArray;
	static int HashsArrayInd = 0;
	static int[] prepow;
	static int prelen = 0;
	static int prime = 61;
	static long fac[];
	static int mod = 1000000007;
	static Random rn = new Random();
	static Scanner sc = new Scanner(System.in);
	static PrintWriter pw = new PrintWriter(System.out);
}

import java.util.*;

import javax.security.auth.kerberos.KerberosKey;
import javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener;

import java.awt.font.GraphicAttribute;
import java.io.*;
import java.nio.channels.AcceptPendingException;
import java.time.Period;

public class Main {

	public static void main(String[] args) throws Exception {
            int x=sc.nextInt();
            int y=sc.nextInt();
            if(y%x!=0) {
            	pw.println(0);
            }else {
            	int num=y/x;
            	pw.print(Pow(2, num-1, 1000000007)-1);
            }

		pw.close();
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(FileReader r) {
			br = new BufferedReader(r);
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}
		public long[] nextLongArray(int n) throws IOException {
            long[] a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = nextLong();
            return a;
        }
		public int[] nextIntArray(int n) throws IOException {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }
		public Integer[] nextIntegerArray(int n) throws IOException {
            Integer[] a = new Integer[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }
		public boolean ready() throws IOException {
			return br.ready();
		}

	}

	static class pair implements Comparable<pair> {
		int x;
		int y;

		public pair(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return x + " " + y;
		}
		public boolean equals(Object o) {
            if (o instanceof pair) {
                pair p = (pair)o;
                return p.x == x && p.y == y;
            }
            return false;
        }
        public int hashCode() {
            return new Double(x).hashCode() * 31 + new Double(y).hashCode();
        }
        public int compareTo(pair other) {
        	if(this.x==other.x) {
        		return Long.compare(this.y, other.y);
        	}
			return Long.compare(other.x, this.x);
		}
	}

	static class tuble implements Comparable<tuble> {
		int x;
		int y;
		int z;

		public tuble(int x, int y, int z) {
			this.x = x;
			this.y = y;
			this.z = z;
		}

		public String toString() {
			return x + " " + y + " " + z;
		}

		public int compareTo(tuble other) {
			if (this.x == other.x) {
				return this.y - other.y;
			} else {
				return this.x - other.x;
			}
		}
	}

	public static long GCD(long a, long b) {
		if (b == 0)
			return a;
		if (a == 0)
			return b;
		return (a > b) ? GCD(a % b, b) : GCD(a, b % a);
	}

	public static long LCM(long a, long b) {
		return a * b / GCD(a, b);
	}

	static long Pow(long a, long e, long mod) // O(log e)
	{
		a %= mod;
		long res = 1l;
		while (e > 0) {
			if ((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1l;
		}
		return res;
	}

	static long nc(int n, int r) {
		if (n < r)
			return 0;
		long v = fac[n];
		v *= Pow(fac[r], mod - 2, mod);
		v %= mod;
		v *= Pow(fac[n - r], mod - 2, mod);
		v %= mod;
		return v;
	}

	public static boolean isprime(long a) {
		if (a == 0 || a == 1) {
			return false;
		}
		if (a == 2) {
			return true;
		}
		for (int i = 2; i < Math.sqrt(a) + 1; i++) {
			if (a % i == 0) {
				return false;
			}
		}
		return true;
	}

	public static boolean isPal(String s) {
		boolean t = true;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
				t = false;
				break;
			}
		}
		return t;
	}

	public static long RandomPick(long[] a) {
		int n = a.length;
		int r = rn.nextInt(n);
		return a[r];
	}

	public static int RandomPick(int[] a) {
		int n = a.length;
		int r = rn.nextInt(n);
		return a[r];
	}

	public static void PH(String s, boolean reverse) {
		prelen = s.length();
		HashsArray[HashsArrayInd] = new int[prelen + 1];
		prepow = new int[prelen];
		if (HashsArrayInd == 0) {
			int[] mods = { 1173017693, 1173038827, 1173069731, 1173086977, 1173089783, 1173092147, 1173107093,
					1173114391, 1173132347, 1173144367, 1173150103, 1173152611, 1173163993, 1173174127, 1173204679,
					1173237343, 1173252107, 1173253331, 1173255653, 1173260183, 1173262943, 1173265439, 1173279091,
					1173285331, 1173286771, 1173288593, 1173298123, 1173302129, 1173308827, 1173310451, 1173312383,
					1173313571, 1173324371, 1173361529, 1173385729, 1173387217, 1173387361, 1173420799, 1173421499,
					1173423077, 1173428083, 1173442159, 1173445549, 1173451681, 1173453299, 1173454729, 1173458401,
					1173459491, 1173464177, 1173468943, 1173470041, 1173477947, 1173500677, 1173507869, 1173522919,
					1173537359, 1173605003, 1173610253, 1173632671, 1173653623, 1173665447, 1173675577, 1173675787,
					1173684683, 1173691109, 1173696907, 1173705257, 1173705523, 1173725389, 1173727601, 1173741953,
					1173747577, 1173751499, 1173759449, 1173760943, 1173761429, 1173762509, 1173769939, 1173771233,
					1173778937, 1173784637, 1173793289, 1173799607, 1173802823, 1173808003, 1173810919, 1173818311,
					1173819293, 1173828167, 1173846677, 1173848941, 1173853249, 1173858341, 1173891613, 1173894053,
					1173908039, 1173909203, 1173961541, 1173968989, 1173999193};
			mod = RandomPick(mods);
			int[] primes = { 59, 61, 67, 71, 73, 79, 83, 89, 97, 101 };
			prime = RandomPick(primes);
		}
		prepow[0] = 1;
		if (!reverse) {

			for (int i = 1; i < prelen; i++) {
				prepow[i] = (int) ((1l * prepow[i - 1] * prime) % mod);

			}
			for (int i = 0; i < prelen; i++) {
				if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z')
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'a' + 1) * prepow[i]) % mod) % mod);
				else
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'A' + 27) * prepow[i]) % mod) % mod);
			}

		} else {
			for (int i = 1; i < prelen; i++) {
				prepow[i] = (int) ((1l * prepow[i - 1] * prime) % mod);

			}
			for (int i = 0; i < prelen; i++) {
				if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z')
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'a' + 1) * prepow[prelen - 1 - i]) % mod) % mod);
				else
					HashsArray[HashsArrayInd][i + 1] = (int) ((1l * HashsArray[HashsArrayInd][i]
							+ ((1l * s.charAt(i) - 'A' + 27) * prepow[prelen - 1 - i]) % mod) % mod);
			}

		}

		HashsArrayInd++;

	}

	public static int PHV(int l, int r, int n, boolean reverse) {
		if (l > r) {
			return 0;
		}
		int val = (int) ((1l * HashsArray[n - 1][r] + mod - HashsArray[n - 1][l - 1]) % mod);
		if (!reverse) {

			val = (int) ((1l * val * prepow[prelen - l]) % mod);
		} else {
			val = (int) ((1l * val * prepow[r - 1]) % mod);
		}
		return val;
	}

    public static void genprime(int n) {
    	 boolean prime[] = new boolean[n+1];
         for(int i=0;i<n;i++)
             prime[i] = true;

         for(int p = 2; p*p <=n; p++)
         {
             if(prime[p] == true)
             {
                 for(int i = p*p; i <= n; i += p)
                     prime[i] = false;
             }
         }
         for(int i = 2; i <= n; i++)
         {
             if(prime[i] == true) {
                primes.put(i,primes.size());
                primes2.put(primes2.size(),i);
             }

         }
    }

    public static void primeFactors(int n)
    {
        while (n % 2 == 0) {
            primefact.put(2,primefact.getOrDefault(2, 0)+1);
            n /= 2;
        }

        for (int i = 3; i <= Math.sqrt(n); i += 2) {
            while (n % i == 0) {
                primefact.put(i,primefact.getOrDefault(i, 0)+1);
                n /= i;
            }
        }

        if (n > 2)
            primefact.put(n,primefact.getOrDefault(n, 0)+1);
    }
    public static long LSB(long x) {
		return x&-x;
	}
	static class fenwick {
		long[] arr;
		public fenwick(int[] a) {
			arr=new long[a.length+1];
			for(int i=1;i<=a.length;i++) {
				arr[i]+=a[i-1];
				if(i+LSB(i)<=a.length) {
					arr[(int) (i+LSB(i))]+=arr[i];
				}
			}
		}public fenwick(long[] a) {
			arr=new long[a.length+1];
			for(int i=1;i<=a.length;i++) {
				arr[i]+=a[i];
				if(i+LSB(i)<=a.length) {
					arr[(int) (i+LSB(i))]+=arr[i];
				}
			}
		}
		public void update(int ind,long x) {
			int i=ind;
			while(i<arr.length) {
				arr[i]+=x;
				i+=LSB(i);
			}
		}
		public long PrefixSum(int ind) {
			long sum=0;
			int i=ind;
			while(i>0) {
				sum+=arr[i];
				i=(int) (i-LSB(i));
			}
			return sum;
		}
		public long RangeQuerey(int l,int r) {
			return  this.PrefixSum(r+1)-this.PrefixSum(l);
		}
	}
	static TreeMap<Integer,Integer>primes=new TreeMap<Integer, Integer>();
	static TreeMap<Integer,Integer>primes2=new TreeMap<Integer, Integer>();
    static TreeMap<Integer,Integer>primefact=new TreeMap<Integer, Integer>();
	static int[][] HashsArray;
	static int HashsArrayInd = 0;
	static int[] prepow;
	static int prelen = 0;
	static int prime = 61;
	static long fac[];
	static int mod = 1000000007;
	static Random rn = new Random();
	static Scanner sc = new Scanner(System.in);
	static PrintWriter pw = new PrintWriter(System.out);
}

import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

public final class round_450_b
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long mod=(long)(1e9+7);

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

    public static void main(String args[]) throws Exception
    {
		long x=sc.nextLong(),y=sc.nextLong();

		List<Long> divs=new ArrayList<>();

		for(long i=1;i*i<=y;i++)
		{
			if(y%i==0)
			{
				divs.add(i);
			}

			if(i!=(y/i))
			{
				divs.add(y/i);
			}
		}

		if(y%x!=0)
		{
			out.println(0);
		}

		else
		{
			List<Pair> list=new ArrayList<>();

			for(long z:divs)
			{
				if(z>=x)
				{
					long now=pow(2,(y/z)-1);

					list.add(new Pair(z,now));
				}
			}

			Collections.sort(list);

			for(int i=list.size()-1;i>=0;i--)
			{
				long now=list.get(i).val;

				for(int j=i+1;j<list.size();j++)
				{
					if(list.get(j).idx%list.get(i).idx==0)
					{
						now=(now-list.get(j).val+mod)%mod;
					}
				}

				Pair p=new Pair(list.get(i).idx,now);

				list.set(i,p);
			}

			out.println(list.get(0).val);
		}

		out.close();
    }

	private static class Pair implements Comparable<Pair>
	{
		long idx,val;

		public Pair(long idx,long val)
		{
			this.idx=idx;this.val=val;
		}

		public int compareTo(Pair x)
		{
			return Long.compare(this.idx,x.idx);
		}
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:b>=a?gcd(b%a,a):gcd(b,a);
	}
	ArrayList<Integer> rec=new ArrayList<>();
	void work() {
		int a=in.nextInt(),b=in.nextInt();
		if(b%a!=0) {
			out.println(0);
			return;
		}
		b/=a;
		for(int i=2;i*i<=b;i++) {
			if(b%i==0) {
				rec.add(i);
				if(i!=b/i)rec.add(b/i);
			}
		}
		out.println(find(b));
	}
	private long find(int b) {
		long r=(pow(2,b-1)-1+mod)%mod;
		for(int k:rec) {
			if(b%k==0) {
				r-=find(b/k);
				r=(r+mod)%mod;
			}
		}
		return r;
	}
	private long pow(long a, long b) {
		long r=1;
		while(b>0) {
			if(b%2==1) {
				r*=a;
				r%=mod;
			}
			b/=2;
			a*=a;
			a%=mod;
		}
		return r;
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt()
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:b>=a?gcd(b%a,a):gcd(b,a);
	}
	ArrayList<Integer> rec=new ArrayList<>();
	void work() {
		int a=in.nextInt(),b=in.nextInt();
		if(b%a!=0) {
			out.println(0);
			return;
		}
		b/=a;
		for(int i=2;i*i<=b;i++) {
			if(b%i==0) {
				rec.add(i);
				rec.add(b/i);
			}
		}
		out.println(find(b));
	}
	private long find(int b) {
		long r=(pow(2,b-1)-1+mod)%mod;
		for(int k:rec) {
			if(b%k==0) {
				r-=find(b/k);
				r=(r+mod)%mod;
			}
		}
		return r;
	}
	private long pow(long a, long b) {
		long r=1;
		while(b>0) {
			if(b%2==1) {
				r*=a;
				r%=mod;
			}
			b/=2;
			a*=a;
			a%=mod;
		}
		return r;
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt()
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

import java.io.*;
import java.util.*;
import java.math.BigInteger;
import java.util.Map.Entry;

import static java.lang.Math.*;

public class D extends PrintWriter {

    long mod = 1_000_000_000 + 7;

    long solve(int d, int b) {
        return (mu(b) * pow(2, d - 1)) % mod;
    }

    long solve(int sum) {

        long ans = 0;

        for (int d = 1; d * d <= sum; d++) {
            if (sum % d == 0) {
                int b = sum / d;
                ans = (ans + solve(d, b)) % mod;
                if (b != d) {
                    ans = (ans + solve(b, d)) % mod;
                }
            }
        }

        return ans;
    }

    int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    long pow(long a, long b) {
        long c = 1;

        for (; b > 0; b /= 2) {
            if (b % 2 == 1) {
                c = (c * a) % mod;
            }
            a = (a * a) % mod;
        }

        return c;
    }

    int mu(int num) {
        int cnt = 1;

        for (int d = 2; d * d <= num; d++) {
            int cur = 0;

            while (num % d == 0) {
                ++cur;
                num /= d;
            }

            if (cur > 1) {
                return 0;
            }

            if (cur == 1) {
                ++cnt;
            }
        }

        if (num > 1) {
            ++cnt;
        }

        return (cnt % 2) * 2 - 1;
    }

    void run() {

        int x = nextInt(), y = nextInt();
        if (y % x == 0) {
            println(solve(y / x));
        } else {
            println(0);
        }
    }

    boolean skip() {
        while (hasNext()) {
            next();
        }
        return true;
    }

    int[][] nextMatrix(int n, int m) {
        int[][] matrix = new int[n][m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                matrix[i][j] = nextInt();
        return matrix;
    }

    String next() {
        while (!tokenizer.hasMoreTokens())
            tokenizer = new StringTokenizer(nextLine());
        return tokenizer.nextToken();
    }

    boolean hasNext() {
        while (!tokenizer.hasMoreTokens()) {
            String line = nextLine();
            if (line == null) {
                return false;
            }
            tokenizer = new StringTokenizer(line);
        }
        return true;
    }

    int[] nextArray(int n) {
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = nextInt();
        }
        return array;
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException err) {
            return null;
        }
    }

    public D(OutputStream outputStream) {
        super(outputStream);
    }

    static BufferedReader reader;
    static StringTokenizer tokenizer = new StringTokenizer("");
    static Random rnd = new Random();
    static boolean OJ;

    public static void main(String[] args) throws IOException {
        OJ = System.getProperty("ONLINE_JUDGE") != null;
        D solution = new D(System.out);
        if (OJ) {
            reader = new BufferedReader(new InputStreamReader(System.in));
            solution.run();
        } else {
            reader = new BufferedReader(new FileReader(new File(D.class.getName() + ".txt")));
            long timeout = System.currentTimeMillis();
            while (solution.hasNext()) {
                solution.run();
                solution.println();
                solution.println("----------------------------------");
            }
            solution.println("time: " + (System.currentTimeMillis() - timeout));
        }
        solution.close();
        reader.close();
    }
}

//package Codeforces450;

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * Created by Pranav ps on 16-12-2017.
 */

/**
 * This is the template for all coding problems
 */
public class D {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, in, out);
        out.close();
    }
    static class Task {
        private long MOD = (long)(1e9+7);
        private HashMap<Long,Long> hm;
        private ArrayList<Long> divisors;
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long x = in.nextLong();
            long y = in.nextLong();
            if(y%x != 0){
                out.println(0);
                return;
            }
            y /= x;
            hm = new HashMap<>();
            divisors = fDivisors(y);

            out.println(dp(y));
        }

        private long dp(long y) {
            if(y==1)
                return 1;
            if(hm.containsKey(y))
                return hm.get(y);
            long ans = pow(y-1);
            for (Long d: divisors) {
                if(d>y)
                    break;
                if(y%d == 0)
                    ans = (ans - dp(y/d) + MOD)%MOD;
            }
            hm.put(y,ans);
            return ans;
        }

        private long pow(long l) {
            if(l == 0)
                return 1;
            long ans = 1;
            if(l%2 == 1)
                ans *= 2;
            long local = pow(l/2);
            local = (local*local)%MOD;
            ans = (ans*local)%MOD;
            return ans;
        }

        private ArrayList<Long> fDivisors(long y) {
            ArrayList<Long> al = new ArrayList<>();
            for (long i = 2; i*i <= y; i++) {
                if(y%i == 0)
                    al.add(i);
            }
            al.add(y);
            return al;
        }
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}

import java.util.*;
import java.io.*;
import java.math.*;
public class A{
    class Node implements Comparable<Node> {
        int id;
        int d;
        public Node(int id,int d){
            this.id=id;
            this.d=d;
        }
        public int compareTo(Node c){
            return this.id-c.id;
        }
    }
    void solve(){
        long x=nl(); long y=nl();
        if(y%x!=0){
            pw.println(0);
            return;
        }
        y/=x;
        long ans=0;
        for(int i=1;i*i<=y;i++){
            if(y%i==0){
                ans=(ans+(mobius(i)*modPow(2,y/i-1,M))%M)%M;
                if(y/i!=i){
                    long d=y/i;
                    ans=(ans+(mobius(d)*modPow(2,y/d-1,M))%M)%M;
                }
            }
        }
        pw.println(ans);

    }
    int mobius(long n){
        int cnt=0;
        for(int i=2;i*i<=n;i++){
            if(n%i==0){
                cnt++;
                n/=i;
                if(n%i==0)return 0;
            }
        }
        if(n>1)cnt++;
        if(cnt%2==0)return 1;
        else return -1;
    }
    static long modPow(long x,long y,long M){
        if(y==0) return 1;
        if(y%2==0) return modPow((x*x)%M,y/2,M)%M;
        else return (x*modPow((x*x)%M,(y-1)/2,M))%M;
    }

    long M=(long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";
    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception { new A().run(); }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private void tr(Object... o) { if(INPUT.length() > 0)System.out.println(Arrays.deepToString(o)); }
}

import java.util.*;
import java.io.*;
import java.math.*;
public class A{

    void solve(){
        long x=nl(); long y=nl();
        if((y-x)%x!=0){
            pw.println(0);
            return;
        }
       long m=(y-x)/x;
       long ans=((m-1)*modPow(2,m-2,M))%M;
       ans=(ans+modPow(2,m-1,M))%M;
       pw.println(ans);

    }
    long M=(long)1e9+7;
    static long modPow(long x,long y,long M){
        if(y==0) return 1;
        if(y%2==0) return modPow((x*x)%M,y/2,M)%M;
        else return (x*modPow((x*x)%M,(y-1)/2,M))%M;
    }

    InputStream is;
    PrintWriter pw;
    String INPUT = "";
    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception { new A().run(); }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private void tr(Object... o) { if(INPUT.length() > 0)System.out.println(Arrays.deepToString(o)); }
}

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.List;
 import java.util.*;
 public class realfast implements Runnable
  {
    private static final int INF = (int) 1e9;
    long in= (long)Math.pow(10,9)+7;
    long fac[]= new long[3000];
    public  void solve() throws IOException
    {
         long m = in;

       long x = readLong();
       long y = readLong();

       if((y%x)!=0)
        out.println(0);
       else
       {
            ArrayList<Integer> arr = new ArrayList<>();
            long len = y/x;
            int root = (int)Math.pow(len,0.5);

            for(int i=1;i<=root;i++)
            {
                if(len%i==0)
                {
                     long val =len/i;
                     arr.add(i);
                     if(val!=i)
                        arr.add((int)val);
                }
            }
            Collections.sort(arr);
            int count[]= new int [arr.size()];
            for(int i=0;i<arr.size();i++)
            {
                long val1 = arr.get(i);
                for(int j=i+1;j<arr.size();j++)
                {
                       long val = arr.get(j);
                       if(val%val1==0)
                       {
                              count[j]= count[i]+1;
                       }
                }
            }
            long ans =0;
            for(int i=0;i<arr.size();i++)
            {
                long cal = (long)arr.get(i);
                if(count[i]%2==0)
                ans= (ans%in +pow(2,(len/cal)-1,in)%in)%in;
                else
                ans = (ans%in -pow(2,(len/cal)-1,in)+in)%in;
            }

            out.println(ans);
       }

    }
    public int gcd(int a , int b )
    {
      if(a<b)
      {
        int t =a;
        a=b;
        b=t;
      }
      if(a%b==0)
        return b ;
      return gcd(b,a%b);
    }
    public long pow(long n , long p,long m)
    {
         if(p==0)
            return 1;
        long val = pow(n,p/2,m);;
        val= (val*val)%m;
        if(p%2==0)
            return val;
        else
            return (val*n)%m;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public static void main(String[] args) {
        new Thread(null, new realfast(), "", 128 * (1L << 20)).start();
    }

    private static final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;
    private BufferedReader reader;
    private StringTokenizer tokenizer;
    private PrintWriter out;

    @Override
    public void run() {
        try {
            if (ONLINE_JUDGE || !new File("input.txt").exists()) {
                reader = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                reader = new BufferedReader(new FileReader("input.txt"));
                out = new PrintWriter("output.txt");
            }
            solve();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                // nothing
            }
            out.close();
        }
    }

    private String readString() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }

    @SuppressWarnings("unused")
    private int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    @SuppressWarnings("unused")
    private long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    @SuppressWarnings("unused")
    private double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }
}
class edge implements Comparable<edge>{
    int val ;
    int color;

    edge(int u, int v)
    {
       this.val=u;
       this.color=v;
    }
    public int compareTo(edge e)
    {
        return this.val-e.val;
    }
}

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.List;
 import java.util.*;
 public class realfast implements Runnable
  {
    private static final int INF = (int) 1e9;
    long in= (long)Math.pow(10,9)+7;
    long fac[]= new long[3000];
    public  void solve() throws IOException
    {
         long m = in;

       int x = readInt();
       int y = readInt();

       if((y%x)!=0)
        out.println(0);
       else
       {
            int len =y/x;

            int root = (int)Math.pow(len,0.5);
            ArrayList<Integer> arr = new ArrayList<>();
            for(int i =1;i<=root;i++)
            {
                if(len%i==0)
                {
                    int j = len/i;
                    arr.add(i);
                    if(j!=i)
                        arr.add(j);
                }
            }
            Collections.sort(arr);
            long dp[]= new long[arr.size()];
            dp[arr.size()-1]=1;
            for(int i=arr.size()-2;i>=0;i--)
            {
                int yo = arr.get(i);
                dp[i]= pow(2,len/yo-1,in);
                for(int j=i+1;j<arr.size();j++)
                {
                    dp[i]= (dp[i]%in-dp[j]%in+in)%in;
                }
            }
            out.println(dp[0]);
       }

    }
    public int gcd(int a , int b )
    {
      if(a<b)
      {
        int t =a;
        a=b;
        b=t;
      }
      if(a%b==0)
        return b ;
      return gcd(b,a%b);
    }
    public long pow(long n , long p,long m)
    {
         if(p==0)
            return 1;
        long val = pow(n,p/2,m);;
        val= (val*val)%m;
        if(p%2==0)
            return val;
        else
            return (val*n)%m;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public static void main(String[] args) {
        new Thread(null, new realfast(), "", 128 * (1L << 20)).start();
    }

    private static final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;
    private BufferedReader reader;
    private StringTokenizer tokenizer;
    private PrintWriter out;

    @Override
    public void run() {
        try {
            if (ONLINE_JUDGE || !new File("input.txt").exists()) {
                reader = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                reader = new BufferedReader(new FileReader("input.txt"));
                out = new PrintWriter("output.txt");
            }
            solve();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                // nothing
            }
            out.close();
        }
    }

    private String readString() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }

    @SuppressWarnings("unused")
    private int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    @SuppressWarnings("unused")
    private long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    @SuppressWarnings("unused")
    private double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }
}
class edge implements Comparable<edge>{
    int val ;
    int color;

    edge(int u, int v)
    {
       this.val=u;
       this.color=v;
    }
    public int compareTo(edge e)
    {
        return this.val-e.val;
    }
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class D
{
	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();
		ArrayList<Integer> div = new ArrayList<Integer>();
		for (int i = 1; i*i <= y; i++)
		{
			if(y%i == 0)
			{
				div.add(i);
				if(i != y/i)
					div.add(y/i);
			}
		}

		if(y%x != 0)
		{
			System.out.println(0);
			return;
		}
		int n = y/x;
		long ans = calc(n);

		boolean[] taken = new boolean[div.size()];
		for (int i = 0; i < taken.length; i++)
		{
			if(!taken[i])
			{
				int v = div.get(i);
				if(v % x == 0 && y%v == 0&& v > x)
				{
					ans -= calc(y/v);
					if(ans < 0)
						ans += MOD;
					for (int j = 0; j < taken.length; j++)
					{
						if(div.get(j)%v == 0)
							taken[j] = true;
					}
				}
			}
		}

		System.out.println(ans);
		pw.flush();
		pw.close();
	}

	static int MOD = 1000000007;
	static long calc(int n)
	{
		return modPow(2, n-1, MOD);
	}

	static long modPow(long a, long e, int mod)	// O(log e)
	{
		a %= mod;
		long res = 1;
		while(e > 0)
		{
			if((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s)
		{
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException
		{
			br = new BufferedReader(new FileReader(new File((s))));
		}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException
		{
			return br.readLine();
		}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else
				{
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException
		{
			return br.ready();
		}
	}
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.StringTokenizer;

public class D
{
	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();
		ArrayList<Integer> div = new ArrayList<Integer>();
		for (int i = 1; i*i <= y; i++)
		{
			if(y%i == 0)
			{
				div.add(i);
				if(i != y/i)
					div.add(y/i);
			}
		}

		if(y%x != 0)
		{
			System.out.println(0);
			return;
		}
		int n = y/x;
		int ans = calc(n);

		int[] occ = new int[div.size()];
		for (int i = 0; i < occ.length; i++)
			if(div.get(i)%x == 0)
				occ[i]++;
		Collections.sort(div);
		boolean[] taken = new boolean[div.size()];
		for (int i = 0; i < taken.length; i++)
		{
			if(occ[i] != 0)
			{
				int v = div.get(i);
				if(v % x == 0 && v > x)
				{
//					ans -= calc(y/v);
					ans = minus(ans, mul(occ[i], calc(y/v)));
//					if(ans < 0)
//						ans += MOD;
					for (int j = i; j < taken.length; j++)
					{
						if(div.get(j)%v == 0)
//							taken[j] = true;
							occ[j] -= occ[i];
					}
				}
			}
		}

		System.out.println(ans);
		pw.flush();
		pw.close();
	}

	private static int mul(int a, int b)
	{
		return (int)(((long)a*b)%MOD);
	}

	private static int minus(int a, int b)
	{
		int ans = a-b;
		ans =  (ans%MOD);
		if(ans < 0)
			ans += MOD;
		return ans;

	}

	static int MOD = 1000000007;
	static int calc(int n)
	{
		return (int)modPow(2, n-1, MOD);
	}

	static long modPow(long a, long e, int mod)	// O(log e)
	{
		a %= mod;
		long res = 1;
		while(e > 0)
		{
			if((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s)
		{
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException
		{
			br = new BufferedReader(new FileReader(new File((s))));
		}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException
		{
			return br.readLine();
		}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else
				{
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException
		{
			return br.ready();
		}
	}
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.StringTokenizer;

public class D
{
	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();
		ArrayList<Integer> div = new ArrayList<Integer>();
		for (int i = 1; i*i <= y; i++)
		{
			if(y%i == 0)
			{
				div.add(i);
				if(i != y/i)
					div.add(y/i);
			}
		}

		if(y%x != 0)
		{
			System.out.println(0);
			return;
		}
		int n = y/x;
		int ans = calc(n);

		int[] occ = new int[div.size()];
		for (int i = 0; i < occ.length; i++)
			if(div.get(i)%n == 0)
				occ[i]++;
		Collections.sort(div);
		boolean[] taken = new boolean[div.size()];
		for (int i = 0; i < taken.length; i++)
		{
			if(occ[i] != 0)
			{
				int v = div.get(i);
				if(v % x == 0 && v > x)
				{
//					ans -= calc(y/v);
					ans = minus(ans, mul(occ[i], calc(y/v)));
//					if(ans < 0)
//						ans += MOD;
					for (int j = i; j < taken.length; j++)
					{
						if(div.get(j)%v == 0)
//							taken[j] = true;
							occ[j] -= occ[i];
					}
				}
			}
		}

		System.out.println(ans);
		pw.flush();
		pw.close();
	}

	private static int mul(int a, int b)
	{
		return (int)(((long)a*b)%MOD);
	}

	private static int minus(int a, int b)
	{
		int ans = a-b;
		ans =  (ans%MOD);
		if(ans < 0)
			ans += MOD;
		return ans;

	}

	static int MOD = 1000000007;
	static int calc(int n)
	{
		return (int)modPow(2, n-1, MOD);
	}

	static long modPow(long a, long e, int mod)	// O(log e)
	{
		a %= mod;
		long res = 1;
		while(e > 0)
		{
			if((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s)
		{
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException
		{
			br = new BufferedReader(new FileReader(new File((s))));
		}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException
		{
			return br.readLine();
		}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else
				{
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException
		{
			return br.ready();
		}
	}
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.StringTokenizer;

public class D
{
	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int x = sc.nextInt();
		int y = sc.nextInt();
		ArrayList<Integer> div = new ArrayList<Integer>();
		for (int i = 1; i*i <= y; i++)
		{
			if(y%i == 0)
			{
				div.add(i);
				if(i != y/i)
					div.add(y/i);
			}
		}

		if(y%x != 0)
		{
			System.out.println(0);
			return;
		}
		int n = y/x;
		int ans = calc(n);

		int[] occ = new int[div.size()];
		for (int i = 0; i < occ.length; i++)
			if(div.get(i)%x == 0)
				occ[i]++;
		Collections.sort(div);
		boolean[] taken = new boolean[div.size()];
		for (int i = 0; i < taken.length; i++)
		{
			if(occ[i] != 0)
			{
				int v = div.get(i);
				if(v % x == 0 && v > x)
				{
//					ans -= calc(y/v);
					ans = minus(ans, mul(occ[i], calc(y/v)));
//					if(ans < 0)
//						ans += MOD;
					int mm = occ[i];
					for (int j = i; j < taken.length; j++)
					{
						if(div.get(j)%v == 0)
//							taken[j] = true;
							occ[j] -= mm;
					}
				}
			}
		}

		System.out.println(ans);
		pw.flush();
		pw.close();
	}

	private static int mul(int a, int b)
	{
		return (int)(((long)a*b)%MOD);
	}

	private static int minus(int a, int b)
	{
		int ans = a-b;
		ans =  (ans%MOD);
		if(ans < 0)
			ans += MOD;
		return ans;

	}

	static int MOD = 1000000007;
	static int calc(int n)
	{
		return (int)modPow(2, n-1, MOD);
	}

	static long modPow(long a, long e, int mod)	// O(log e)
	{
		a %= mod;
		long res = 1;
		while(e > 0)
		{
			if((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s)
		{
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException
		{
			br = new BufferedReader(new FileReader(new File((s))));
		}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException
		{
			return br.readLine();
		}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else
				{
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException
		{
			return br.ready();
		}
	}
}

import java.io.*;
import java.math.*;
import java.security.KeyStore.Entry;
import java.util.*;

public class SPOJANDCC
{
	@SuppressWarnings("rawtypes")
	static InputReader in;
	static PrintWriter out;

	static int mod = (int) 1e9 + 7;

	static int pow(long x, long y)
	{
		long ans = 1;
		while (y > 0)
		{
			if ((y & 1) == 1)
				ans = (ans * x) % mod;
			x = (x * x) % mod;
			y >>= 1;
		}
		return (int) ans;
	}

	static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

	static int cnt(int n)
	{
		if (map.containsKey(n))
			return map.get(n);
		int ans = pow(2, n - 1);
		int tmp = 1;
		for (int i = 2; i * i <= n; i++)
		{
			if (n % i == 0)
			{
				ans = ans - cnt(n / i);
				tmp = 0;
				if (ans < 0)
					ans += mod;
			}
			if (i * i != n)
			{
				ans = ans - cnt(i);
				tmp = 0;
				if (ans < 0)
					ans += mod;
			}
		}
		ans = ans - tmp;
		if (ans < 0)
			ans += mod;
		map.put(n, ans);
		return ans;
	}

	static void solve()
	{
		int x = in.ni(), y = in.ni();
		if (y % x != 0)
			out.println("0");
		else
			out.println(cnt(y / x));
	}

	@SuppressWarnings("rawtypes")
	static void soln()
	{
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	public static void main(String[] args)
	{
		new Thread(null, new Runnable()
		{
			public void run()
			{
				try
				{
					soln();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}, "1", 1 << 26).start();
	}

	static class InputReader<SpaceCharFilter>
	{

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int snext()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = stream.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int ni()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nl()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = ni();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nl();
			}
			return a;
		}

		public String readString()
		{
			int c = snext();
			while (isSpaceChar(c))
			{
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine()
		{
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}

	}
}

import javax.swing.plaf.synth.SynthEditorPaneUI;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Contest1 {
    static int [] fac, count;
    static void sivie(int n ){
        fac= new int[n+1];
        count= new int[n+1];
        Arrays.fill(fac,1);
        for (int i =2;i<=n;i++){
            if (fac[i]==1){
                fac[i]=i;
                count[i]=1;
                for (int j = i*2;j<=n;j+=i) {
                    fac[j] *= i;
                    count[j]++;
                }
            }
        }
    }
    static int mod = (int)1e9+7;
    static long modpow(long a ,long ex ){
        long res=1;
        while (ex>0){
            if (ex%2==1)
                res=(res*a)%mod;
            a*=a;
            a%=mod;
            ex>>=1;
        }
        return res;
    }
    static long get(int x,int f){
        if (f<fac.length){
            if (f!=fac[f])
                return 0;
            long ret = modpow(2,x-1);
            return ret*(count[f]%2==0?1:-1);
        }
        else {
            ArrayList<Integer>facs = new ArrayList<>();
            int c = f;
            long val=1;
            for (int j =2;1l*j*j<=f;j++){
                if (c%j==0){
                    facs.add(j);
                    while (c%j==0){
                        c/=j;
                        val*=j;
                    }
                }
            }
            if (c!=0){
                val*=c;
                facs.add(c);
            }
            if (val!=f)
                return 0;
            long here = modpow(2,x-1);
            return here*(facs.size()%2==0?1:-1);
        }
    }
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        sivie((int)1e5);
        int x = sc.nextInt();
        int y = sc.nextInt();

        if (y%x!=0){
            pw.println(0);
        }
        else {
            long ans = modpow(2,y/x -1)+get(1,y/x);
            ans+=mod;
            ans%=mod;
            int v = y/x;
            for (int j =2;1l*j*j<=v;j++){
                if (v%j==0){
                    long c= get(v/j,j);
                    ans+=c+mod;
                    ans%=mod;
                    if (j!=v/j)
                        ans+=get(j,v/j);
                }
            }
            pw.println(ans);
        }
        pw.flush();
    }
    static long gcd(long a,long b){
        if (a==0)
            return b;
        return gcd(b%a,a);
    }
    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(FileReader r) {
            br = new BufferedReader(r);
        }

        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public String nextLine() throws IOException {
            return br.readLine();
        }

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++)
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec)
                        f *= 10;
                }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

        public boolean ready() throws IOException {
            return br.ready();
        }
    }
}

import javax.swing.plaf.synth.SynthEditorPaneUI;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Contest1 {
    static int [] fac, count;
    static void sivie(int n ){
        fac= new int[n+1];
        count= new int[n+1];
        Arrays.fill(fac,1);
        for (int i =2;i<=n;i++){
            if (fac[i]==1){
                fac[i]=i;
                count[i]=1;
                for (int j = i*2;j<=n;j+=i) {
                    fac[j] *= i;
                    count[j]++;
                }
            }
        }
    }
    static int mod = (int)1e9+7;
    static long modpow(long a ,long ex ){
        long res=1;
        while (ex>0){
            if (ex%2==1)
                res=(res*a)%mod;
            a*=a;
            a%=mod;
            ex>>=1;
        }
        return res;
    }
    static long get(int x,int f){
        if ( f<=1)
            return 0;
        if (f<fac.length){
            if (f!=fac[f])
                return 0;
            long ret = modpow(2,x-1);
            return ret*(count[f]%2==0?1:-1);
        }
        else {
            ArrayList<Integer>facs = new ArrayList<>();
            int c = f;
            long val=1;
            for (int j =2;1l*j*j<=f;j++){
                if (c%j==0){
                    facs.add(j);
                    while (c%j==0){
                        c/=j;
                        val*=j;
                    }
                }
            }
            if (c!=0){
                val*=c;
                facs.add(c);
            }
            if (val!=f)
                return 0;
            long here = modpow(2,x-1);
            return here*(facs.size()%2==0?1:-1);
        }
    }
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        sivie((int)1e5);
        int x = sc.nextInt();
        int y = sc.nextInt();

        if (y%x!=0){
            pw.println(0);
        }
        else {
            long ans = modpow(2,y/x -1)+get(1,y/x);
            ans+=mod;
            ans%=mod;
            int v = y/x;
            for (int j =2;1l*j*j<=v;j++){
                if (v%j==0){
                    long c= get(v/j,j);
                    ans+=c+mod;
                    ans%=mod;
                    if (j!=v/j)
                        ans+=get(j,v/j);
                }
            }
            pw.println(ans);
        }
        pw.flush();
    }
    static long gcd(long a,long b){
        if (a==0)
            return b;
        return gcd(b%a,a);
    }
    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(FileReader r) {
            br = new BufferedReader(r);
        }

        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public String nextLine() throws IOException {
            return br.readLine();
        }

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++)
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec)
                        f *= 10;
                }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

        public boolean ready() throws IOException {
            return br.ready();
        }
    }
}

import javax.swing.plaf.synth.SynthEditorPaneUI;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Contest1 {
    static int [] fac, count;
    static void sivie(int n ){
        fac= new int[n+1];
        count= new int[n+1];
        Arrays.fill(fac,1);
        for (int i =2;i<=n;i++){
            if (fac[i]==1){
                fac[i]=i;
                count[i]=1;
                for (int j = i*2;j<=n;j+=i) {
                    fac[j] *= i;
                    count[j]++;
                }
            }
        }
    }
    static int mod = (int)1e9+7;
    static long modpow(long a ,long ex ){
        long res=1;
        while (ex>0){
            if (ex%2==1)
                res=(res*a)%mod;
            a*=a;
            a%=mod;
            ex>>=1;
        }
        return res;
    }
    static long get(int x){
        if (x<fac.length){
            if (x!=fac[x])
                return 0;
            long ret = modpow(2,x-1);
            return ret*(count[x]%2==0?1:-1);
        }
        else {
            ArrayList<Integer>facs = new ArrayList<>();
            int c = x;
            long val=1;
            for (int j =2;1l*j*j<=x;j++){
                if (c%j==0){
                    facs.add(j);
                    while (c%j==0){
                        c/=j;
                        val*=j;
                    }
                }
            }
            if (c!=0){
                val*=c;
                facs.add(c);
            }
            if (val!=x)
                return 0;
            long here = modpow(2,x-1);
            return here*(facs.size()%2==0?1:-1);
        }
    }
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        sivie((int)1e5);
        int x = sc.nextInt();
        int y = sc.nextInt();

        if (y%x!=0){
            pw.println(0);
        }
        else {
            long ans = modpow(2,y/x -1)-1;
            int v = y/x;
            for (int j =2;1l*j*j<=v;j++){
                if (v%j==0){
                    long c= get(v/j);
                    ans+=c+mod;
                    ans%=mod;
                    if (j!=v/j)
                        ans+=get(j);
                }
            }
            pw.println(ans);
        }
        pw.flush();
    }
    static long gcd(long a,long b){
        if (a==0)
            return b;
        return gcd(b%a,a);
    }
    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(FileReader r) {
            br = new BufferedReader(r);
        }

        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public String nextLine() throws IOException {
            return br.readLine();
        }

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++)
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec)
                        f *= 10;
                }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

        public boolean ready() throws IOException {
            return br.ready();
        }
    }
}

import javax.swing.plaf.synth.SynthEditorPaneUI;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Contest1 {
    static int [] fac, count;
    static void sivie(int n ){
        fac= new int[n+1];
        count= new int[n+1];
        Arrays.fill(fac,1);
        for (int i =2;i<=n;i++){
            if (fac[i]==1){
                fac[i]=i;
                count[i]=1;
                for (int j = i*2;j<=n;j+=i) {
                    fac[j] *= i;
                    count[j]++;
                }
            }
        }
    }
    static int mod = (int)1e9+7;
    static long modpow(long a ,long ex ){
        long res=1;
        while (ex>0){
            if (ex%2==1)
                res=(res*a)%mod;
            a*=a;
            a%=mod;
            ex>>=1;
        }
        return res;
    }
    static long get(int x,int f){
        if ( f<=1)
            return 0;
        if (f<fac.length){
            if (f!=fac[f])
                return 0;
            long ret = modpow(2,x-1);
            return ret*(count[f]%2==0?1:-1);
        }
        else {
            ArrayList<Integer>facs = new ArrayList<>();
            int c = f;
            long val=1;
            for (int j =2;1l*j*j<=f;j++){
                if (c%j==0){
                    facs.add(j);
                    val*=j;
                    while (c%j==0){
                        c/=j;
                    }
                }
            }
            if (c!=0){
                val*=c;
                facs.add(c);
            }
            if (val!=f)
                return 0;
            long here = modpow(2,x-1);
            return here*(facs.size()%2==0?1:-1);
        }
    }
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        sivie((int)1e5);
        int x = sc.nextInt();
        int y = sc.nextInt();

        if (y%x!=0){
            pw.println(0);
        }
        else {
            long ans = modpow(2,y/x -1)+get(1,y/x);
            ans+=mod;
            ans%=mod;
            int v = y/x;
            for (int j =2;1l*j*j<=v;j++){
                if (v%j==0){
                    long c= get(v/j,j);
                    ans+=c+mod;
                    ans%=mod;
                    if (j!=v/j)
                        ans+=get(j,v/j);
                    ans+=mod;
                    ans%=mod;
                }
            }
            pw.println(ans);
        }
        pw.flush();
    }
    static long gcd(long a,long b){
        if (a==0)
            return b;
        return gcd(b%a,a);
    }
    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(FileReader r) {
            br = new BufferedReader(r);
        }

        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public String nextLine() throws IOException {
            return br.readLine();
        }

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++)
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec)
                        f *= 10;
                }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

        public boolean ready() throws IOException {
            return br.ready();
        }
    }
}