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)

macro_rules! debug {
    ( $x:ident [ $i:expr ] ) => {
        if cfg!(debug_assertions) {
            println!("{}[{}] = {}", stringify!($x), $i, $x[$i]);
        }
    };
    ( $x:ident [ $i:expr ][ $j:expr ] ) => {
        if cfg!(debug_assertions) {
            println!("{}[{}][{}] = {}", stringify!($x), $i, $j, $x[$i][$j]);
        }
    };
    ( $x:expr ) => {
        if cfg!(debug_assertions) {
            println!("{}:{} {} = {:?}", line!(), column!(), stringify!($x), $x);
        }
    };
}

fn powmod(mut base: u64, mut exponent: u64, modulus: u64) -> u64 {
    let mut result = 1;
    while exponent > 0 {
        if exponent & 1 == 1 {
            result = result * base % modulus;
        }
        base = base * base % modulus;
        exponent >>= 1;
    }
    result
}

fn invmod(x: u64, p: u64) -> u64 {
    powmod(x, p - 2, p)
}

fn falling_factorial_mod(mut n: u64, mut k: u64, modulus: u64) -> u64 {
    let mut result = 1;
    while k > 0 {
        result = result * n % modulus;
        n -= 1;
        k -= 1;
    }
    result
}

fn combination_mod(n: u64, k: u64, p: u64) -> u64 {
    falling_factorial_mod(n, k, p) * invmod(falling_factorial_mod(k, k, p), p) % p
}

fn factorize(mut n: u64) -> Vec<(u64, usize)> {
    let mut d = 2;
    let mut divs = Vec::<(u64, usize)>::new();
    while n > 1 && d * d <= n {
        let mut count = 0;
        while n % d == 0 {
            n /= d;
            count += 1;
        }
        if count > 0 {
            divs.push((d, count));
        }
        d += 1;
    }
    if n > 1 {
        divs.push((n, 1));
    }
    divs
}

fn main() {
    let stdin = std::io::stdin();
    let mut stdin = my::io::InputReader::new(stdin.lock());

    const MOD: u64 = 1_000_000_007;
    
    let N: u64 = stdin.read();
    let M: u64 = stdin.read();

    let mut result = 1;
    let divs = factorize(M);
    for (p, e) in divs {
        let e_u64 = e as u64;
        result = result * combination_mod(N + e_u64 - 1, e_u64, MOD) % MOD;
    }
    println!("{}", result);
}

mod my {
    pub mod io {
        use std::io::{BufRead, ErrorKind, Result};
        use std::str::{FromStr, from_utf8};
        use std::fmt::Debug;

        pub fn read_word<R: BufRead>(r: &mut R, buf: &mut Vec<u8>)
                                              -> Result<usize> {
            let mut read = 0;
            loop {
                let (done, used) = {
                    let available = match r.fill_buf() {
                        Ok(n) => n,
                        Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
                        Err(e) => return Err(e)
                    };
                    match available.iter().position(|&x| x == b'\n' || x == b' ') {
                        Some(i) => {
                            buf.extend_from_slice(&available[..i]);
                            (true, i + 1)
                        }
                        None => {
                            buf.extend_from_slice(available);
                            (false, available.len())
                        }
                    }
                };
                r.consume(used);
                read += used;
                if done || used == 0 {
                    return Ok(read);
                }
            }
        }

        pub struct InputReader<R: BufRead> {
            reader: R,
            buf: Vec<u8>,
        }

        impl<R: BufRead> InputReader<R> {
            pub fn new(reader: R) -> InputReader<R> {
                InputReader {
                    reader: reader,
                    buf: Vec::<u8>::new(),
                }
            }

            pub fn read_word(&mut self) {
                read_word(&mut self.reader, &mut self.buf);
            }
            
            pub fn read<T>(&mut self) -> T
                where T: FromStr,
                      T::Err: Debug
            {
                self.buf.clear();
                self.read_word();
                from_utf8(&self.buf).unwrap().trim().parse().unwrap()
            }
        }
    }
}