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 Rust (1.15.1) (judge verdict: Accepted)

use std::io::prelude::*;
use std::io::stdin;
use std::str::FromStr;

fn main() {
    let n: u64 = read();
    let m: u64 = read();

    let ps = m.prime_factorization();
    let mut ans = 1;
    let mod_comb = ModCombination::new();

    for &(_, c) in ps.iter() {
        ans = (ans * mod_comb.calc(c + n - 1, n - 1)) % 1_000_000_007;
    }

    println!("{}", ans);
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let token: String = stdin
        .lock()
        .bytes()
        .map(|b| b.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().unwrap()
}

// need IntegerSqrt
trait PrimeFactorization: Sized {
    fn prime_factorization(&self) -> Vec<(Self, Self)>;
}

impl PrimeFactorization for u64 {
    fn prime_factorization(&self) -> Vec<(Self, Self)> {
        let mut n = *self;
        let mut result = vec![];
        for p in 2..self.isqrt() + 2 {
            if n % p != 0 {
                continue;
            }
            let mut count = 0;
            while n % p == 0 {
                n /= p;
                count += 1;
            }
            result.push((p, count));
        }

        if n != 1 {
            result.push((n, 1));
        }

        result
    }
}

// https://en.wikipedia.org/wiki/integer_square_root
trait IntegerSqrt {
    fn isqrt(&self) -> Self;
}

impl IntegerSqrt for u64 {
    fn isqrt(&self) -> Self {
        if *self < 2 {
            *self
        } else {
            let s = (*self >> 2).isqrt() << 1;
            let l = s + 1;
            if l * l > *self {
                s
            } else {
                l
            }
        }
    }
}

struct ModCombination {
    fac: Vec<u64>,
    finv: Vec<u64>,
    modulo: u64,
}

impl ModCombination {
    fn new() -> ModCombination {
        let max = 210_000;
        let modulo = 1_000_000_007u64;
        let mut fac = vec![1; max];
        let mut inv = vec![1; max];
        let mut finv = vec![1; max];
        for i in 2..max {
            fac[i] = fac[i - 1] * i as u64 % modulo;
            inv[i] = modulo - inv[(modulo % i as u64) as usize] * (modulo / i as u64) % modulo;
            finv[i] = finv[i - 1] * inv[i] % modulo;
        }
        ModCombination {
            fac: fac,
            finv: finv,
            modulo: modulo,
        }
    }

    fn calc(&self, n: u64, k: u64) -> u64 {
        if n < k {
            0
        } else {
            self.fac[n as usize]
                * (self.finv[k as usize] * self.finv[(n - k) as usize] % self.modulo)
                % self.modulo
        }
    }
}