#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
////////////////////////////////////////////////////////////////////////////////
#ifndef __x86_64__
#error Only x86-64 targets are supported
#endif
#include<cstdint>
#include<vector>
#include<string>
#include<iosfwd>
#define __builtin_ia32_adc(x,y,flag) __asm__("addb %3, %0\n\t" "adcq %2, %1\n\t" "setc %0":"+r"(flag),"+r"(x):"r"(y),"i"(-1):"cc")
struct bigint{// made by dengyaotriangle!
typedef unsigned long long u64;
typedef unsigned __int128 u128;
typedef std::size_t st;
std::vector<u64> data;
bigint(){}
bigint(u64 x):data(x?std::vector<u64>{x}:std::vector<u64>{}){}
bigint(const std::string &s){
st pos=s.length();
int cnt=0;
u64 val=0;
while(pos){
pos--;
if(cnt==64){
data.push_back(val);
val=0;cnt=0;
}
val|=(u64)(s[pos]=='1')<<cnt;
++cnt;
}
if(cnt&&val)data.push_back(val);
}
explicit operator std::string()const{
if(data.empty())return "0";
bool t=0;
std::string ret;
for(int i=63;i>=0;i--){
t|=(data.back()>>i)&1;
if(t)ret+='0'|((data.back()>>i)&1);
}
st i=data.size()-1;
while(i){
i--;
for(int j=63;j>=0;j--)ret+='0'|((data[i]>>j)&1);
}
return ret;
}
explicit operator bool()const{return !data.empty();}
explicit operator u64()const{return data.empty()?0:data[0];}
st digit()const{
if(data.empty())return 0;
return (data.size()<<6)-__builtin_clzll(data.back());
}
bool operator==(const bigint &a)const{return a.data==data;}
bool operator!=(const bigint &a)const{return a.data!=data;}
bool operator<(const bigint &a)const{
if(data.size()!=a.data.size())return data.size()<a.data.size();
for(st i=data.size();i;){
i--;
if(data[i]!=a.data[i])return data[i]<a.data[i];
}
return 0;
}
bool operator>(const bigint &a)const{return a<(*this);}
bool operator<=(const bigint &a)const{return !(*this>a);}
bool operator>=(const bigint &a)const{return !(*this<a);}
bigint &operator<<=(st n){
if(data.empty())return *this;
int w=n&63;st z=n>>6;
st i=data.size();
bool flg=0;
if(w&&(data.back()>>(64-w)))data.push_back(0),flg=1;
data.resize(data.size()+z);
while(i){
i--;
if(flg)data[i+z+1]|=data[i]>>(64-w);
data[i+z]=data[i]<<w;
flg|=bool(w);
}
for(st i=0;i<z;i++)data[i]=0;
return *this;
}
bigint &operator>>=(st n){
int w=n&63;st z=n>>6,i=0;
for(;i+z<data.size();i++){
if(w&&i)data[i-1]|=data[i+z]<<(64-w);
data[i]=data[i+z]>>w;
}
while(data.size()>i)data.pop_back();
while(!data.empty()&&data.back()==0)data.pop_back();
return *this;
}
bigint operator<<(st n)const{return bigint(*this)<<=n;}
bigint operator>>(st n)const{return bigint(*this)>>=n;}
bigint &operator+=(const bigint &a){
data.resize(std::max(data.size(),a.data.size()));
bool carry=0;
for(st i=0;i<data.size();i++){
u64 rg=0;
if(i<a.data.size())rg=a.data[i];
__builtin_ia32_adc(data[i],rg,carry);
}
if(carry)data.push_back(1);
return *this;
}
bigint &operator-=(const bigint &a){
bool carry=1;
for(st i=0;i<data.size();i++){
u64 rg=-1;
if(i<a.data.size())rg=~a.data[i];
__builtin_ia32_adc(data[i],rg,carry);
}
while(!data.empty()&&data.back()==0)data.pop_back();
return *this;
}
bigint &operator++(){return *this+=bigint(1);}
bigint &operator--(){return *this-=bigint(1);}
bigint operator++(int){bigint tmp=*this;++*this;return tmp;}
bigint operator--(int){bigint tmp=*this;--*this;return tmp;}
bigint &operator*=(const bigint &a){
std::vector<u64> ret(data.size()+a.data.size());
for(st i=0;i<data.size();i++){
u64 carry=0;bool wcarry=0;
st k=i;
for(st j=0;j<a.data.size();j++,k++){
u128 r=data[i]*(u128)a.data[j]+carry;
u64 cur=r;
carry=r>>64;
__builtin_ia32_adc(ret[k],cur,wcarry);
}
while(carry||wcarry){
__builtin_ia32_adc(ret[k],carry,wcarry);
carry=0;k++;
}
}
while(!ret.empty()&&ret.back()==0)ret.pop_back();
data=ret;
return *this;
}
bigint &operator/=(const bigint &a){
if(a.digit()>digit()){
data.clear();
return *this;
}
st z=digit()-a.digit();
std::vector<u64> ret;
while(1){
bigint tmp=a<<z;
if(tmp<=*this){
*this-=tmp;
st v1=z>>6;
if(ret.size()<=v1)ret.resize(v1+1);
ret[v1]|=(u64)(1)<<(z&63);
}
if(!z)break;
z--;
}
data=ret;
return *this;
}
bigint &operator%=(const bigint &a){
if(a.digit()>digit())return *this;
st z=digit()-a.digit();
while(1){
bigint tmp=a<<z;
if(tmp<=*this)*this-=tmp;
if(!z)break;
z--;
}
return *this;
}
bigint operator+(const bigint &a)const{return bigint(*this)+=a;}
bigint operator-(const bigint &a)const{return bigint(*this)-=a;}
bigint operator*(const bigint &a)const{return bigint(*this)*=a;}
bigint operator/(const bigint &a)const{return bigint(*this)/=a;}
bigint operator%(const bigint &a)const{return bigint(*this)%=a;}
};
std::istream &operator>>(std::istream &st,bigint &a){
std::string s;st>>s;a=bigint(s);return st;
}
std::ostream &operator<<(std::ostream &st,const bigint &a){
return st<<(std::string)(a);
}
////////////////////////////////////////////////////////////////////////////////
void swap(bigint &a, bigint &b) {
a.data.swap(b.data);
}
int bsf(const bigint &a) {
for (int i = 0; i < (int)a.data.size(); ++i) if (a.data[i]) {
return i << 6 | __builtin_ctzll(a.data[i]);
}
assert(false);
}
bigint gcd(bigint a, bigint b) {
return b ? gcd(b, a % b) : a;
/*
if (!a) return b;
if (!b) return a;
const int s = min(bsf(a), bsf(b));
a >>= bsf(a);
do {
b >>= bsf(b);
if (a > b) swap(a, b);
b -= a;
} while (b);
return a << s;
//*/
}
bool isOne(const bigint &a) {
return (a.digit() == 1 && (unsigned long long)a == 1);
}
int mod(const bigint &a, int m) {
int b = 0;
for (int i = (int)a.data.size(); --i >= 0; ) {
b = ((unsigned __int128)b << 64 | a.data[i]) % m;
}
return b;
}
namespace montgomery {
int sz;
bigint m, negInvM, two2;
void init(const bigint &m_) {
assert(m_);
assert(m_.data[0] & 1);
m = m_;
sz = m.data.size();
negInvM = 1;
for (int e = 1; e < sz << 6; ) {
negInvM *= (m * negInvM + 2);
chmin(e <<= 1, sz << 6);
// if ((int)negInvM.data.size() > (e + 63) >> 6) negInvM.data.resize((e + 63) >> 6);
}
assert((m * negInvM + 1) % (bigint(1) << (sz << 6)) == 0);
two2 = (bigint(1) << (sz << 7)) % m;
}
// 2^(-6sz) a mod m
bigint reduce(const bigint &a) {
bigint c = a * negInvM;
if ((int)c.data.size() > sz) c.data.resize(sz);
c = (a + c * m) >> (sz << 6);
return (c >= m) ? (c - m) : c;
}
bigint mod(const bigint &a) {
return reduce(a * two2);
}
bigint mul(const bigint &a, const bigint &b) {
return reduce(reduce(a * b) * two2);
}
bigint power(const bigint &a, const bigint &e) {
bigint b = 1;
for (int i = (int)e.digit(); --i >= 0; ) {
b = mul(b, b);
if (e.data[i >> 6] >> (i & 63) & 1) b = mul(b, a);
}
return b;
}
} // montgomery
constexpr int LIM_SMALL = 16;
int lpf[1 << LIM_SMALL];
#include <random>
mt19937_64 rng(58);
int LEN_N;
// phi(n) | 2^E L && n: square-free
int E;
bigint L;
vector<bigint> ps;
void solve(const bigint &n) {
if(LEN_N>300)cout<<"HELP "<<n<<endl;
assert(!isOne(n));
montgomery::init(n);
constexpr int NUM_ITERS = 10;
for (int iter = 0; iter < NUM_ITERS; ++iter) {
bigint a;
a.data.resize(n.data.size());
for (int i = 0; i < (int)n.data.size(); ++i) {
a.data[i] = rng();
}
a = montgomery::mod(a);
{
const bigint g = gcd(a, n);
if (g == n) {
continue;
}
if (!isOne(g)) {
solve(g);
solve(n / g);
return;
}
}
a = montgomery::power(a, L);
if (!isOne(a)) {
for (; ; ) {
bigint b = montgomery::mul(a, a);
if (isOne(b)) {
const bigint g = gcd(a - 1, n);
if (!isOne(g) && g != n) {
solve(g);
solve(n / g);
return;
}
break;
}
a = b;
}
}
}
ps.push_back(n);
}
int main() {
for (int p = 2; p < 1 << LIM_SMALL; ++p) lpf[p] = p;
for (int p = 2; p < 1 << LIM_SMALL; ++p) if (lpf[p] == p) {
for (int n = 2 * p; n < 1 << LIM_SMALL; n += p) chmin(lpf[n], p);
}
bigint N, M;
for (; cin >> N >> M; ) {
LEN_N=N.digits();
vector<bigint> ans;
bigint n = N, m = M;
{
const int s = bsf(n);
if (s) {
for (int i = 0; i < s; ++i) {
ans.push_back(2);
}
n >>= s;
m >>= (s - 1);
}
}
for (int p = 3; p < 1 << LIM_SMALL; ++p) if (lpf[p] == p) {
int e = 0;
for (; mod(n, p) == 0; ) {
ans.push_back(p);
n /= p;
m /= (e++ ? p : (p - 1));
}
}
for (; !isOne(n); ) {
E = bsf(m);
L = m >> E;
ps.clear();
solve(n / gcd(n, m));
for (const bigint &p : ps) {
ans.push_back(p);
n /= p;
m /= (p - 1);
for (; !(n % p); ) {
ans.push_back(p);
n /= p;
m /= p;
}
}
}
assert(isOne(n));
assert(isOne(m));
sort(ans.begin(), ans.end());
cout << ans.size() << '\n';
for (const bigint &p : ans) {
cout << p << '\n';
}
cout << flush;
}
return 0;
}