import java.util.*;

import java.util.List;
import java.util.ArrayList;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int n = in.nextInt();
        int m = in.nextInt();
        int[] step = new int[m +1]; //抛弃0下标,我们从1下标开始,这样可以和n,m对应
        for (int i = 0; i < m + 1; i++) {
            step[i] = Integer.MAX_VALUE; //先赋值,为了等下区分
        }
        step[n] = 0; //先把n下标定位为,因为是从n开始的,是第0步
        for (int i = n; i < m; i++) { //从n下标开始,到m下标结束
            if (step[i] == Integer.MAX_VALUE) { //代表走不到这里
                continue;//跳过当前i
            }
            //代表可以走到这里
            //获取约数
            List<Integer> list = div(i);
            for (int j :list) { //遍历得到的约数集合,j代表了往后面走的步数
                if (i + j <= m && step[i + j] == Integer.MAX_VALUE) { //代表还没有到达
                    step[i + j] = step[i] + 1; //为前一步的加一
                } else if (i + j<= m &&step[i + j] != Integer.MAX_VALUE){//代表下面一步已经有人走了
                step[i+j] = Math.min(step[i + j],step[i] +1); //原有的路径步数和当前的再往后面走一步比较
                }
            }
        }
        if (step[m] == Integer.MAX_VALUE) {
            System.out.print(-1);//代表走不到
        } else {
            System.out.print(step[m]);
        }
    }
    //求约数的方法
    public static List<Integer> div(int num) {
        List<Integer> list = new ArrayList<>(); //存储约数
        for (int i = 2; i * i <= num;i++) { //约数不包括1和自己,而且只这里只求前面一块的
            if (num % i == 0) { //能被整除,代表是约数
                list.add(i);//约数放入集合
                if (num / i != i) {
                    list.add(num /i); //把另外一半放入集合,前提是两个约不相等(2×3放两次  4×4放一次)
                }
            }
        }
        return list;
    }
}

以例子举例:()里面代表从哪里走到当前下标的

--->1,从4下标开始,求得4的约数2,然后4往下走两步到6,

--->2,然后从6开始找约数:2,3,这时候分开两头走,可以走两步到8也可以走3步到9,

--->3,从8开始约数为2或4,到10和12 或者从9开始约数为3,到12

--->4,从10开始约数为2,5到12或15 或者从12开始约数为2,3,4,6到14,15,16,18

............

--->此时我们可以看到到达12的话可以是3步也可以是4步,那么我们需要最优的解,那当然就是3步了

--->总结出:我们可以走每一步(每一个约数都走一遍),但是在每一位下标下面存储的次数是只存储最小的次数,3步4步都可以到,那就是3步到的路径

--->不管哪条路径,只要你们到达同一个下标的位置,就代表在这里重合了,既然你们都可以到,那么我只要最短的

--->余下步骤以此类推

实现:

--->我们先定义m+1长度的数组:这是为了抛弃0下标,让我们可以让n下标就是n位置,m同样(我们下标

0到m--->1到m+1),m+1下标代表我们从1开始的m位置的元素

然后把数组每一个元素都赋相同的值,

--->定义n下标元素为0(因为是从n开始的,所以步数为0)

//走一遍理解

--->遍历数组元素(从n开始到m结束),首先因为是从n开始的,所以n下标的元素一定是0,我们找到n的约数,然后让n+约数下标的元素的值变为(0+1)(步),代表走一步到达这里,然后后面的以此类推,

---->但是切记,当多条路径重合的时候,我们的下标的元素值只取最小的那一步

核心实现:遍历数组元素,若当前下标元素是我们一开始设定的初始值,则代表不论哪条路径都达不到这里(从n开始,n下标加上的约数,那么n+1的下标元素可能就还是初始值),跳过,继续到下一位下标,比较是否是初始值

--->若不是的话,则代表当前下标可以有路径到达(且一定是最短的),

--->所以我们要比较(i+j)下标元素的大小(从当前下标走到下一步的位置), //j代表当前下标的约数

--->若i+j下标元素为初始值,则代表这是一条路径(从i下标走到i+j下标),若不是初始值,则代表i+j下标已经有路径到达了,所以我们要比较i+j下标原有的步数和我们现在走到i+j下标的步数,取最小值

--->就这样一直走下去,最后若m下标元素为初始值,则代表走不到m反之,m下标元素就是最小步数

--->怎么比较i+j下标元素的值

i+j原有的元素值和当前i下标的元素值+1(代表从i下标走到i+j下标走了一步)进行比较