#include <map>
#include <string>
#include <iostream>
#include <cctype>
#include <stack>
#include <vector>
using namespace std;
//判断x是不是质数
bool isprime(int x) {
    if (x == 2) return true;
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0) return false;
    }
    return true;
}
int main() {
    //注意:质因数我们不考虑1
    int n, a;
    while (cin >> n >> a) {
        vector<int>aa(1000, 0);//存储a的质因数 aa[i]代表质因数i有aa[i]个
        vector<int>nn(1000, 0);//存储n的阶乘的所有质因数
        //求解a的质因数
        int tt = a;
        for (int i = 2; i * i <= a; i++) {
            if (isprime(i))
                while (tt % i == 0) {
                    aa[i]++;
                    tt /= i;
                }
        }
        //注意要检查一下最后的t是不是1,如果不是1,一定是一个质数,后面判断其实可以省略
        //举个例子 将26分解 2*13,tt=13,13还没被检测出来就跳出循环了,所以循环出来要判断一下
        //相反,如果是12,分解为2*2*3,出来的时候tt是1,所以不必处理
        if (tt != 1 && isprime(tt)) aa[tt]++;
        //求解2~n的质因数 ---与求解a的质因数类似,只是需要求解2到n每一个数的质因数,进行叠加
        for (int j = 2; j <= n; j++) {

            int t = j;
            for (int i = 2; i * i <= j; i++) {

                if (isprime(i))

                    while (t % i == 0) {
                        nn[i]++;
                        t /= i;
                        if (t == i) break;//如果最后分解的结果是两个质数相乘,跳出即可
                    }
            }
            if (t != 1 && isprime(t)) nn[t]++;
        }
        int k = 0;
        //举个例子 a是2*5 n!=2*3*4**5*6=2*3*2*2*5*2*3
        //我们尝试去遍历a的每一个质因子,然后看看n!对应的质因子数目是a的多少倍,k就是其中的最小值,类似于短板效应
        //比如a有一个质因子2,一个质因子5,而n!虽然有4个质因子2,却只有一个质因子5,显然k应取决于质因子5的倍数关系,k至少也是0,所以初始化为0
        for (int i = 0; i < 1000; i++) {
            if (aa[i] > 0) {
                if (k == 0) k = nn[i] / aa[i];
                else k = min(nn[i] / aa[i], k);
            }
        }
        cout << k << endl;
    }
}
// 64 位输出请用 printf("%lld")