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)

#[allow(unused_macros)]
macro_rules ! for_ { ( $ init : stmt ; $ cond : expr ; $ incr : expr , $ body : block ) => ( { $ init ; while $ cond { $ body $ incr ; } } ) ; }

#[allow(dead_code)]
pub const M: u64 = 1_000_000_007;

fn main() {
    use std::io::Read;
    let mut buf = String::new();
    std::io::stdin().read_to_string(&mut buf).unwrap();
    let mut iter = buf.split_whitespace();
    
    let n: u64 = iter.next().unwrap().parse::<u64>().unwrap();
    let m: u64 = iter.next().unwrap().parse::<u64>().unwrap();
    
    let factors = prime_factors(m);
    let mut ret = 1u64;
    for (_, value) in factors.iter() {
        ret *= comb(value + n - 1, *value);
        ret %= M;
    }
    println!("{}", ret);
}

fn comb(n: u64, r: u64) -> u64 {
    let mut ret = 1u64;
    for_!(let mut i = 0; i < r; i+=1, {
        ret *= n - i;
        ret %= M;
    });
    for_!(let mut i = 1; i < r+1; i+=1, {
        ret *= modinv(i as i64, M as i64) as u64;
        ret %= M;
    });
    ret
}

#[doc = " n>=1"]
#[allow(dead_code)]
fn is_prime(n: u64) -> bool {
    for_ ! ( let mut i = 2 ; i * i <= n ; i += 1 , { if n % i == 0 { return false ; } } );
    n != 1
}
#[doc = " n>=1"]
#[allow(dead_code)]
fn divisors(n: u64) -> Vec<u64> {
    let mut ret = vec![];
    for_ ! ( let mut i = 1 ; i * i <= n ; i += 1 , { if n % i == 0 { ret . push ( i ) ; if i != n / i { ret . push ( n / i ) ; } } } );
    ret
}
#[allow(dead_code)]
use std::collections::HashMap;
#[doc = " n>=1"]
#[allow(dead_code)]
fn prime_factors(mut n: u64) -> HashMap<u64, u64> {
    let mut ret = HashMap::new();
    for_ ! ( let mut i = 2 ; i * i <= n ; i += 1 , { while n % i == 0 { * ret . entry ( i ) . or_insert ( 0 ) += 1 ; n /= i ; } } );
    if n != 1 {
        ret.insert(n, 1);
    }
    ret
}
#[doc = " return: (primes, is_prime)"]
#[allow(dead_code)]
fn sieve(n: usize) -> (Vec<usize>, Vec<bool>) {
    let mut primes = vec![];
    let mut is_prime = vec![true; n + 1];
    is_prime[0] = false;
    is_prime[1] = false;
    for i in 2..n + 1 {
        if is_prime[i] {
            primes.push(i);
            for_ ! ( let mut j = 2 * i ; j <= n ; j += i , { is_prime [ j ] = false ; } )
        }
    }
    (primes, is_prime)
}

#[doc = " a / b modulo m == a * modinv(b, m)"]
#[allow(dead_code)]
fn modinv(mut a: i64, m: i64) -> i64 {
    let mut b = m;
    let mut u = 1;
    let mut v = 0;
    while b != 0 {
        let t = a / b;
        a -= t * b;
        std::mem::swap(&mut a, &mut b);
        u -= t * v;
        std::mem::swap(&mut u, &mut v);
    }
    u %= m;
    if u < 0 {
        u += m
    };
    u
}