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 Haskell (GHC 7.10.3) (judge verdict: Accepted)

{-# LANGUAGE DataKinds      #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}

import           Data.List    (group)
import           Data.Ratio   (denominator, numerator)
import           GHC.TypeLits (KnownNat, Nat, natVal, type (+), type (^))

main :: IO ()
main = do
  [n, m] <- map read . words <$> getLine
  print $ f n m

type Modulus = 10 ^ 9 + 7

f :: Int -> Int -> Int
f n m = unModular $ g $ map (fromIntegral . length) $ group $ factors m
  where
    g :: [Modular Int Modulus] -> Modular Int Modulus
    g = product . map (\b -> nCombinations'' (b + fromIntegral n - 1) b)

factors :: Integral a => a -> [a]
factors = factors' primes
  where
    factors' pps@(p:ps) n
      | n < 2              = []
      | n < p ^ (2 :: Int) = [n]  -- stop early
      | n `mod` p == 0     = p : factors' pps (n `div` p)
      | otherwise          = factors' ps n
    factors' _ _ = error "`primes` is a infinite list"

primes :: Integral a => [a]
primes = 2 : filter (\n -> head (factors n) == n) [3, 5 ..]

nCombinations :: (Eq a, Num a) => a -> a -> a
nCombinations _ 0 = 1
nCombinations n k
  | n == k    = 1
  | otherwise = nCombinations (n - 1) (k - 1) + nCombinations (n - 1) k

nPermutations :: (Num a, Eq b, Num b) => a -> b -> a
nPermutations _ 0 = 1
nPermutations n k = n * nPermutations (n - 1) (k - 1)

factorial :: (Eq a, Num a) => a -> a
factorial 0 = 1
factorial n = n * factorial (n - 1)

nCombinations' :: (Eq a, Integral a) => a -> a -> a
nCombinations' n k = factorial n `div` factorial k `div` factorial (n - k)

nCombinations'' :: (Eq a, Fractional a) => a -> a -> a
nCombinations'' n k = factorial n / factorial k / factorial (n - k)

tests, test1, test2, test3 :: Bool
tests = test1 && test2 && test3
test1 = f 2 6 == 4
test2 = f 3 12 == 18
test3 = f 100000 1000000000 == 957870001

newtype Modular a (modulus :: Nat) =
  Modular { unModular :: a }
  deriving (Eq)

instance Show a => Show (Modular a modulus) where
  show (Modular n) = show n

instance (Integral a, KnownNat modulus) => Num (Modular a modulus) where
  fromInteger           = toModular . fromInteger
  Modular n + Modular m = toModular $ n + m
  Modular n * Modular m = toModular $ n * m
  negate (Modular n)    = toModular $ negate n
  abs (Modular n)       = toModular $ abs n
  signum (Modular n)    = toModular $ signum n

instance (Integral a, KnownNat modulus) => Fractional (Modular a modulus) where
  recip m@(Modular n) = toModular $ modularReciprocal (fromInteger (natVal m)) n
  fromRational r = fromInteger (numerator r) / fromInteger (denominator r)

toModular :: (Integral a, KnownNat modulus) => a -> Modular a modulus
toModular n = let m = Modular $ n `mod` fromInteger (natVal m) in m

modularReciprocal :: Integral a => a -> a -> a
modularReciprocal modulus n = snd $ modularReciprocal' modulus n
  where
    -- modularReciprocal' n m = (x, y)
    -- n * x + m * y = 1
    modularReciprocal' _ 0 = notCoprimeError
    modularReciprocal' _ 1 = (0, 1)
    modularReciprocal' m l = (y, x - q * y)
      where
        (q, r) = m `divMod` l
        (x, y) = modularReciprocal' l r
    notCoprimeError =
      error $ unwords
        [ "divider"
        , parentheses $ showIntegral n
        , "must be coprime to modulus"
        , parentheses $ showIntegral modulus
        ]
    parentheses s = "(" ++ s ++ ")"
    showIntegral = show . toInteger