Problem: Bash got tired on his journey to become the greatest Pokemon master. So he decides to take a break and play with functions.

Bash defines a function f0(n), which denotes the number of ways of factoring n into two factors p and q such that gcd(p, q) = 1. In other words, f0(n) is the number of ordered pairs of positive integers (p, q) such that p·q = n and gcd(p, q) = 1.

But Bash felt that it was too easy to calculate this function. So he defined a series of functions, where fr + 1 is defined as:

<image>

Where (u, v) is any ordered pair of positive integers, they need not to be co-prime.

Now Bash wants to know the value of fr(n) for different r and n. Since the value could be huge, he would like to know the value modulo 109 + 7. Help him!

Input

The first line contains an integer q (1 ≤ q ≤ 106) — the number of values Bash wants to know.

Each of the next q lines contain two integers r and n (0 ≤ r ≤ 106, 1 ≤ n ≤ 106), which denote Bash wants to know the value fr(n).

Output

Print q integers. For each pair of r and n given, print fr(n) modulo 109 + 7 on a separate line.

Example

Input

5
0 30
1 25
3 65
2 5
4 48


Output

8
5
25
4
630

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class E {
	public static void main(String[] args) throws NumberFormatException, IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		genPrimes();
		
		int q = sc.nextInt();
		
		int mod = (int) 1e9 + 7;
		int maxR = (int) 1e6 + 1;
		int maxP = 20;
		long dp[][] = new long[maxR][maxP];
		
		Arrays.fill(dp[0], 2);
		for(int i = 0; i < maxR; i++)
			dp[i][0] = 1;
		
		for(int i = 1; i < maxR; i++)
			for(int j = 1; j < maxP; j++) {
				dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
			}
		
		while(q-->0) {
			int r = sc.nextInt();
			int n = sc.nextInt();
			ArrayList<Integer> pows = getPows(n);

			long ans = 1;
			for(int p : pows) {
				ans *= dp[r][p];
				ans %= mod;
			}
			
			out.println(ans);
		}
		
		out.flush();
		out.close();
	}
	
	private static ArrayList<Integer> getPows(int n) {

		ArrayList<Integer> ans = new ArrayList<Integer>();
		for(int p : primes) {
			if(p * p > n)
				break;
			int pow = 0;
			while(n % p == 0) {
				n /= p;
				pow++;
			}
			
			if(pow > 0)
				ans.add(pow);

			if(n == 1)
				break;
		}
		if(n > 1)
			ans.add(1);
		
		return ans;
	}

	static ArrayList<Integer> primes;
	static void genPrimes() {
		primes = new ArrayList<Integer>();
		int max = (int) 1e3;
		boolean isPrime[] = new boolean[max];
		Arrays.fill(isPrime, true);
		isPrime[0] = isPrime[1] = false;
		for(int i = 2; i < max; i++)
			if(isPrime[i]) {
				primes.add(i);
				for(int j = i * 2; j < max; j += i)
					isPrime[j] = false;
			}
	}
	
	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner(FileReader f) {
			br = new BufferedReader(f);
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}
	}
}