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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using static System.Console;
using static System.Math;
using static Utils;
class Program
{


    void Solve()
    {
        var A = io.Long;
        var B = io.Long;
        var ad = new List<long>();
        var bd = new HashSet<long>();
        for (var i = 1L; i * i <= A; i++)
        {
            if (A % i == 0)
            {
                ad.Add(i);
                if (i != A / i)
                {
                    ad.Add(A / i);
                }
            }
        }

        for (var i = 1L; i * i <= B; i++)
        {
            if (B % i == 0)
            {
                bd.Add(i);
                if (i != B / i)
                {
                    bd.Add(B / i);
                }
            }
        }

        var factor = ad.Where(x => bd.Contains(x));
        var P = new Prime();

        WriteLine(factor.Count(x => x == 1 || P.IsPrime(x)));

    }
    public int GCD(int a, int b) => (a < b) ? GCD(b, a) : b == 0 ? a : GCD(b, a % b);
    class Prime
    {
        private bool[] isPrimeArr;
        public Prime(long n = (long)2e7)
        {
            SieveInit(n);
        }
        private void SieveInit(long n)
        {
            isPrimeArr = new bool[n + 1];
            for (var i = 2; i <= n; ++i) isPrimeArr[i] = true;
            for (var i = 2; i <= n; ++i) if (isPrimeArr[i]) for (var j = 2 * i; j <= n; j += i) isPrimeArr[j] = false;
        }
        public bool IsPrime(long n)
        {
            if (n < isPrimeArr.Length) return isPrimeArr[n];
            if (n == 2) return true; if (n < 2 || n % 2 == 0) return false;
            for (long v = 3; v <= (long)Math.Sqrt(n); v += 2) if (n % v == 0) return false;
            return true;
        }

    }
    SimpleIO io = new SimpleIO();
    public static void Main(string[] args) => new Program().Stream();
    private void Stream()
    {
        //var exStdIn = new System.IO.StreamReader("stdin.txt");
        //SetIn(exStdIn);
        Solve();
        io.Flush();
    }

}

class SimpleIO
{
    string[] _nextBuffer;
    int _bufferCnt;
    char[] cs = new char[] { ' ', '"', ',' };
    StreamWriter sw = new StreamWriter(OpenStandardOutput())
    {
#if DEBUG
        AutoFlush = true
#else
        AutoFlush = false
#endif
    };
    public SimpleIO()
    {
        _nextBuffer = new string[0];
        _bufferCnt = 0;
        SetOut(sw);
    }
    string Next()
    {
        if (_bufferCnt < _nextBuffer.Length) return _nextBuffer[_bufferCnt++];
        var st = ReadLine();
        while (st == string.Empty) st = ReadLine();
        _nextBuffer = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
        _bufferCnt = 0;
        return _nextBuffer[_bufferCnt++];
    }
    public string String => Next();
    public char Char => char.Parse(String);
    public int Int => int.Parse(String);
    public long Long => long.Parse(String);
    public double Double => double.Parse(String);
    public void Flush() => Out.Flush();
}
static class Utils
{
    public static T id<T>(T x) => x;
    public static void FOR(int a, int b, Action<int> f) => FOR(a, b, 1, f);
    public static void FOR(int a, int b, int n, Action<int> f)
    {
        for (int i = a; i < b; i += n) f(i);
    }
    public static void REP(int a, Action<int> f) => FOR(0, a, f);
    public class IndexedItem<T>
    {
        public int Idx;
        public T Val;
        public IndexedItem(int idx, T val)
        {
            Idx = idx;
            Val = val;
        }
    }
    public static IEnumerable<IndexedItem<T>> Indexed<T>(this IEnumerable<T> xs) => xs.Select((x, i) => new IndexedItem<T>(i, x));
}