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.Generic;
using System.Linq;
using System.Text;

using System.Runtime.CompilerServices;

public class Contest
{
	static void Swap<T>(ref T lhs, ref T rhs) { T temp; temp = lhs; lhs = rhs; rhs = temp; }
	public const long MOD1 = 1000000007L; // 10^9+7

	public static void Main() {
//		Solve_A();
//		Solve_B();
//		Solve_C();
		Solve_D();
//		Solve_E();
//		Solve_F();
 	}

	public static void Solve_A() {
		long  n;
 		MyIO.ReadMulti(out n);
 


		double ans = n%2==0?0.5:(double)((n/2)+1)/(double)n;

		MyIO.WriteMulti(ans);
 
	}
	public static void Solve_B() {
		long  n, k;
		long[] a;
 		MyIO.ReadMulti(out n, out k);
		MyIO.ReadArray(out a);


		long ans = 0;
		foreach(var e in a) if (e>=k) ans++;

		MyIO.WriteMulti(ans);
 
	}
	public static void Solve_C() {
		long  n;
 		MyIO.ReadMulti(out n);
 		long[] a;
		MyIO.ReadArray(out a);

		VT<long,long>[] s = new VT<long, long>[n];
		for (int i = 1; i <= n; i++)
		{
			s[i-1] = new VT<long, long>(i,a[i-1]);
		}
		Array.Sort(s,(x,y)=>(int)(x.Item2-y.Item2));

		long[] ans = new long[n];
		for(int i=0;i<n;i++)ans[i] = s[i].Item1;

		MyIO.WriteArray(ans);
 
	}
	public static void Solve_D() {
		long  a,b;
 		MyIO.ReadMulti(out a, out b);
 
		long gcd = Gcd(a,b);
		long[] fac = PrimeFactor(gcd);
		Dictionary<long,int> dic = new Dictionary<long, int>();
		foreach(var e in fac) {
			if(!dic.ContainsKey(e)) dic[e]=0;
			dic[e]++;
		}

		MyIO.WriteMulti(dic.Count+1);
 
	}
	public static void Solve_E() {
		long  n, m;
 		MyIO.ReadMulti(out n, out m);
 		VT<long,long>[] ab = new VT<long, long>[m];
		int[] a = new int[m];
		for (int i = 0; i < m; i++)
		{
			long aq, bq;
			MyIO.ReadMulti(out aq, out bq);
			ab[i] = new VT<long, long>(aq,bq);
			long[] fq;
			MyIO.ReadArray(out fq);
			int bit = 0;
			foreach(var e in fq) bit |= (1<<(int)(e-1));
			a[i] = bit;
		}
		int lim = 1<<(int)n;
		long[][] dp = new long[m+1][];
		dp[0] = Enumerable.Repeat((long)int.MaxValue,lim).ToArray();
		dp[0][0] = 0;
		for (int i = 0; i < m; i++)
		{
			dp[i+1] = Enumerable.Repeat((long)int.MaxValue,lim).ToArray();
			for (int j = 0; j < lim; j++)
			{
				int nb = j | a[i];
				dp[i+1][nb] = Math.Min(dp[i+1][nb],dp[i][nb]);
				dp[i+1][nb] = Math.Min(dp[i+1][nb],dp[i][j]+ab[i].Item1);
			}
		}

		long ans = -1;
		if(dp[m][lim-1]<(long)int.MaxValue) ans = dp[m][lim-1];


		MyIO.WriteMulti(ans);
 
	}
	public static void Solve_F() {
		long  n, k;
 		MyIO.ReadMulti(out n, out k);

 


		long ans = 0;

		MyIO.WriteMulti(ans);
 
	}



	public static long Gcd(long a, long b) {
	    var v = new[] { a, b };
	    while (v[1] != 0) v = new[] { v[1], v[0] % v[1] };
	    return v[0];
	}

    public static long[] PrimeFactor(long n) {
		List<long> ret = new List<long>();
        if (n < 2) return ret.ToArray();
        while ((n & 1) == 0) {
			ret.Add(2);
			n >>= 1;
		}
        while ((n % 3) == 0) {
			ret.Add(3);
			n /= 3;
		}
        long sqrt = (long)Math.Sqrt(n);
        for (long i = 5, f = 2; i <= sqrt; i += f, f ^= 6) {
            while ((n % i) == 0) {
				ret.Add(i);
				n /= i;
			}
        }
		if(1<n) ret.Add(n);
        return ret.ToArray();
    }





}


















#region MyIO

public struct VT<T, U>
{
	public T Item1; public U Item2;
    public VT(T a, U b) { Item1 = a; Item2 = b; }
}
public struct VT<T, U, V>
{
	public T Item1; public U Item2; public V Item3;
    public VT(T a, U b, V c) { Item1 = a; Item2 = b; Item3 = c; }
}
public struct VT<T, U, V, W>
{
	public T Item1; public U Item2; public V Item3; public W Item4;
    public VT(T a, U b, V c, W d) { Item1 = a; Item2 = b; Item3 = c; Item4 = d; }
}

public class Printer : System.IO.StreamWriter
{
	public override IFormatProvider FormatProvider { get { return System.Globalization.CultureInfo.InvariantCulture; } }
	public Printer(System.IO.Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	public Printer(System.IO.Stream stream, Encoding encoding) : base(stream, encoding) { }
}
public static class MyIO
{
	private static char[] splitter = new char[] {' '};
	private static bool eq<T, U>() => typeof(T).Equals(typeof(U));
	private static T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
	private static T cv<T>(string s) =>
		eq<T, int>()    ? ct<T, int>(int.Parse(s))
	  : eq<T, long>()   ? ct<T, long>(long.Parse(s))
	  : eq<T, double>() ? ct<T, double>(double.Parse(s, System.Globalization.CultureInfo.InvariantCulture))
	  : eq<T, char>()   ? ct<T, char>(s[0])
						: ct<T, string>(s);
			
	public static string[] ReadMulti<T>(out T a) {
		var ar = Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries); 
		a = cv<T>(ar[0]);
		return ar;
	}
	public static string[] ReadMulti<T, U>(out T a, out U b) {
		var ar = ReadMulti<T>(out a); 
        b = cv<U>(ar[1]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V>(out T a, out U b, out V c) {
		var ar = ReadMulti<T, U>(out a, out b); 
        c = cv<V>(ar[2]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W>(out T a, out U b, out V c, out W d) {
		var ar = ReadMulti<T, U, V>(out a, out b, out c); 
        d = cv<W>(ar[3]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e) {
		var ar = ReadMulti<T, U, V, W>(out a, out b, out c, out d); 
        e = cv<X>(ar[4]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W, X, Y>(out T a, out U b, out V c, out W d, out X e, out Y f) {
		var ar = ReadMulti<T, U, V, W, X>(out a, out b, out c, out d, out e); 
        f = cv<Y>(ar[5]);
		return ar;
	}
	public static string[] ReadArray<T>(out T[] a) {		
		var ar = Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries);
		a = ar.Select(cv<T>).ToArray();
		return ar;
	}		
	public static string[][] ReadLines<T>(int n, out T[] a) {
		a = new T[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) arr[i] = ReadMulti(out a[i]);
		return arr;
	}
	public static string[][] ReadLines<T, U>(int n, out VT<T, U>[] a) {
		a = new VT<T, U>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p;
			arr[i] = ReadMulti(out o, out p);
			a[i] = new VT<T, U>(o, p);
		}
		return arr;
	}
	public static string[][] ReadLines<T, U, V>(int n, out VT<T, U, V>[] a) {
		a = new VT<T, U, V>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p; V q;
			arr[i] = ReadMulti(out o, out p, out q);
			a[i] = new VT<T, U, V>(o, p, q);
		}
		return arr;
	}
	public static string[][] ReadLines<T, U, V, W>(int n, out VT<T, U, V, W>[] a) {
		a = new VT<T, U, V, W>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p; V q; W r;
			arr[i] = ReadMulti(out o, out p, out q, out r);
			a[i] = new VT<T, U, V, W>(o, p, q, r);
		}
		return arr;
	}
	public static string[][] ReadMatrix<T>(int n, out T[][] a) {
		a = new T[n][];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) arr[i] = ReadArray(out a[i]);
		return arr;
	}

	private static void wwp(Action act){
		var sw = new Printer(Console.OpenStandardOutput()){AutoFlush = false};
		Console.SetOut(sw);
		act();
		Console.Out.Flush();
		sw.AutoFlush = true;
		Console.SetOut(sw);
	}
	private static string wfm(Type t) =>t.Equals(typeof(double)) ? "{0:F10}" : "{0}";
	public static void WriteMulti(params object[] a) {
		wwp(()=>{
			for(int i=0;i<a.Length;i++) {
				string fs = wfm(a[i].GetType()) + ((i<a.Length-1) ? " " : Environment.NewLine);
				Console.Write(fs, a[i]);
			}
		});
	}
	public static void WriteArray<T>(T[] a) {
		wwp(()=>{
			string fs = wfm(typeof(T));
			string fs1 = fs + " ";
			string fs2 = fs + Environment.NewLine;
			for(int i=0;i<a.Length;i++) Console.Write( ((i<a.Length-1) ? fs1 : fs2), a[i]);
		});
	}
	public static void WriteLines<T>(T[] a) {
		wwp(()=>{
			string fs = wfm(typeof(T)) + Environment.NewLine;
			foreach(T x in a) Console.Write(fs, x);
		});
	}


}

#endregion