Problem:
Score : 1100 points

Problem Statement

Snuke got positive integers s_1,...,s_N from his mother, as a birthday present. There may be duplicate elements.

He will circle some of these N integers. Since he dislikes cubic numbers, he wants to ensure that if both s_i and s_j (i ≠ j) are circled, the product s_is_j is not cubic. For example, when s_1=1,s_2=1,s_3=2,s_4=4, it is not possible to circle both s_1 and s_2 at the same time. It is not possible to circle both s_3 and s_4 at the same time, either.

Find the maximum number of integers that Snuke can circle.

Constraints

1 ≦ N ≦ 10^5

1 ≦ s_i ≦ 10^{10}

All input values are integers.

Input

The input is given from Standard Input in the following format:

N
s_1
:
s_N

Output

Print the maximum number of integers that Snuke can circle.

Sample Input 1

8
1
2
3
4
5
6
7
8

Sample Output 1

6

Snuke can circle 1,2,3,5,6,7.

Sample Input 2

6
2
4
8
16
32
64

Sample Output 2

3

Sample Input 3

10
1
10
100
1000000007
10000000000
1000000009
999999999
999
999
999

Sample Output 3

9

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<functional>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
#define MOD 1000000007
#define f(i,n) for(int i=0;i<int(n);i++)
#define N (50000)
bool u[100000];
vector<int>p;

void pri(void){
	int xx;
	f(i, 100000)u[i] = true;
	u[0] = false;
	u[1] = false;
	f(i, 100000){
		if (u[i]){
			if(i<3000)p.push_back(i);
			xx = i*2;
			while (xx < 100000){
				u[xx] = false;
				xx += i;
			}
		}
	}
	return;
}

long long niro(long long x){
	long long l = 0;
	long long r = 1000000000;
	long long m;
	if (l + 1 < r){
		m = (l + r) / 2;
		if ((m*m) <= x)l = m;
		else r = m;
	}
	return l;
}

long long red1(long long x){
	long long xx;
	f(i, p.size()){
		xx = p[i] * p[i] * p[i];
		while (x%xx == 0)x = x / xx;
	}
	return x;
}
long long red2(long long x){
long long xx, yy;
long long re = 1;

	f(i, p.size()){
		if (x%p[i] == 0){
			xx = p[i] * p[i];
			if (x%xx == 0){
				yy = 1000000000000 / p[i];
				if (re > yy)return -1;
				re *= p[i];
				x = x / xx;
			}
			else{
				yy = 1000000000000 / xx;
				if (re > yy)return -1;
				re *= xx;
				x = x / p[i];
			}
		}
	}
	if (x > 1){
		if (x < 100000){
			if (u[x]){
				yy = 1000000000000 / (x*x);
				if (re > yy)return -1;
				re *= (x*x);
				x = 1;
			}
		}
	}
	if (x > 1){
		xx = niro(x);
		if ((xx*xx) == x){
			yy = 1000000000000 / (xx);
			if (re > yy)return -1;
			re *= xx;
			x = 1;
		}
	}
	if (x > 1)return -1;
	if (re > 10000000000)return -1;
	return re;
}

int main(void){
	int n;
	vector<long long>v;
	set<long long>s;
	map<long long, long long>m1;
	map<long long, long long>m2;
	long long ans, k, x, y, z;
  ans=0;
	pri();
	scanf("%d", &n);
	f(i, n){
		scanf("%lld", &k);
		x = red1(k);
		y = red2(x);
		if (y < 0){
			if (s.count(x) == 0){
				v.push_back(x);
				m2[x] = y;
				s.insert(x);
				m1[x] = 1;
			}
			else{
				z = m1[x];
				m1[x] = z + 1;
			}
		}
		else{
			if (s.count(x) == 0){
				if (s.count(y) == 0)v.push_back(x);
				m2[x] = y;
				s.insert(x);
				m1[x] = 1;
			}
			else{
				z = m1[x];
				m1[x] = z + 1;
			}
		}
	}
	f(i, v.size()){
		if (v[i] == 1){
			if (m1[1] > 0)ans++;
		}
		else{
			if (m2[v[i]] > 0){
				ans += max(m1[v[i]], m1[m2[v[i]]]);
			}
			else ans += m1[v[i]];
		}
	}
	printf("%lld\n", ans);
	
	return 0;
}