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 C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <list>
#include <stack>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>

#define int long long
#define MOD 1000000007

#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, a, n) for (int i = (a); i <= (n); i++)
#define all(a) (a).begin(), (a).end()
#define mp(a, b) make_pair((a), (b))

using namespace std;

int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, -1, 0, 1 };

class ModInt {
private:
	long long value;
	long long mod;

	long long calcModNum(long long value) {
		if (value < 0) {
			long long times = (-value) / this->mod + 1;
			value += this->mod * times;
		}
		return value % this->mod;
	}

	long long extgcd(long long a, long long b, long long &x, long long &y) {
		long long g = a;
		x = 1;
		y = 0;
		if (b != 0) {
			g = extgcd(b, a % b, y, x);
			y -= (a / b) * x;
		}
		return g;
	}

	long long modInverse(long long a, long long b) {
		long long x, y;
		extgcd(a, b, x, y);
		return x;
	}
public:
	// コンストラクタ
	ModInt(int value, int mod) {
		this->value = (long long)value;
		this->mod = (long long)mod;
	}

	// 値を返す
	int getValue() {
		return (int)this->value;
	}

	ModInt operator + (ModInt obj) {
		ModInt retObj(calcModNum(this->value + obj.value), this->mod);
		return retObj;
	}
	void operator += (ModInt obj) {
		this->value = calcModNum(this->value + obj.value);
	}
	ModInt operator + (int value) {
		ModInt retObj(calcModNum(this->value + (long long)value), this->mod);
		return retObj;
	}
	void operator += (int value) {
		this->value = calcModNum(this->value + (long long)value);
	}

	ModInt operator - (ModInt obj) {
		ModInt retObj(calcModNum(this->value - obj.value), this->mod);
		return retObj;
	}
	void operator -= (ModInt obj) {
		this->value = calcModNum(this->value - obj.value);
	}
	ModInt operator - (int value) {
		ModInt retObj(calcModNum(this->value - (long long)value), this->mod);
		return retObj;
	}
	void operator -= (int value) {
		this->value = calcModNum(this->value - (long long)value);
	}

	ModInt operator * (ModInt obj) {
		ModInt retObj(calcModNum(this->value * obj.value), this->mod);
		return retObj;
	}
	void operator *= (ModInt obj) {
		this->value = calcModNum(this->value * obj.value);
	}
	ModInt operator * (int value) {
		ModInt retObj(calcModNum(this->value * (long long)value), this->mod);
		return retObj;
	}
	void operator *= (int value) {
		this->value = calcModNum(this->value * (long long)value);
	}

	ModInt operator / (ModInt obj) {
		ModInt retObj(calcModNum(this->value * modInverse(obj.value, this->mod)), this->mod);
		return retObj;
	}
	void operator /= (ModInt obj) {
		this->value = calcModNum(this->value * modInverse(obj.value, this->mod));
	}
	ModInt operator / (int value) {
		ModInt retObj(calcModNum(this->value * modInverse(value, this->mod)), this->mod);
		return retObj;
	}
	void operator /= (int value) {
		this->value = calcModNum(this->value * modInverse(value, this->mod));
	}
};

int f(int n, int r) {
	ModInt ret(1, MOD);
	REP(i, 1, n + r - 1) ret *= i;
	REP(i, 1, n - 1) ret /= i;
	REP(i, 1, r) ret /= i;
	return ret.getValue();
}

signed main() {
	int N, M;
	cin >> N >> M;

	unordered_map<int, int> m;
	REP(i, 2, 100000) {
		while (M % i == 0) {
			m[i]++;
			M /= i;
		}
		if (M == 1) break;
	}
	if (M > 1) m[M]++;

	int ret = 1;

	for (auto &pr : m) {
		ret *= f(N, pr.second);
		ret %= MOD;
	}

	cout << ret << endl;

    return 0;
}