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 Kotlin (1.0.0) (judge verdict: Accepted)

import java.io.*
import java.util.*

fun solve(A: Long, B: Long){
    // gcd(A, B)の素数の約数を数える
    val g = gcd(A, B)
    val factors = PrimeUtils.primeFactorize(g)
    println(factors.size + 1)
    return
}

tailrec fun gcd(x: Int, y: Int): Int = if (y == 0) x else gcd(y, x % y)
tailrec fun gcd(x: Long, y: Long): Long = if (y == 0L) x else gcd(y, x % y)


object PrimeUtils {
    fun isPrime(num: Long): Boolean {
        if (num == 1L) return false
        if (num in listOf(2L, 3L)) return true
        if (num % 6 in listOf(0L, 2L, 3L, 4L)) return false
        val sqrt = Math.sqrt(num.toDouble()).toLong()
        for (n in 5..sqrt step 6) {
            if (num % n == 0L) return false
        }
        for (n in 7..sqrt step 6) {
            if (num % n == 0L) return false
        }
        return true
    }

    fun generatePrimesBelow(sup: Long): Sequence<Long> {
        if (sup < 2L) return sequenceOf()
        if (sup < 3L) return sequenceOf(2L)
        val seq = (0..sup / 6L)
                .asSequence()
                .flatMap { sequenceOf(6 * it + 5L, 6 * it + 7L) }
                .filter { it < sup }
        return sequenceOf(2L, 3L) + seq.filter { isPrime(it) }
    }

    fun primeFactorize(num: Long): Map<Long, Int> {
        var n = num
        val result = mutableMapOf<Long, Int>()
        val sqrt = Math.sqrt(num.toDouble()).toLong()
        val trialDivs = sequenceOf(2L) + (3..sqrt step 2).asSequence()
        for (trialDiv in trialDivs) {
            if (trialDiv > n) break
            val divideRes = iterateDivide(n, trialDiv)
            if (divideRes.first > 0) {
                result[trialDiv] = divideRes.first
                n = divideRes.second
            }
        }
        if (n != 1L) result[n] = 1
        return result
    }
}


fun iterateDivide(num: Long, divisor: Long): Pair<Int, Long> {
    var n = num
    var count = 0
    while (num != 0L && n % divisor == 0L) {
        n /= divisor
        count++
    }
    return Pair(count, n)
}


fun main(args: Array<String>) {
    fun StringArray(size: Int, init: (Int) -> String = { "\u0000" }): Array<String> {
        return Array<String>(size, init)
    }
    class Scanner(stream: InputStream) {
        private val reader = BufferedInputStream(stream).bufferedReader()
        private var st: StringTokenizer? = null
        fun next(): String {
            while (!(st?.hasMoreTokens() ?: false)) st = StringTokenizer(reader.readLine())
            return st!!.nextToken()
        }
    }
    val sc = Scanner(System.`in`)
    val A = sc.next().toLong()
    val B = sc.next().toLong()
    solve(A, B)
}