#include <iostream>
#include <iomanip>
#include <random>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <numeric>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <sstream>
#include <bitset>
#include <cassert>
#include <fstream>
#include <queue>
#include <stack>
#include <unordered_map>
#include <unordered_set>

#define len(X) ((int)(X).size())

#ifdef __LOCAL
#define DBG(X) cout << #X << "=" << (X) << '\n';
#define SAY(X) cout << (X) << '\n';
#else
#define DBG(X)
#define SAY(X)
#endif

#define M_PI       3.14159265358979323846

using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

const int INT_INF = (int)(2e9);
const ll  LL_INF = (ll)(2e18);

const int NIL = -1;
static mt19937 _g(time(nullptr));

inline ll randint(ll a, ll b) { ll w = (_g() << 31LL) ^ _g(); return a + w % (b - a + 1); }
inline void fast_io() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); };
template<typename T> inline T sign(T x) { return T(x > 0) - T(x < 0); }
template<typename T, typename S> inline ostream& operator<<(ostream& os, const pair<T, S> p) { cout << "[" << p.first << ";" << p.second << "]"; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const vector<T>& v) { for (auto el : v) cout << el << " "; return os; }
template<typename T> inline T fetch() { T ret; cin >> ret; return ret; }
template<typename T> inline vector<T> fetch_vec(int sz) { vector<T> ret(sz); for (auto& elem : ret) cin >> elem; return ret; }

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


vector<int> getDivisors(int n)
{
    vector<int> out;

    for (int i = 1; i <= sqrt(n); ++i)
    {
        if (n % i == 0)
        {
            if (n / i == i)
            {
                out.push_back(i);
            }
            else
            {
                out.push_back(i);
                out.push_back(n / i);
            }
        }
    }

    return out;
}

unordered_set<ll> getPrimes(ll n)
{
    unordered_set<ll> out = {1};

    if (n < 2) return out;

    vector<bool> primes(n + 1, true);
    primes[0] = false;

    if (n % 2 == 0)
        out.insert(2);

    for (ll i = 3; i < (n + 1) / 2; i += 2)
    {
        if (!primes[i]) continue;

        if (n % i == 0)
            out.insert(i);
        
        for (ll j = i + i; j < n + 1; j += i)
            primes[j] = false;
    }

    return out;
}

unordered_set<ll> primeFactors(ll n)
{
    unordered_set<ll> out = { 1 };
    
    if (n < 2) return out;

    if (n % 2 == 0)
        out.insert(2);

    while (n % 2 == 0)
        n = n / 2;

    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        if (n % i == 0)
        {
            out.insert(i);
            while (n % i == 0)
                n = n / i;
        }
    }

    if (n > 2)
        out.insert(n);

    return out;
}


int main()
{
    ll N, K;
    std::cin >> N >> K;

    std::unordered_set<ll> primesN = primeFactors(N);
    std::unordered_set<ll> primesK = primeFactors(K);

    for (auto it = primesN.begin(); it != primesN.end();)
    {
        if (primesK.find(*it) == primesK.end())
            it = primesN.erase(it);
        else
            ++it;
    }

    std::cout << primesN.size() << std::endl;
    //for (auto it: primesN)
    //    std::cout << it << " ";
    //std::cout << std::endl;

    return 0;
}


Measured memory_bytes: 256