Problem:
Score : 400 points

Problem Statement

Given are positive integers A and B.

Let us choose some number of positive common divisors of A and B.

Here, any two of the chosen divisors must be coprime.

At most, how many divisors can we choose?

Definition of common divisor

An integer d is said to be a common divisor of integers x and y when d divides both x and y.

Definition of being coprime

Integers x and y are said to be coprime when x and y have no positive common divisors other than 1.

Definition of dividing

An integer x is said to divide another integer y when there exists an integer \alpha such that y = \alpha x.

Constraints

All values in input are integers.

1 \leq A, B \leq 10^{12}

Input

Input is given from Standard Input in the following format:

A B

Output

Print the maximum number of divisors that can be chosen to satisfy the condition.

Sample Input 1

12 18

Sample Output 1

3

12 and 18 have the following positive common divisors: 1, 2, 3, and 6.

1 and 2 are coprime, 2 and 3 are coprime, and 3 and 1 are coprime, so we can choose 1, 2, and 3, which achieve the maximum result.

Sample Input 2

420 660

Sample Output 2

4

Sample Input 3

1 2019

Sample Output 3

1

1 and 2019 have no positive common divisors other than 1.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)


#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <array>
#include <cmath>

using namespace std;

using ll = long long int;

// GCDを計算します
template <typename NumType>
NumType calcGCD(NumType a, NumType b) {
    if (a < b) {
        NumType tmp = a;
        a = b;
        b = tmp;
    }

    NumType r = a % b;
    while (r != 0) {
        a = b;
        b = r;
        r = a % b;
    }

    return b;
}

// 約数を数えます
template <typename NumType>
NumType cntDivisor(const NumType & num) {
    NumType cnt = 0;
    for(NumType i = 1; i * i <= num; ++i) {
        if(num % i == 0) {
            cnt++;
            if(i * i != num) cnt++;
        }
    }

    return cnt;
}

// 約数を返す
template <typename NumType>
std::vector<NumType> divisor(NumType num) {
    std::vector<NumType> ans;

    ans.push_back(1);

    for(NumType i = 2; i * i <= num; ) {
        if (num % i == 0) {
            if (ans.back() != i) {
                ans.push_back(i);
            }
            num /= i;
        } else {
            i++;
        }
    }

    if (ans.back() != num)
        ans.push_back(num);

    return ans;
}

// 約数を返す
template <typename NumType>
std::vector<NumType> common_divisor(NumType a, NumType b) {
    std::vector<NumType> ans;

    NumType min = (a <= b) ? a : b;
    NumType max = (a > b) ? a : b;

    for (NumType i = 1; i*2 <= min; i++) {
        if (a % i == 0 && b % i == 0)
            ans.push_back(i);
    }

    if (max % min == 0) ans.push_back(min);

    return ans;
}


// 共通部分を返す
template <typename NumType>
std::vector<NumType> get_common(const std::vector<NumType> &a, const std::vector<NumType> &b) {
    std::vector<NumType> ans;

    const auto target = (a.size() <= b.size()) ? a : b;
    const auto compare = (a.size() > b.size()) ? a : b;

    auto tgt_it = target.cbegin();
    auto cmp_it = compare.cbegin();

    while (tgt_it != target.cend()) {
        for (; *cmp_it < *tgt_it && cmp_it != compare.cend(); cmp_it++);
        if (cmp_it == compare.cend()) break;

        if (*tgt_it == *cmp_it) ans.push_back(*tgt_it);
        cmp_it++, tgt_it++;
    }

    return ans;
}

// [beg, end)の範囲を，添え字indexでループするfor文に置換します
#define FOR_RANGE(index, beg, end)     for (ll index = beg; index < N; ++index)

#define DEBUG(x)     std::cout << #x << " : " << x << "\n"

template<class T>
T min(T a, T b) {
    return (a < b) ? a : b;
}

template<class T>
T max(T a, T b) {
    return (a > b) ? a : b;
}



int main() {
    ll A, B;
    cin >> A >> B;

    auto a_div = divisor(A);
    // for (auto n : a_div) {
    //     cout << n << " ";
    // }
    // cout << "\n";

    auto b_div = divisor(B);
    // for (auto n : a_div) {
    //     cout << n << " ";
    // }
    // cout << "\n";

    // auto common = get_common(a_div, b_div);
    // for (auto n : common) {
    //     cout << n << " ";
    // }
    // cout << "\n";

    int ans = 0;
    for (size_t i = 0; i < a_div.size(); i++) {
        for (size_t j = 0; j < b_div.size(); j++) {
            if (a_div[i] == b_div[j]) ans++;
        }
    }


    cout << ans;

    return 0;
}