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: Wrong Answer)

#include<iostream>
#include<vector>
#include<cstdio>
#include<string>
#include<algorithm>
#include <sstream>
#include<map>
#include<cmath>
#include<queue>

using namespace std;

// ユークリッドの互除法
// 最大公約数を求める
int CalcGCD(int a, int b)
{
	if (a < b) swap(a, b);
	if (b == 0) return a;

	return CalcGCD(a % b, b);
}

bool IsPrimeNum(int num)
{
	for (int i = 2; i < num; ++i) {
		if (num % i == 0) {
			return false;
		}
	}
	return true;
}

// すべて互いに素か求める
bool CanCount(vector<int> vNum, vector<bool> vUse)
{
	vector<int> vTmp;
	for (int i = 0; i < vNum.size(); i++)
	{
		if (vUse[i]) { vTmp.push_back(vNum[i]); }
	}

	// 現状の数を計算
	int counter = 0;
	for (int i = 0; i < vTmp.size(); i++)
	{
		for (int j = 0; j < vTmp.size(); j++)
		{
			if (i == j) { continue; }
			if (CalcGCD(vTmp[i], vTmp[j]) != 1)
			{
				return false;
			}
		}
	}
	return true;
}

struct Info
{
	vector<bool> m_vUse;
	int m_index;
	int m_anser;

	bool isSame(vector<bool> vUse, int index)
	{
		bool isSame = true;
		for (int i = 0; i < vUse.size(); i++)
		{
			if (m_vUse[i] != vUse[i])
			{
				isSame = false;
				break;
			}
		}
		if (m_index != index)
		{
			isSame = false;
		}
		return isSame;
	}
};
vector<Info> DP;

int calcDP(vector<int> vNum, vector<bool> vUse, int index)
{
	for (int i = 0; i < DP.size(); i++)
	{
		if (DP[i].isSame(vUse, index) != false)
		{
			return DP[i].m_anser;
		}
	}

	if (index >= vNum.size())
	{
		int result = 0;
		if (CanCount(vNum, vUse))
		{
			for (int i = 0; i < vUse.size(); ++i)
			{
				if (vUse[i]) { ++result; }
			}
		}
		return result;
	}

	int noUseCurIndex = calcDP(vNum, vUse, index+1);

	Info tmp;
	tmp.m_vUse = vUse;
	tmp.m_index = index;
	tmp.m_anser = noUseCurIndex;
	DP.push_back(tmp);
	vUse[index] = true;
	int useCurIndex = calcDP(vNum, vUse, index+1);

	tmp.m_vUse = vUse;
	tmp.m_index = index;
	tmp.m_anser = useCurIndex;
	DP.push_back(tmp);
	return max(noUseCurIndex, useCurIndex);
}

int main() {

	int A, B;
	cin >> A >> B;
	vector<int> vNum;
	int gcd = CalcGCD(A, B);

	for (int i = 1; i <= gcd; ++i)
	{
		if (A % i != 0) { continue; }
		if (B % i != 0) { continue; }
		vNum.push_back(i);
	}
	sort(vNum.begin(), vNum.end());
	vector<bool> vUse(vNum.size(), false);

	int counter = calcDP(vNum, vUse, false);

	cout << counter;

	return 0;
}