/*
* url: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1080
* stratege: 将除数m进行分解,分别求出质因子及其个数,然后对n进行判断,n中是否包含m的每个质因子下的个数,如果有,则可整除
* Test Case: 16 32768 yes, 32768 = 2^15, 16!包含15个因子2,可整除
* Status: 10537360 10139 Factovisors Accepted C++ 2.820 2012-08-29 07:45:15
* Author: johnsondu
*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std ;
#define LL long long
const int MAXN = 50000 ;
bool isPrime[MAXN] ;
int p[MAXN], prilen ;
bool flag ;
LL n, m ;
LL f[35][2], flen ;
void getPrime () //筛选素数
{
int i ;
memset (isPrime, true, sizeof (isPrime)) ;
isPrime[0] = isPrime[1] = false ;
for (i = 4; i < MAXN; i += 2)
isPrime[i] = false ;
p[0] = 2, prilen = 1 ;
for (i = 3; i < MAXN; i += 2)
{
if (isPrime[i])
{
p[prilen ++] = i ;
for (int j = 2*i; j < MAXN; j += i)
isPrime[j] = false ;
}
}
}
void divide ()
{
flen = 0 ;
LL i, tp = m ;
memset (f, 0, sizeof (f)) ;
for (i = 0; (LL)p[i]*p[i] <= tp; i ++)
{
if (tp % p[i] == 0)
{
f[flen][0] = p[i] ; //保存质因子
while (tp % p[i] == 0)
{
f[flen][1] ++ ; //该质因子下的数量
tp /= p[i] ;
}
flen ++ ;
}
}
if (tp == m && n < m)
{
flag = true ;
}
if(tp > 1)
{
f[flen][0] = tp ;
f[flen][1] = 1 ;
flen ++ ;
}
}
void solve ()
{
flag = false ;
divide () ;
for (int i = 0; i < flen; i ++) //假设测试案例为16, 32728, 16的阶乘中有15个为2的质因子,
{
int t = (int)((log(n*1.0))/(log(f[i][0]*1.0))) ; //(1)假设m的第一个质因子为x, 则此处是求x^1, x^2, x^3,.. 一共有有p项
int tmp = t ;
int tt = 0 ;
for (int j = 1; j <= tmp-3; j ++) //比如当前质因子为2,则3*2*2 = 12也在16内,此时多一个2, 通过验算
tt += j*j ; //出现这类类似情况时,是从x^3以后开始出现,并且多出的个数为1, 4, 9,..为平方数。这里求多出的质因子的个数
t = t*(t+1)/2 ; //在(1)下,m的质因子的总和的个数,比如m为16,在(1)中求出t = 4, 则有2^1, 2^2, 2^3, 2^4, 共有10个2
t = (n/f[i][0]-tmp) + t + tt ; //(n/f[i][0]-tmp) 表示普通的能被2直接整除的个数,比如6 = 2*3, 12=2*6..
if (t < f[i][1]) //如果个数小于m中质因子的个数,显然无法整除
{
flag = true ;
break ;
}
if (flag)
break ;
}
if (flag)
printf ("%lld does not divide %lld!\n", m, n) ;
else printf ("%lld divides %lld!\n", m, n) ;
}
int main ()
{
getPrime () ;
while (scanf ("%lld%lld", &n, &m) != EOF)
{
if (m < MAXN)
{
if (isPrime[m] && n < m)
{
printf ("%lld does not divide %lld!\n", m, n) ;
continue ;
}
}
if (m == 0)
{
printf ("%lld does not divide %lld!\n", m, n) ;
continue ;
}
if (m == 1)
{
printf ("%lld divides %lld!\n", m, n) ;
continue ;
}
solve () ;
}
return 0;
}