Problem:
Score : 400 points

Problem Statement

You are given positive integers N and M.

How many sequences a of length N consisting of positive integers satisfy a_1 \times a_2 \times ... \times a_N = M? Find the count modulo 10^9+7.

Here, two sequences a' and a'' are considered different when there exists some i such that a_i' \neq a_i''.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq M \leq 10^9

Input

Input is given from Standard Input in the following format:

N M

Output

Print the number of the sequences consisting of positive integers that satisfy the condition, modulo 10^9 + 7.

Sample Input 1

2 6

Sample Output 1

4

Four sequences satisfy the condition: \{a_1, a_2\} = \{1, 6\}, \{2, 3\}, \{3, 2\} and \{6, 1\}.

Sample Input 2

3 12

Sample Output 2

18

Sample Input 3

100000 1000000000

Sample Output 3

957870001

Solution in Scala (2.11.7) (judge verdict: Accepted)

object Main extends App {
  val sc = new java.util.Scanner(System.in)
  val n,m = sc.nextInt

  val mod = 1000000007

  def plus(a: Long, b: Long): Long = (a+b) % mod
  def minus(a: Long, b: Long): Long = (a-b+mod) % mod
  def times(a: Long, b: Long): Long = (a*b) % mod

  def pow(a: Long, n: Int): Long = {
    def pow(a: Long, n: Int, res: Long): Long = {
      if (n == 0) res
      else if ((n&1) == 0) pow(times(a,a),n >> 1,res)
      else pow(times(a,a),n >> 1,times(a,res))
    }
    pow(a,n,1L)
  }

  def inv(a: Long): Long = pow(a,mod-2)
  def div(a: Long, b: Long): Long = times(a,inv(b))


  def factorize(n: Int): List[Int] = {
    if (n == 1) Nil
    else {
      var i = 2
      var d = 0
      while (i*i <= n && d == 0) {
        if (n % i == 0) d = i
        i += 1
      }
      if (d == 0) List(n) else d::factorize(n/d)
    }
  }

  if (m == 1) println(1)
  else {
    val f = factorize(m)
    val bs = f.toSet.toList.map((x: Int) => f.count(_ == x))

    val l = bs.max + n - 1

    def factTable(n: Int): IndexedSeq[Long] = {
      (1 to n).scanLeft(1L)(times(_,_))
    }

    val fact = factTable(l)

    def factInvTable(n: Int): IndexedSeq[Long] = {
      (1 to n).scanRight(inv(fact(n)))(times(_,_))
    }

    val factInv = factInvTable(l)

    def comb(n: Int, k: Int): Long = {
      times(times(fact(n), factInv(k)), factInv(n-k))
    }

    println(bs.map(b => comb(b+n-1, b)).reduceLeft(times(_,_)))
  }
}