import std.stdio, std.range, std.numeric, std.array, std.math;

// sieve of Eratosthenes
struct EratosthenesSieve {
    private static ulong[] _primes = [2, 3]; // , 3, 5, 7, 11, 13, 17, 19];

    static void grow(ulong x) {
        if (x <= primes[$ - 1]) return;
        auto p = primes[$ - 1] + 2;
        ulong[] candidates = primes ~ iota(p, x+1, 2).array;
        auto end = (cast(ulong) sqrt(cast(real) x)) + 1;
        for (size_t i = 1; candidates[i] < end; ++i) {
            p = candidates[i];
            auto tmp = candidates[0 .. i];
            foreach (c; candidates[i .. $]) {
                if (c == p || c % p != 0) tmp ~= c;
            }
            candidates = tmp;
        }
        _primes = candidates;
    }

    static const(ulong)[] primes() { return _primes; }

    /// O(x log log x)
    static bool isPrime(ulong x) {
        // O(log x)
        if (_primes.assumeSorted.equalRange(x).length > 0) return true;
        /// O(x log log x)
        grow(x);
        // O(log x)
        return _primes.assumeSorted.equalRange(x).length > 0;
    }
}

unittest {
    with (EratosthenesSieve) {
        assert(primes == [2, 3]);
        assert(isPrime(3));
        assert(isPrime(5));
        assert(!isPrime(9));
        assert(isPrime(13));
        assert(isPrime(524287));
        // assert(isPrime(6700417));
    }
}

ulong[ulong] primeFactorize(ulong x) {
    ulong[ulong] ret;
    EratosthenesSieve.grow(x);
    auto end = sqrt(cast(real) x);
    foreach (p; EratosthenesSieve.primes) {
        if (x % p == 0) {
            ulong n = 1;
            while ((x / p) % p == 0) {
                x /= p;
                ++n;
            }
            ret[p] = n;
        }
        if (p > end) break;
    }
    return ret;
}

unittest {
    assert(primeFactorize(6) == [2UL: 1UL, 3: 1]);
    assert(primeFactorize(40) == [2UL: 3UL, 5: 1]);
}

void main() {
    ulong a, b;
    readf("%d %d\n", &a, &b);
    writeln(primeFactorize(gcd(a, b)).length + 1);
}
