You are given $n$ positive integers $a_1, \ldots, a_n$, and an integer $k \geq 2$. Count the number of pairs $i, j$ such that $1 \leq i < j \leq n$, and there exists an integer $x$ such that $a_i \cdot a_j = x^k$.


-----Input-----

The first line contains two integers $n$ and $k$ ($2 \leq n \leq 10^5$, $2 \leq k \leq 100$).

The second line contains $n$ integers $a_1, \ldots, a_n$ ($1 \leq a_i \leq 10^5$).


-----Output-----

Print a single integer — the number of suitable pairs.


-----Example-----
Input
6 3
1 3 9 8 24 1

Output
5



-----Note-----

In the sample case, the suitable pairs are: $a_1 \cdot a_4 = 8 = 2^3$; $a_1 \cdot a_6 = 1 = 1^3$; $a_2 \cdot a_3 = 27 = 3^3$; $a_3 \cdot a_5 = 216 = 6^3$; $a_4 \cdot a_6 = 8 = 2^3$.

Difficulty: MEDIUM_HARD

Solutions:
from collections import defaultdict
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
n = int(max(a) ** 0.5)
mark = [True] * (n + 1)
prime = []
for i in range(2, n + 1):
	if mark[i]:
		for j in range(i, n + 1, i):
			mark[j] = False
		prime.append(i)
d = defaultdict(int)
(ans, count) = (0, 0)
for i in a:
	(t, t1) = ((), ())
	for j in prime:
		if i == 1:
			break
		if i % j == 0:
			count = 0
			while i % j == 0:
				i //= j
				count += 1
			z = count % k
			if z:
				t += (j, z)
				t1 += (j, k - z)
	if i > 1:
		t += (i, 1)
		t1 += (i, k - 1)
	ans += d[t1]
	d[t] += 1
print(ans)


import math
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
import math as mt
MAXN = 100001
spf = [0 for i in range(MAXN)]

def sieve():
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(4, MAXN, 2):
		spf[i] = 2
	for i in range(3, mt.ceil(mt.sqrt(MAXN))):
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i

def getFactorization(x):
	ret = list()
	while x != 1:
		ret.append(spf[x])
		x = x // spf[x]
	return ret
sieve()
(n, k) = map(int, input().split())
l = list(map(int, input().split()))
d = dict()
ans = 0
for i in range(n):
	s = set()
	rem = set()
	prime = getFactorization(l[i])
	for j in prime:
		if l[i] % j == 0:
			p = 0
			while l[i] % j == 0:
				p += 1
				l[i] //= j
			if p % k != 0:
				s.add(j ** (p % k))
				rem.add(j ** ((k - p) % k))
	s = tuple(s)
	rem = tuple(rem)
	if rem in d:
		ans += d[rem]
	if s in d:
		d[s] += 1
	else:
		d.update({s: 1})
print(ans)


import itertools as it
from collections import defaultdict
import os
import sys

def sieve(n):
	is_prime = [True] * n
	for candidate in it.chain([2], range(3, int(n ** 0.5) + 1, 2)):
		if is_prime[candidate]:
			for k in range(2 * candidate, n, candidate):
				is_prime[k] = False
	primes = [idx for (idx, k) in enumerate(is_prime) if idx >= 2 and k]
	return primes

def factorize(n, primes, k):
	factors = []
	number = n
	for f in primes:
		count = 0
		while number % f == 0:
			count += 1
			number //= f
		if count % k:
			factors.append((f, count % k))
		if f > number:
			break
	if number > 1:
		factors.append((number, 1))
	return tuple(factors)

def solve(arr, k):
	total = 0
	d = defaultdict(int, {})
	primes = sieve(int(100000.0 ** 0.5) + 10)
	for a in arr:
		fac = factorize(a, primes, k)
		fac_complement = tuple(((f, k - count) for (f, count) in fac))
		total += d[fac_complement]
		d[fac] += 1
	return total

def pp(input):
	(n, k) = map(int, input().strip().split())
	arr = map(int, input().strip().split())
	print(solve(arr, k))
if 'paalto' in os.getcwd():
	from string_source import string_source, codeforces_parse
	pp(string_source('6 3\n1 3 9 8 24 1'))
else:
	pp(sys.stdin.readline)


import math

def sieve_of_eratosthenes(n=100000):
	prime = [True for i in range(n + 1)]
	prime[0] = False
	prime[1] = False
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * 2, n + 1, p):
				prime[i] = False
		p += 1
	return prime

def prime_factorization(n, k, prime):
	a = list()
	b = list()
	i = 2
	while n > 1:
		if prime[i]:
			count = 0
			while n % i == 0:
				count += 1
				n = n // i
			if count % k != 0:
				a.append((i, count % k))
				b.append((i, k - count % k))
		i += 1
	return [tuple(a), tuple(b)]

def prime_factorization2(n, k):
	a = list()
	b = list()
	count = 0
	while n % 2 == 0:
		count += 1
		n = n / 2
	if count > 0 and count % k != 0:
		a.append((2, count % k))
		b.append((2, k - count % k))
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		count = 0
		while n % i == 0:
			count += 1
			n = n / i
		if count > 0 and count % k != 0:
			a.append((i, count % k))
			b.append((i, k - count % k))
	if n > 2:
		a.append((n, 1))
		b.append((n, k - 1))
	return [tuple(a), tuple(b)]

def solve(a, k):
	result = 0
	hashmap = {}
	for i in a:
		(x, y) = prime_factorization2(i, k)
		if y in hashmap:
			result += hashmap[y]
		if x in hashmap:
			hashmap[x] += 1
		else:
			hashmap[x] = 1
	return result
values = input().split()
(_, k) = (int(values[0]), int(values[1]))
a = list(map(int, input().split()))
print(solve(a, k))


def f(n):
	Ans = []
	d = 2
	while d * d <= n:
		if n % d == 0:
			Ans.append(d)
			n //= d
		else:
			d += 1
	if n > 1:
		Ans.append(n)
	return Ans
(n, k) = map(int, input().split())
arr = list(map(int, input().split()))
m = {}
c = 0
for i in arr:
	r = {}
	d = 2
	while d * d <= i:
		if i % d == 0:
			r[d] = (r.get(d, 0) + 1) % k
			i //= d
		else:
			d += 1
	if i > 1:
		r[i] = (r.get(i, 0) + 1) % k
	r = tuple(filter(lambda x: x[1], r.items()))
	r2 = tuple(map(lambda x: (x[0], k - x[1]), r))
	c += m.get(r2, 0)
	m[r] = m.get(r, 0) + 1
print(c)


import os, sys
from io import BytesIO, IOBase
from collections import Counter

def main():
	(n, k) = map(int, input().split())
	a = list(map(int, input().split()))
	sieve = [Counter() for _ in range(10 ** 5 + 1)]
	for i in range(2, 10 ** 5 + 1):
		if not len(sieve[i]):
			for x in range(i, 10 ** 5 + 1, i):
				(z, c) = (x, 0)
				while not z % i:
					c += 1
					z //= i
				sieve[x][i] += c
				if sieve[x][i] > k:
					sieve[x][i] %= k
					if not sieve[x][i]:
						sieve[x][i] = k
	x = Counter(a)
	ans = 0
	powe = [pow(2, k)]
	for j in range(3, 400):
		xx = pow(j, k)
		powe.append(xx)
		if xx > 10 ** 5:
			break
	for i in a:
		num = 1
		x[i] -= 1
		for j in sieve[i]:
			num *= pow(j, k - sieve[i][j])
			if num > 10 ** 5:
				break
		ans += x[num]
		for xx in range(2, 400):
			num1 = num * powe[xx - 2]
			if num1 <= 10 ** 5:
				ans += x[num1]
			else:
				break
	print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


(n, k) = map(int, input().split())
a = list(map(int, input().split()))
d = {}
ans = 0
for el in a:
	i = 2
	a = []
	b = []
	while i * i <= el:
		cnt = 0
		while not el % i:
			el //= i
			cnt += 1
		if cnt % k:
			a.append((i, cnt % k))
			b.append((i, k - cnt % k))
		i += 1
	if el > 1:
		a.append((el, 1))
		b.append((el, k - 1))
	a = tuple(a)
	b = tuple(b)
	ans += d.get(b, 0)
	d[a] = d.get(a, 0) + 1
print(ans)


from math import sqrt

def gd(n, k):
	ans = 1
	obrans = 1
	for i in range(2, int(sqrt(n) + 1)):
		j = 0
		while n % i == 0:
			j += 1
			n //= i
		ans *= pow(i, j % k)
		obrans *= pow(i, -j % k)
	ans *= n
	obrans *= pow(n, k - 1)
	return (ans, obrans)
(n, k) = map(int, input().split())
oba = set()
dct = {}
for i in list(map(int, input().split())):
	(a, b) = gd(i, k)
	dct[a] = dct.get(a, 0) + 1
	(a, b) = (min(a, b), max(a, b))
	oba.add((a, b))
ans = 0
for (i, j) in oba:
	if i == j:
		ans += (dct.get(i, 0) * dct.get(j, 0) - dct.get(i, 0)) // 2
	else:
		ans += dct.get(i, 0) * dct.get(j, 0)
print(ans)


import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')
(n, k) = map(int, input().split())
a = list(map(int, input().split()))

def factors(n, k):
	i = 2
	sq = int(n ** 0.5) + 1
	di = {}
	while n != 1:
		if n % i == 0:
			cur = 0
			while n % i == 0:
				n = n // i
				cur += 1
			if cur % k != 0:
				di[i] = cur % k
		i += 1
		if i > sq:
			break
	if n != 1:
		di[n] = 1
	return '|'.join(('%d:%d' % (i, di[i]) for i in di))
ft = {}
di = {}
for i in a:
	ft[i] = factors(i, k)
	di[ft[i]] = 1 if ft[i] not in di else di[ft[i]] + 1
ans = 0
for i in a:
	ftt = ft[i]
	if ftt == '':
		ans += di[ftt] - 1
	else:
		dx = {}
		for oo in ftt.split('|'):
			(x, y) = map(int, oo.split(':'))
			dx[x] = -y % k
		ftt2 = '|'.join(('%d:%d' % (i, dx[i]) for i in dx))
		if ftt == ftt2:
			ans += di[ftt2] - 1
		elif ftt2 in di:
			ans += di[ftt2]
print(ans // 2)


from collections import defaultdict as dc
dic = dc(lambda : 0)
(x, y) = list(map(int, input().split()))
s = list(map(int, input().split()))
siv = [0] * (max(s) + 1)
ln = len(siv)
siv[1] = 1
for n in range(2, ln):
	if siv[n] == 0:
		siv[n] = n
		for k in range(2 * n, ln, n):
			if siv[k] == 0:
				siv[k] = n

def prf(x):
	dic = dc(lambda : 0)
	while x > 1:
		d = siv[x]
		dic[siv[x]] += 1
		x //= siv[x]
	return dic

def req(dic, k):
	cur = dic
	for n in cur:
		cur[n] %= k
	for n in cur:
		cur[n] = (k - cur[n]) % k
	tot = 1
	for n in cur:
		tot *= n ** cur[n]
	return tot

def conv(x, k):
	dicc = prf(x)
	for n in dicc:
		dicc[n] %= k
	tot = 1
	for n in dicc:
		tot *= n ** dicc[n]
	return tot
res = 0
for n in s:
	re = req(prf(n), y)
	res += dic[re]
	dic[conv(n, y)] += 1
print(res)


import math as mt
from typing import Counter

def sieve():
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(4, MAXN, 2):
		spf[i] = 2
	for i in range(3, mt.ceil(mt.sqrt(MAXN))):
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i

def getFactorization(x, k):
	li = dict()
	while x != 1:
		if not spf[x] in li:
			li[spf[x]] = 0
		li[spf[x]] += 1
		if li[spf[x]] == k:
			del li[spf[x]]
		x = x // spf[x]
	li_prime = li.copy()
	for i in li_prime.keys():
		li_prime[i] = k - li_prime[i]
	return (tuple(li.items()), tuple(li_prime.items()))

def Solution(n, k, array):
	lists = dict()
	sieve()
	count = 0
	for i in array:
		if len(mask_li[i]) == 0:
			(li, li_prime) = getFactorization(i, k)
			mask_li[i] = li
			mask_li_prime[i] = li_prime
		if mask_li_prime[i] in lists:
			count += lists[mask_li_prime[i]]
		if mask_li[i] in lists:
			lists[mask_li[i]] += 1
		else:
			lists[mask_li[i]] = 1
	return count
values = input().split()
(n, k) = (int(values[0]), int(values[1]))
a = list(map(int, input().split()))
maximun = max(a)
MAXN = maximun + 1
mask_li = [() for i in range(0, maximun + 1)]
mask_li_prime = [() for i in range(0, maximun + 1)]
spf = [0 for i in range(MAXN)]
result = Solution(n, k, a)
print(result)


import array
import math
import os
import sys

def main():
	init_primes()
	(N, K) = read_ints()
	A = read_ints()
	print(solve(N, K, A))
PRIMES = []
PMAX = 100000

def init_primes():
	b = [0] * (PMAX + 1)
	for i in range(2, PMAX + 1):
		if not b[i]:
			PRIMES.append(i)
			for j in range(i + i, PMAX + 1, i):
				b[j] = 1

def solve(N, K, A):
	high = max(A)
	D = dict()
	for a in A:
		if a not in D:
			D[a] = 0
		D[a] += 1
	ans = 0
	for (a, c) in D.items():
		if a == 1:
			ans += c * (c - 1)
			continue
		b = 1
		x = a
		for p in PRIMES:
			if x == 1:
				break
			if x % p == 0:
				b *= p
				x //= p
				while x % p == 0:
					x //= p
		assert x == 1
		p = b ** K
		i = 1
		while True:
			x = i ** K * p
			if x > high * high:
				break
			if x % a == 0:
				y = x // a
				if a == y:
					ans += c * (c - 1)
				elif y in D:
					f = 1
					if y == 1:
						f = 2
					ans += f * c * D[y]
			i += 1
	return ans // 2
DEBUG = 'DEBUG' in os.environ

def inp():
	return sys.stdin.readline().rstrip()

def read_int():
	return int(inp())

def read_ints():
	return [int(e) for e in inp().split()]

def dprint(*value, sep=' ', end='\n'):
	if DEBUG:
		print(*value, sep=sep, end=end)
main()


from collections import defaultdict
import sys as _sys

def main():
	(n, k) = _read_ints()
	a = tuple(_read_ints())
	result = find_good_pairs_n(a, k)
	print(result)

def _read_line():
	result = _sys.stdin.readline()
	assert result[-1] == '\n'
	return result[:-1]

def _read_ints():
	return map(int, _read_line().split())

def find_good_pairs_n(sequence, k):
	sequence = tuple(sequence)
	factors_seq = tuple(map(_find_prime_factors, sequence))
	factors_seq = map(lambda factors: map(lambda kv: (kv[0], kv[1] % k), factors.items()), factors_seq)
	factors_seq = map(lambda factors: filter(lambda kv: kv[1] > 0, factors), factors_seq)
	factors_seq = map(sorted, factors_seq)
	factors_seq = tuple(map(tuple, factors_seq))
	counter = defaultdict(int)
	for factors in factors_seq:
		counter[factors] += 1
	result = 0
	for factors in factors_seq:
		necessary_factors = tuple(((factor, k - amount) for (factor, amount) in factors))
		result += counter[necessary_factors]
		if factors == necessary_factors:
			result -= 1
	assert result % 2 == 0
	result //= 2
	return result

def _find_prime_factors(x):
	result = dict()
	if x % 2 == 0:
		factor_2_n = 0
		while x & 1 == 0:
			x >>= 1
			factor_2_n += 1
		result[2] = factor_2_n
	factor = 3
	while x != 1 and factor * factor <= x:
		if x % factor == 0:
			factor_n = 0
			while x % factor == 0:
				x //= factor
				factor_n += 1
			result[factor] = factor_n
		factor += 2
	if x != 1:
		result[x] = 1
	return result
main()


import collections
import time
import os
import sys
import bisect
import heapq
from typing import List
import math

def factors(val):
	wc = []
	for i in range(2, int(math.sqrt(val)) + 2):
		if i > val:
			break
		if val % i == 0:
			c = 0
			while val % i == 0:
				c += 1
				val //= i
			wc.append((i, c))
	if val > 1:
		wc.append((val, 1))
	return wc

def expand(fc, maxd, k):

	def dfs(index, mul):
		if index >= len(fc):
			return [mul]
		(w, c) = fc[index]
		d = k - c % k if c % k != 0 else 0
		x = []
		t = mul * w ** d
		while t <= maxd:
			x.extend(dfs(index + 1, t))
			d += k
			t *= w ** k
		return x
	return dfs(0, 1)

def solve(N, K, A):
	wc = collections.defaultdict(int)
	ans = 0
	for v in A:
		fc = factors(v)
		fc = [(f, c % K) for (f, c) in fc if c % K != 0]
		key = '_'.join(['{}+{}'.format(f, c) for (f, c) in fc])
		cov = [(f, K - c) for (f, c) in fc]
		ckey = '_'.join(['{}+{}'.format(f, c) for (f, c) in cov])
		ans += wc[ckey]
		wc[key] += 1
	return ans
(N, K) = map(int, input().split())
A = [int(x) for x in input().split()]
print(solve(N, K, A))


from collections import Counter as C
NN = 100000
X = [-1] * (NN + 1)
L = [[] for _ in range(NN + 1)]
k = 2
while k <= NN:
	X[k] = 1
	L[k].append(k)
	for i in range(k * 2, NN + 1, k):
		X[i] = 0
		L[i].append(k)
	d = 2
	while k ** d <= NN:
		for i in range(k ** d, NN + 1, k ** d):
			L[i].append(k)
		d += 1
	while k <= NN and X[k] >= 0:
		k += 1
P = [i for i in range(NN + 1) if X[i] == 1]
K = 4

def free(ct):
	a = 1
	for c in ct:
		a *= c ** (ct[c] % K)
	return a

def inv(ct):
	a = 1
	for c in ct:
		a *= c ** (-ct[c] % K)
	return a
(N, K) = map(int, input().split())
A = [int(a) for a in input().split()]
D = {}
ans = 0
for a in A:
	c = C(L[a])
	invc = inv(c)
	if invc in D:
		ans += D[invc]
	freec = free(c)
	if freec in D:
		D[freec] += 1
	else:
		D[freec] = 1
print(ans)


import math

def prime_factorization(n, k):
	a = list()
	b = list()
	count = 0
	while n % 2 == 0:
		count += 1
		n = n / 2
	if count > 0 and count % k != 0:
		a.append((2, count % k))
		b.append((2, k - count % k))
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		count = 0
		while n % i == 0:
			count += 1
			n = n / i
		if count > 0 and count % k != 0:
			a.append((i, count % k))
			b.append((i, k - count % k))
	if n > 2:
		a.append((n, 1))
		b.append((n, k - 1))
	return [tuple(a), tuple(b)]

def solve(a, k):
	result = 0
	hashmap = {}
	for i in a:
		(x, y) = prime_factorization(i, k)
		if y in hashmap:
			result += hashmap[y]
		if x in hashmap:
			hashmap[x] += 1
		else:
			hashmap[x] = 1
	return result
values = input().split()
(_, k) = (int(values[0]), int(values[1]))
a = list(map(int, input().split()))
print(solve(a, k))


import os
import sys
from io import BytesIO, IOBase
from collections import Counter

def seieve_prime_factorisation(n):
	(p, i) = ([1] * (n + 1), 2)
	while i * i <= n:
		if p[i] == 1:
			for j in range(i * i, n + 1, i):
				p[j] = i
		i += 1
	return p

def prime_factorisation_by_seive(p, x):
	c = Counter()
	while p[x] != 1:
		c[p[x]] += 1
		x = x // p[x]
	c[x] += 1
	return c

def main():
	(n, k) = map(int, input().split())
	a = list(map(int, input().split()))
	ma = max(a)
	p = seieve_prime_factorisation(ma)
	b = Counter()
	(ans, z) = (0, 0)
	for i in a:
		if i != 1:
			(c, d) = ([], [])
			e = prime_factorisation_by_seive(p, i)
			for j in sorted(e.keys()):
				y = e[j] % k
				if y:
					c.append((j, y))
					d.append((j, k - y))
			if c:
				(c, d) = (tuple(c), tuple(d))
				b[c] += 1
				ans += b[d] - (c == d)
			else:
				z += 1
		else:
			z += 1
	print(ans + z * (z - 1) // 2)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import math
from collections import Counter
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
ans = 0
prev = Counter()
for x in a:
	sig = []
	p = 2
	while p <= math.sqrt(x):
		cnt = 0
		while x % p == 0:
			cnt += 1
			x = x // p
		cnt = cnt % k
		if cnt > 0:
			sig.append((p, cnt))
		p += 1
	if x > 1:
		sig.append((x, 1))
	com_sig = []
	for (p, val) in sig:
		com_sig.append((p, (k - val) % k))
	ans += prev[tuple(sig)]
	prev[tuple(com_sig)] += 1
print(ans)


from collections import defaultdict
largerPrime = list(range(10 ** 5 + 1))

def largestPrime(N=10 ** 5):
	for i in range(2, N + 1):
		if largerPrime[i] == i:
			for j in range(i * 2, N + 1, i):
				largerPrime[j] = i
largestPrime()

def primeFactors(n, k):
	primeFactors = defaultdict(int)
	while n != 1:
		primeFactors[largerPrime[n]] += 1
		primeFactors[largerPrime[n]] %= k
		n = int(n / largerPrime[n])
	return primeFactors

def negate(pair, k):
	neg = []
	for key in pair:
		if pair[key]:
			neg.append((key, k - pair[key]))
	neg.sort()
	if neg:
		return neg
	return 1
(n, k) = map(int, input().split())
arr = [int(x) for x in input().split()]
one = 0
ans = 0
d = defaultdict(int)
for i in arr:
	fac = primeFactors(i, k)
	x = negate(fac, k)
	if x == 1:
		ans += one
		one += 1
	else:
		x = tuple(x)
		ans += d[x]
		save = []
		for key in fac:
			if fac[key]:
				save.append((key, fac[key]))
		save.sort()
		d[tuple(save)] += 1
print(ans)


from collections import defaultdict
import math
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
ans = 0
hm = defaultdict(int)
for i in range(n):
	x = 2
	t = []
	t1 = []
	y = a[i]
	while x <= math.sqrt(a[i]):
		if a[i] % x == 0:
			c = 0
			while y % x == 0:
				y = y // x
				c += 1
			if c % k > 0:
				t.append((x, c % k))
				t1.append((x, k - c % k))
		x += 1
	if y > 1:
		t.append((y, 1 % k))
		t1.append((y, k - 1 % k))
	ans += hm[tuple(t1)]
	hm[tuple(t)] += 1
print(ans)


from collections import defaultdict

class Primes:

	def __init__(self, N):
		self.N = N
		self.prime = {i for i in range(2, self.N + 1)}
		self.spf = [-1] * (N + 1)
		for i in range(2, self.N + 1):
			if i in self.prime:
				self.spf[i] = i
				for j in range(i * 2, self.N + 1, i):
					if j in self.prime:
						self.spf[j] = i
						self.prime.remove(j)

	def fact(self, Number):
		v = Number
		d = defaultdict(int)
		while v > 1:
			x = self.spf[v]
			d[x] += 1
			v //= x
		return d
P = Primes(10 ** 5)
(n, k) = list(map(int, input().split()))
a = list(map(int, input().split()))
cnt = [0] * (10 ** 5 + 1)
for v in a:
	cnt[v] += 1
ans = 0
for v in a:
	cnt[v] -= 1
	d = P.fact(v)
	res = 1
	for (num, order) in list(d.items()):
		res *= pow(num, (k - order % k) % k)
	if res <= 10 ** 5:
		for i in range(1, 1000):
			if pow(i, k) * res > 10 ** 5:
				break
			ans += cnt[pow(i, k) * res]
print(ans)


(n, k) = list(map(int, input().split()))
arr = list(map(int, input().split()))
ans = 0
d = {}
for i in range(n):
	x = 2
	a = []
	b = []
	y = arr[i]
	while x * x <= arr[i]:
		if arr[i] % x == 0:
			c = 0
			while y % x == 0:
				y = y // x
				c += 1
			if c % k > 0:
				a.append((x, c % k))
				b.append((x, k - c % k))
		x += 1
	if y > 1:
		a.append((y, 1 % k))
		b.append((y, k - 1 % k))
	try:
		ans += d[tuple(b)]
	except:
		pass
	try:
		d[tuple(a)] += 1
	except:
		d[tuple(a)] = 1
print(ans)


from collections import defaultdict
import sys

class Primes:

	def __init__(self, N):
		self.n = N
		self.spf = [1] * (N + 1)
		self.isprime = [True] * (N + 1)
		self.isprime[0] = self.isprime[1] = False
		self.primes = []
		for i in range(2, N + 1):
			if self.isprime[i]:
				self.primes.append(i)
				self.spf[i] = i
				for j in range(i * i, N + 1, i):
					self.isprime[j] = False
					self.spf[j] = i

	def GETPRIMES(self):
		return self.primes

	def fact(self, M):
		assert M <= self.n
		d = defaultdict(int)
		while M > 1:
			p = self.spf[M]
			exp = 0
			while M % p == 0:
				M //= p
				exp += 1
			d[p] = exp
		return d

	def isprime(self, M):
		assert M <= self.n
		return self.isprime[M]

def input():
	return sys.stdin.readline().rstrip()
MAXN = int(100000.0)

def slv():
	(n, k) = map(int, input().split())
	P = Primes(MAXN)
	Pairs = set([])
	a = list(map(int, input().split()))
	C = [0] * (MAXN + 1)
	for elem in a:
		fac = P.fact(elem)
		v = 1
		pair_v = 1
		for (p, ord) in fac.items():
			if ord % k != 0:
				v *= pow(p, ord % k)
				pair_v *= pow(p, k - ord % k)
		C[v] += 1
		(v, pair_v) = (min(v, pair_v), max(v, pair_v))
		if not (len(fac) > 1 and k > 60):
			Pairs.add((v, pair_v))
	ans = 0
	for (v, pair_v) in Pairs:
		if v <= MAXN and pair_v <= MAXN:
			if v != pair_v:
				ans += C[v] * C[pair_v]
			else:
				ans += C[v] * (C[pair_v] - 1) // 2
	print(ans)
	return

def main():
	t = 1
	for i in range(t):
		slv()
	return
main()


from collections import defaultdict
total = 0
import math
dic = defaultdict(int)
(n, k) = list(map(int, input().split()))
z = list(map(int, input().split()))
for ii in z:
	i = ii
	x = []
	x2 = []
	a = 2
	while a <= math.sqrt(ii):
		co = 0
		while i % a == 0:
			i = i // a
			co += 1
		co = co % k
		if co:
			x.append((a, co))
			x2.append((a, k - co))
		a += 1
	if i > 1:
		x.append((i, 1))
		x2.append((i, k - 1))
	dic[tuple(x)] += 1
	total += dic[tuple(x2)]
	if x2 == x:
		total -= 1
print(total)


(n, k) = map(int, input().split())
A = list(map(int, input().split()))
import math
from collections import Counter
C = Counter()
for x in A:
	L = int(math.sqrt(x))
	FACT = dict()
	for i in range(2, L + 2):
		while x % i == 0:
			FACT[i] = FACT.get(i, 0) + 1
			x = x // i
	if x != 1:
		FACT[x] = FACT.get(x, 0) + 1
	for f in list(FACT):
		FACT[f] %= k
		if FACT[f] == 0:
			del FACT[f]
	if FACT == dict():
		C[1, 1] += 1
	else:
		RET = 1
		ALL = 1
		for f in FACT:
			RET *= f ** FACT[f]
			ALL *= f ** k
		C[RET, ALL // RET] += 1
ANS = 0
ANS2 = 0
for (x, y) in C:
	if x == y:
		ANS += C[x, y] * (C[x, y] - 1) // 2
	else:
		ANS2 += C[x, y] * C[y, x]
print(ANS + ANS2 // 2)


import sys
input = sys.stdin.readline
from collections import defaultdict
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
dd = defaultdict(int)
ans = 0
for aa in a:
	primes = []
	b = aa
	for j in range(2, int(b ** 0.5) + 1):
		if b % j == 0:
			cnt = 0
			while b % j == 0:
				cnt += 1
				b //= j
			primes.append([j, cnt])
	if b > 1:
		primes.append([b, 1])
	(key1, key2) = (1, 1)
	for (p, c) in primes:
		if c % k != 0:
			key1 *= p ** (c % k)
			key2 *= p ** (k - c % k)
	ans += dd[key2]
	dd[key1] += 1
print(ans)


from math import *
(n, k) = list(map(int, input().split()))
a = [int(i) for i in input().split()]
ma = max(a)
p = []
prime = [True] * (ma + 1)
prime[0] = False
prime[1] = False
for i in range(2, ma + 1):
	if prime[i]:
		p.append(i)
		if i ** 2 <= n:
			for j in range(i ** 2, ma + 1, i):
				prime[j] = False

def factor(x):
	res = {}
	sq = ceil(sqrt(x))
	for i in p:
		if i > sq or x <= 1:
			break
		if x % i == 0:
			res[i] = 0
			while x % i == 0:
				res[i] += 1
				x //= i
	if x > 1:
		res[x] = 1
	nres = []
	for j in res:
		if res[j] % k > 0:
			nres.append((j, res[j] % k))
	return tuple(nres)
d = {}
for i in range(n):
	f = factor(a[i])
	if f not in d:
		d[f] = 1
	else:
		d[f] += 1
ans = 0
for x in d:
	y = []
	for i in x:
		y.append((i[0], k - i[1]))
	y = tuple(y)
	if y in d:
		if y != x:
			ans += d[x] * d[y]
		else:
			ans += d[x] * (d[y] - 1)
print(ans // 2)


from collections import defaultdict
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
n = int(max(a) ** 0.5)
mark = [True] * (n + 1)
primes = []
for i in range(2, n + 1):
	if mark[i]:
		primes.append(i)
		for j in range(i, n + 1, i):
			mark[j] = False
d = defaultdict(int)
ans = 0
for i in a:
	(t, t1) = ((), ())
	for j in primes:
		if i == 1:
			break
		elif i % j == 0:
			x = 0
			while i % j == 0:
				i //= j
				x += 1
			z = x % k
			if z:
				t += (j, z)
				t1 += (j, k - z)
	if i != 1:
		t += (i, 1)
		t1 += (i, k - 1)
	ans += d[t1]
	d[t] += 1
print(ans)


import sys
zz = 1
sys.setrecursionlimit(10 ** 5)
if zz:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('all.txt', 'w')
di = [[-1, 0], [1, 0], [0, 1], [0, -1]]

def fori(n):
	return [fi() for i in range(n)]

def inc(d, c, x=1):
	d[c] = d[c] + x if c in d else x

def ii():
	return input().rstrip()

def li():
	return [int(xx) for xx in input().split()]

def fli():
	return [float(x) for x in input().split()]

def comp(a, b):
	if a > b:
		return 2
	return 2 if a == b else 0

def gi():
	return [xx for xx in input().split()]

def gtc(tc, ans):
	print('Case #' + str(tc) + ':', ans)

def cil(n, m):
	return n // m + int(n % m > 0)

def fi():
	return int(input())

def pro(a):
	return reduce(lambda a, b: a * b, a)

def swap(a, i, j):
	(a[i], a[j]) = (a[j], a[i])

def si():
	return list(input().rstrip())

def mi():
	return map(int, input().split())

def gh():
	sys.stdout.flush()

def isvalid(i, j, n, m):
	return 0 <= i < n and 0 <= j < m

def bo(i):
	return ord(i) - ord('a')

def graph(n, m):
	for i in range(m):
		(x, y) = mi()
		a[x].append(y)
		a[y].append(x)
t = 1
uu = t
while t > 0:
	t -= 1
	(n, k) = mi()
	a = li()
	d = {}
	ans = 0
	for i in a:
		p = i
		j = 2
		r = []
		while j * j <= p:
			if p % j == 0:
				c = 0
				while p % j == 0:
					p //= j
					c += 1
				if c % k:
					r.append(j)
					r.append(c % k)
			j += 1
		if p >= 2:
			r.append(p)
			r.append(1)
		b = []
		for j in range(len(r)):
			if j % 2:
				b.append(k - r[j])
			else:
				b.append(r[j])
		ans += d.get(tuple(b), 0)
		inc(d, tuple(r))
	print(ans)


import os
import sys
from bisect import bisect_right
from collections import Counter, defaultdict
from heapq import *
from io import BytesIO, IOBase
from math import gcd, inf, sqrt, ceil

def lcm(a, b):
	return a * b // gcd(a, b)

def getFactorization(x):
	ret = list()
	while x != 1:
		ret.append(spf[x])
		x = x // spf[x]
	return ret

def printDivisors(n):
	i = 2
	z = [1, n]
	while i <= sqrt(n):
		if n % i == 0:
			if n / i == i:
				z.append(i)
			else:
				z.append(i)
				z.append(n // i)
		i = i + 1
	return z

def cheaker(a):
	j = 1
	p = False
	for i in a:
		if i != j:
			break
		j += 1
	q = len(a)
	for i in a[::-1]:
		if i != q:
			break
		q -= 1
	for i in range(j - 1, q):
		if a[i] == i + 1:
			return False
	return True

def create(n, x, f):
	pq = len(bin(n)[2:])
	if f == 0:
		tt = min
	else:
		tt = max
	dp = [[inf] * n for _ in range(pq)]
	dp[0] = x
	for i in range(1, pq):
		for j in range(n - (1 << i) + 1):
			dp[i][j] = tt(dp[i - 1][j], dp[i - 1][j + (1 << i - 1)])
	return dp

def enquiry(l, r, dp, f):
	if l > r:
		return inf if not f else -inf
	if f == 1:
		tt = max
	else:
		tt = min
	pq1 = len(bin(r - l + 1)[2:]) - 1
	return tt(dp[pq1][l], dp[pq1][r - (1 << pq1) + 1])

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	x = []
	for i in range(2, n + 1):
		if prime[i]:
			x.append(i)
	return x

def main():
	(n, k) = map(int, input().split())
	a = [int(x) for x in input().split()]
	z = {}
	an = 0
	for i in a:
		j = 2
		tt = []
		xx = []
		while j <= sqrt(i):
			c = 0
			while i % j == 0:
				i = i // j
				c += 1
			c = c % k
			if c:
				tt.append((j, c))
				xx.append((j, k - c))
			j += 1
		if i > 1:
			tt.append((i, 1))
			xx.append((i, k - 1))
		tt = tuple(tt)
		xx = tuple(xx)
		if tt not in z:
			z[tt] = 1
		else:
			z[tt] += 1
		if xx in z:
			an += z[xx]
		if tt == xx:
			an -= 1
	print(an)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()