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)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use proconio::input;
#[allow(unused_imports)]
use proconio::marker::*;
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::*;
#[allow(unused_imports)]
use std::f64::consts::*;

#[allow(unused)]
const INF: usize = std::usize::MAX / 4;
#[allow(unused)]
const M: usize = 1000000007;

fn inv(a: usize) -> usize {
    let m = M as i64;
    let mut a = a as i64;
    let mut b = m as i64;
    let mut u = 1;
    let mut v = 0;
    let mut tmp;
    while b != 0 {
        let t = a / b;
        a -= t * b;
        tmp = a;
        a = b;
        b = tmp;
        u -= t * v;
        tmp = u;
        u = v;
        v = tmp;
    }
    u %= m;
    if u < 0 {
        u += m;
    }
    return u as usize;
}

fn factors(n: usize) -> Vec<usize> {
    let sqrt_n = (n as f64).sqrt() as usize;
    let mut ret = HashSet::new();
    for d in 1..=sqrt_n {
        if n % d == 0 {
            ret.insert(d);
            ret.insert(n / d);
        }
    }
    let mut ret = ret.into_iter().collect::<Vec<_>>();
    ret.sort();
    ret
}

fn dfs(
    n: usize,
    m: usize,
    factors: &HashMap<usize, Vec<usize>>,
    ret: &mut Vec<usize>,
    f: &Vec<usize>,
    g: &Vec<usize>,
) -> usize {
    let depth = ret.len();
    if depth > n {
        return 0;
    }
    if m == 1 {
        let mut count = HashMap::new();
        for &v in ret.iter() {
            *count.entry(v).or_insert(0) += 1;
        }
        count.insert(1, n - depth);
        let mut c = f[n];
        for &ci in count.values() {
            c = c * g[ci] % M;
        }
        // eprintln!("{:?} {}", ret, c);
        return c;
    }
    let mut c = 0;
    for &x in factors.get(&m).unwrap() {
        if x == 1 || (depth > 0 && x > ret[depth - 1]) {
            continue;
        }
        ret.push(x);
        c = (c + dfs(n, m / x, factors, ret, f, g)) % M;
        ret.resize(depth, 0);
    }
    c
}

fn main() {
    input! {
        n: usize,
        m: usize,
    }
    let m_factors = factors(m);
    // eprintln!("{:?}", m_factors);
    let all_factors = m_factors
        .iter()
        .map(|&f| (f, factors(f)))
        .collect::<HashMap<_, _>>();
    // eprintln!("{:?}", all_factors);

    let mut f = vec![1; n + 1];
    let mut g = vec![1; n + 1];
    for i in 1..f.len() {
        f[i] = i * f[i - 1] % M;
        g[i] = inv(f[i]);
    }
    println!("{}", dfs(n, m, &all_factors, &mut vec![], &f, &g));
}
*/

fn main() {
    let exe = "/tmp/bin90CC3D55";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";