This time your assignment is really simple.

Calculate GCD(1, 1) * GCD(1, 2) * ... * GCD(1, M) * GCD(2, 1) * GCD(2, 2) * ... * GCD(2, M) * ... * GCD(N, 1) * GCD(N, 2) * ... * GCD(N, M).

where GCD is defined as the Greatest Common Divisor. 

Input Format

The first and only line contains two space separated integers N and M.

Output Format

Output the required product modulo 10^{9}+7.

Constraints

1 <= N, M <= 1.5 * 10^{7}

Sample input:

4 4

Sample output:

96

Explanation

For the above testcase, N = 4, M = 4. So, 

GCD(1, 1) * GCD(1, 2) * ...... * GCD(4, 4) = 1 * 1 * 1 * 1 * 1 * 2 * 1 * 2 * 1 * 1 * 3 * 1 * 1 * 2 * 1 * 4 = 96.

Difficulty: MEDIUM_HARD
Tags: Number theory

Starter code:

Solutions:
import math, sys
MOD = 1000000007

def rwh_primes2(n):
	if n < 3:
		return []
	elif n == 3:
		return [2]
	elif n < 6:
		return [2, 3]
	correction = n % 6 > 1
	n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6]
	sieve = [True] * (n // 3)
	sieve[0] = False
	for i in range(int(n ** 0.5) // 3 + 1):
		if sieve[i]:
			k = 3 * i + 1 | 1
			sieve[k * k // 3::2 * k] = [False] * ((n // 6 - k * k // 6 - 1) // k + 1)
			sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = [False] * ((n // 6 - (k * k + 4 * k - 2 * k * (i & 1)) // 6 - 1) // k + 1)
	return [2, 3] + [3 * i + 1 | 1 for i in range(1, n // 3 - correction) if sieve[i]]
(N, M) = list(map(int, sys.stdin.readline().split()))
(N, M) = (min(N, M), max(N, M))
primes = rwh_primes2(M + 1)
product = 1
for p in primes:
	n = 0
	k = p
	while k <= N:
		n += N // k * (M // k)
		k *= p
	product *= pow(p, n, MOD)
	product %= MOD
print(product)


import math, sys
MOD = 1000000007

def rwh_primes2(n):
	if n < 3:
		return []
	elif n == 3:
		return [2]
	elif n < 6:
		return [2, 3]
	correction = n % 6 > 1
	n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6]
	sieve = [True] * (n // 3)
	sieve[0] = False
	for i in range(int(n ** 0.5) // 3 + 1):
		if sieve[i]:
			k = 3 * i + 1 | 1
			sieve[k * k // 3::2 * k] = [False] * ((n // 6 - k * k // 6 - 1) // k + 1)
			sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = [False] * ((n // 6 - (k * k + 4 * k - 2 * k * (i & 1)) // 6 - 1) // k + 1)
	return [2, 3] + [3 * i + 1 | 1 for i in range(1, n // 3 - correction) if sieve[i]]
(N, M) = list(map(int, sys.stdin.readline().split()))
(N, M) = (min(N, M), max(N, M))
primes = rwh_primes2(M + 1)
product = 1
for p in primes:
	n = 0
	k = p
	while k <= N:
		n += N // k * (M // k)
		k *= p
	product *= pow(p, n, MOD)
	product %= MOD
print(product)


(n, m) = [int(i) for i in input().strip().split()]
val = 1
primes = [True for i in range(n + 1)]
primes[0] = 0
primes[1] = 0
if n < m:
	(n, m) = (m, n)
mo = 1000000007
for i in range(2, m + 1):
	if primes[i]:
		for j in range(i, m + 1, i):
			primes[j] = 0
		summ = 0
		fact = i
		prod1 = n // fact
		prod2 = m // fact
		while prod1 != 0 and prod2 != 0:
			summ += prod1 * prod2
			fact *= i
			prod1 = n // fact
			prod2 = m // fact
		ff = i
		while summ:
			if summ % 2:
				val = val * ff % mo
			ff = ff * ff % mo
			summ //= 2
		val = val % mo
print(val)


def primesTo(n):
	isPrime = [True if i % 2 else False for i in range(n + 1)]
	(isPrime[1], isPrime[2]) = (0, 1)
	for p in range(3, int(n ** 0.5) + 1, 2):
		if isPrime[p]:
			for pq in range(2 * p, n + 1, p):
				isPrime[pq] = False
	return (p for p in range(n + 1) if isPrime[p])

def exponentOf(p, M, N):
	if N < p:
		return 0
	return M // p * (N // p) + exponentOf(p, M // p, N // p)

def modularPower(p, exp, mod):
	if exp == 0:
		return 1
	return (p if exp % 2 else 1) * modularPower(p * p % mod, exp // 2, mod) % mod

def gcdPrimeContribution(p, M, N, mod):
	exp = exponentOf(p, M, N)
	return modularPower(p, exp, mod)

def modProd(entries, mod):
	product = 1
	for entry in entries:
		product = product * entry % mod
	return product

def gcdProduct(M, N, mod):
	(M, N) = (max(M, N), min(M, N))
	return modProd((gcdPrimeContribution(p, M, N, mod) for p in primesTo(N)), mod)

def main():
	(M, N) = map(int, input().split(' '))
	mod = 10 ** 9 + 7
	print(gcdProduct(M, N, mod))
main()


import math, sys
MOD = 1000000007

def rwh_primes2(n):
	if n < 3:
		return []
	elif n == 3:
		return [2]
	elif n < 6:
		return [2, 3]
	correction = n % 6 > 1
	n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6]
	sieve = [True] * (n // 3)
	sieve[0] = False
	for i in range(int(n ** 0.5) // 3 + 1):
		if sieve[i]:
			k = 3 * i + 1 | 1
			sieve[k * k // 3::2 * k] = [False] * ((n // 6 - k * k // 6 - 1) // k + 1)
			sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = [False] * ((n // 6 - (k * k + 4 * k - 2 * k * (i & 1)) // 6 - 1) // k + 1)
	return [2, 3] + [3 * i + 1 | 1 for i in range(1, n // 3 - correction) if sieve[i]]
(N, M) = list(map(int, sys.stdin.readline().split()))
(N, M) = (min(N, M), max(N, M))
primes = rwh_primes2(M + 1)
product = 1
for p in primes:
	n = 0
	k = p
	while k <= N:
		n += N // k * (M // k)
		k *= p
	product *= pow(p, n, MOD)
	product %= MOD
print(product)


def primes_2(n):
	(n, correction) = (n - n % 6 + 6, 2 - (n % 6 > 1))
	sieve = [True] * (n // 3)
	for i in range(1, int(n ** 0.5) // 3 + 1):
		if sieve[i]:
			k = 3 * i + 1 | 1
			sieve[k * k // 3::2 * k] = [False] * ((n // 6 - k * k // 6 - 1) // k + 1)
			sieve[k * (k - 2 * (i & 1) + 4) // 3::2 * k] = [False] * ((n // 6 - k * (k - 2 * (i & 1) + 4) // 6 - 1) // k + 1)
	return [2, 3] + [3 * i + 1 | 1 for i in range(1, n // 3 - correction) if sieve[i]]
modulus = pow(10, 9) + 7
inputs = input().split(' ')
(m, n) = (min(int(inputs[0]), int(inputs[1])), max(int(inputs[0]), int(inputs[1])))
primes = primes_2(m + 1)
result = 1
for prime in primes:
	tmp_result = 0
	k = prime
	while k <= n:
		tmp_result += n // k * (m // k)
		k *= prime
	result *= pow(prime, tmp_result, modulus)
	result %= modulus
print(result)


from fractions import gcd
from math import log
from itertools import takewhile as tw
from os.path import basename, exists, expanduser, splitext, isfile
from os import getcwd
lolPath = getcwd()
randid = '\\qosdjfoiz.txt'
home = isfile(lolPath + randid)
if home:
	from mesures import ch, prof
modo = 10 ** 9 + 7

def initPrim(mp):
	from math import sqrt
	from array import array
	ps = [2, 3, 5, 7, 11]
	top = int(sqrt(mp))
	at = 'b'
	ba = array(at, [0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0])
	c = 1
	while c < 1 + mp // 30:
		ba = ba + ba
		c *= 2
	ba = array(at, [0, 0, 1, 1, 0, 1]) + ba
	ba = ba[:mp]
	ixp = 3
	ixba = 13
	p = ps[ixp]
	while p <= top:
		for i in range(p * p, mp + 1, 2 * p):
			ba[i] = 0
		ixp += 1
		p = ps[ixp]
		tc = p * p
		for j in range(ixba, min(tc, mp), 2):
			if ba[j]:
				ps += [j]
		ixba = tc
	return (ba, ps)

def cl(N, M, nm=False):
	if N > M:
		(N, M) = (M, N)
	res = 1
	for f in tw(lambda x: x <= N, ps):
		mp = int(log(N, f))
		cumpo = 0
		exp = f
		if trace & 1:
			print('facteur:', f)
		for po in range(1, mp + 1):
			cumpo += N // exp * (M // exp)
			exp *= f
			if trace & 1:
				print('\tpuiss cumul', exp, cumpo)
		if nm:
			res = res * pow(f, cumpo)
		else:
			res = res * pow(f, cumpo, modo) % modo
	return res
trace = 0
if home:
	cr = ch()
(ba, ps) = initPrim(15 * 10 ** 6)
if home:
	print(cr.lap())
(N, M) = map(int, input().split())
print(cl(N, M))


MOD = 10 ** 9 + 7
(N, M) = [int(x) for x in input().split()]
if N > M:
	(N, M) = (M, N)

def primes(max):
	a = [True for _ in range(max + 1)]
	current = 2
	while current < max + 1:
		if a[current]:
			yield current
			for x in range(2 * current, max + 1, current):
				a[x] = False
		current += 1

def pow(b, p):
	ans = 1
	acc = b
	while p > 0:
		if p % 2 == 1:
			ans *= acc
		ans %= MOD
		acc = acc * acc % MOD
		p //= 2
	return ans
ans = 1
gen = primes(N)
for p in gen:
	acc = 1
	num = p
	while num <= N:
		ans *= pow(p, N // num * (M // num))
		num *= p
	ans %= MOD
print(ans)


import sys
import math

def gcd(x, y):
	while y != 0:
		(x, y) = (y, x % y)
	return x

def Factors(n):
	pfacts = [1]
	pfacts.remove(1)
	while n % 2 == 0:
		pfacts.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			pfacts.append(i)
			n = n / i
	if n > 2:
		pfacts.append(n)
	return pfacts

def FactorArray(n):
	pfacts = [1]
	pfacts.remove(1)
	temp = n
	if n <= 3:
		return [n]
	count = 1
	while temp % 2 == 0:
		pfacts.append(2 ** count)
		temp = temp // 2
		count += 1
	for i in range(3, int(math.sqrt(temp)) + 1, 2):
		count = 1
		while temp % i == 0:
			pfacts.append(i ** count)
			temp = temp // i
			count += 1
	if temp > 2:
		pfacts.append(temp)
	return pfacts

def primes(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * int((n - i * i - 1) / (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def modExp(x, e, m):
	X = x
	E = e
	Y = 1
	while E > 0:
		if E % 2 == 0:
			X = X * X % m
			E = E / 2
		else:
			Y = X * Y % m
			E = E - 1
	return Y
(n, m) = input().strip().split(' ')
(n, m) = [int(n), int(m)]
res = 1
N = min(n, m)
M = max(n, m)
priArr = primes(2 * N)
countArr = [0] * len(priArr)
res = 1
if N == 1:
	print(1)
else:
	for x in range(0, len(priArr)):
		mulTimes = M // priArr[x]
		count = mulTimes
		mulTimes = mulTimes * (N // priArr[x])
		loopMax = math.floor(math.log(N, priArr[x]))
		for i in range(1, loopMax):
			count = count // priArr[x]
			mulTimes += count * (N // priArr[x] ** (i + 1))
		res = res % 1000000007 * modExp(priArr[x], mulTimes, 1000000007)
	print(res % 1000000007)


(N, M) = map(int, input().split())
lim = min(N, M) + 1
mark = bytearray(lim >> 1)
primes = [2]
for i in range(3, lim, 2):
	if mark[i >> 1]:
		continue
	primes.append(i)
	for j in range(3 * i, lim, 2 * i):
		mark[j >> 1] = 1
mod = 10 ** 9 + 7
prod = 1
for p in primes:
	q = p
	while q < lim:
		prod = prod * pow(p, N // q * (M // q), mod) % mod
		q *= p
print(prod)


(N, M) = map(int, input().split())
lim = min(N, M) + 1
mark = bytearray(lim >> 1)
primes = [2]
for i in range(3, lim, 2):
	if mark[i >> 1]:
		continue
	primes.append(i)
	for j in range(3 * i, lim, 2 * i):
		mark[j >> 1] = 1
mod = 10 ** 9 + 7
prod = 1
for p in primes:
	q = p
	while q < lim:
		prod = prod * pow(p, N // q * (M // q), mod) % mod
		q *= p
print(prod)


def pr_tab(x):
	a = [True] * (x + 1)
	i = 2
	a[0] = False
	a[1] = False
	primes = []
	while i * i <= x:
		a[i] = True
		for j in range(i * 2, x + 1, i):
			a[j] = False
		i = i + 1
		while not a[i]:
			i = i + 1
	for i in range(len(a)):
		if a[i]:
			primes.append(i)
	return primes
mod = 10 ** 9 + 7
prime = pr_tab(10 ** 7 + 5 * 10 ** 6 + 20)
(n, m) = map(int, input().split())
(m, n) = (min(m, n), max(m, n))
p = prime[0]
i = 0
res = 1
while p <= m:
	a = m
	pr = p
	s = 0
	while a // pr != 0:
		s = s + n // p * (m // p)
		p = p * pr
		a = a // pr
	res = res * pow(pr, s, mod) % mod
	i = i + 1
	p = prime[i]
print(res)


(n, m) = [int(i) for i in input().strip().split()]
val = 1
primes = [True for i in range(n + 1)]
primes[0] = 0
primes[1] = 0
if n < m:
	(n, m) = (m, n)
mo = 1000000007
for i in range(2, m + 1):
	if primes[i]:
		for j in range(i, m + 1, i):
			primes[j] = 0
		summ = 0
		fact = i
		prod1 = n // fact
		prod2 = m // fact
		while prod1 != 0 and prod2 != 0:
			summ += prod1 * prod2
			fact *= i
			prod1 = n // fact
			prod2 = m // fact
		ff = i
		while summ:
			if summ % 2:
				val = val * ff % mo
			ff = ff * ff % mo
			summ //= 2
		val = val % mo
print(val)


def primesTo(n):
	isPrime = [True if i % 2 else False for i in range(n + 1)]
	(isPrime[1], isPrime[2]) = (0, 1)
	for p in range(3, int(n ** 0.5) + 1, 2):
		if isPrime[p]:
			for pq in range(2 * p, n + 1, p):
				isPrime[pq] = False
	return (p for p in range(n + 1) if isPrime[p])

def exponentOf(p, M, N):
	if N < p:
		return 0
	return M // p * (N // p) + exponentOf(p, M // p, N // p)

def modularPower(p, exp, mod):
	if exp == 0:
		return 1
	return (p if exp % 2 else 1) * modularPower(p * p % mod, exp // 2, mod) % mod

def gcdPrimeContribution(p, M, N, mod):
	exp = exponentOf(p, M, N)
	return modularPower(p, exp, mod)

def modProd(entries, mod):
	product = 1
	for entry in entries:
		product = product * entry % mod
	return product

def gcdProduct(M, N, mod):
	(M, N) = (max(M, N), min(M, N))
	return modProd((gcdPrimeContribution(p, M, N, mod) for p in primesTo(N)), mod)

def main():
	(M, N) = map(int, input().split(' '))
	mod = 10 ** 9 + 7
	print(gcdProduct(M, N, mod))
main()


MOD = 10 ** 9 + 7
(N, M) = [int(x) for x in input().split()]
if N > M:
	(N, M) = (M, N)

def primes(max):
	a = [True for _ in range(max + 1)]
	current = 2
	while current < max + 1:
		if a[current]:
			yield current
			for x in range(2 * current, max + 1, current):
				a[x] = False
		current += 1

def pow(b, p):
	ans = 1
	acc = b
	while p > 0:
		if p % 2 == 1:
			ans *= acc
		ans %= MOD
		acc = acc * acc % MOD
		p //= 2
	return ans
ans = 1
gen = primes(N)
for p in gen:
	acc = 1
	num = p
	while num <= N:
		ans *= pow(p, N // num * (M // num))
		num *= p
	ans %= MOD
print(ans)


mod = 1000000007

def sieve(bound):
	arr = [1 for i in range(bound - 2)]
	arr.insert(0, 0)
	arr.insert(0, 0)
	ps = []
	l = len(arr)
	sq = 0
	for (i, val) in enumerate(arr):
		if sq > bound:
			break
		elif val == 1:
			ind = i
			ps.append(i)
			for ind in range(sq, l, i):
				arr[ind] = 0
		sq = sq + 2 * i + 1
	for j in range(i, l):
		if arr[j] == 1:
			ps.append(j)
	return ps

def solve(n, m):
	primes = sieve(min(n, m) + 2)
	prod = 1
	for p in primes:
		exp = 0
		ntemp = n // p
		mtemp = m // p
		while ntemp > 0 and mtemp > 0:
			exp += ntemp * mtemp
			ntemp = ntemp // p
			mtemp = mtemp // p
		prod = prod * pow(p, exp, mod) % mod
	return prod
nm = input().split()
n = int(nm[0])
m = int(nm[1])
print(solve(n, m))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


import math
import os
import random
import re
import sys

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


import math, sys
MOD = 1000000007

def rwh_primes2(n):
	if n < 3:
		return []
	elif n == 3:
		return [2]
	elif n < 6:
		return [2, 3]
	correction = n % 6 > 1
	n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6]
	sieve = [True] * (n // 3)
	sieve[0] = False
	for i in range(int(n ** 0.5) // 3 + 1):
		if sieve[i]:
			k = 3 * i + 1 | 1
			sieve[k * k // 3::2 * k] = [False] * ((n // 6 - k * k // 6 - 1) // k + 1)
			sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = [False] * ((n // 6 - (k * k + 4 * k - 2 * k * (i & 1)) // 6 - 1) // k + 1)
	return [2, 3] + [3 * i + 1 | 1 for i in range(1, n // 3 - correction) if sieve[i]]
(N, M) = list(map(int, sys.stdin.readline().split()))
(N, M) = (min(N, M), max(N, M))
primes = rwh_primes2(M + 1)
product = 1
for p in primes:
	n = 0
	k = p
	while k <= N:
		n += N // k * (M // k)
		k *= p
	product *= pow(p, n, MOD)
	product %= MOD
print(product)


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


import math, sys
MOD = 1000000007

def rwh_primes2(n):
	if n < 3:
		return []
	elif n == 3:
		return [2]
	elif n < 6:
		return [2, 3]
	correction = n % 6 > 1
	n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6]
	sieve = [True] * (n // 3)
	sieve[0] = False
	for i in range(int(n ** 0.5) // 3 + 1):
		if sieve[i]:
			k = 3 * i + 1 | 1
			sieve[k * k // 3::2 * k] = [False] * ((n // 6 - k * k // 6 - 1) // k + 1)
			sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = [False] * ((n // 6 - (k * k + 4 * k - 2 * k * (i & 1)) // 6 - 1) // k + 1)
	return [2, 3] + [3 * i + 1 | 1 for i in range(1, n // 3 - correction) if sieve[i]]
(N, M) = list(map(int, sys.stdin.readline().split()))
(N, M) = (min(N, M), max(N, M))
primes = rwh_primes2(M + 1)
product = 1
for p in primes:
	n = 0
	k = p
	while k <= N:
		n += N // k * (M // k)
		k *= p
	product *= pow(p, n, MOD)
	product %= MOD
print(product)


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))


from math import gcd

def primesTo(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def solve(A):
	if A[0] == 1 or A[1] == 1:
		return 1
	m = min(A)
	primes = primesTo(m + 1)
	total = 1
	modo = 10 ** 9 + 7
	for p in primes:
		temp = p
		while temp <= m:
			total = total * pow(p, A[0] // temp * (A[1] // temp), modo) % modo
			temp *= p
	return total % modo
A = list(map(int, input().split()))
print(solve(A))