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: Accepted)

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=1e5+10;
const int N=4000;
struct node{
	ll x,y;
};
node a[MAXN];
ll prime[MAXN],s[MAXN],s1[MAXN];
bool p[MAXN];
int n,len;
map<ll,int>mp;
void init()
{
	for (int i=2;i<=N;i++) {
		if (!p[i]) {
			p[i]=1; prime[++len]=i;
		}
		for (int j=1;j<=len&&prime[j]*i<=N;j++) {
			p[prime[j]*i]=1;
			if (i%prime[j]==0) break;
		}
	}
}
ll sqr(ll x){
	return x*x;
}
void pan(ll x,int now){
	ll ans1=1;
	ll ans2=1;
	for (register int i=1;i<=len&&prime[i]*prime[i]<=x;i++) 
	if (x%prime[i]==0)
	{
        int sum=0;
        while (x%prime[i]==0) {
        	x/=prime[i]; sum++;
        }
        sum=(sum%3);
        for (int j=1;j<=sum;j++) ans1*=(ll)prime[i];
        for (int j=1;j<=(3-sum)%3;j++) ans2*=(ll)prime[i];
	}
    if (x>1) {
    	ans1*=x;
    	if (sqr(floor(sqrt(x)))==x) {
    		ans2*=floor(sqrt(x));
    	} 
    	else if (sqr(ceil(sqrt(x)))==x) {
    		ans2*=ceil(sqrt(x));
    	}
    	else {
    		if (x>MAXN) ans2=0; else ans2*=(x*x);
     	}
    }
    a[now].x=ans1; a[now].y=ans2;
}
bool cmp(node x,node y)
{
	return x.x<y.x;
}
int main()
{
	scanf("%d",&n);
	init();
	for (int i=1;i<=n;i++) {
		scanf("%lld",&s[i]);
		pan(s[i],i);
		mp[a[i].x]++;
	}
	sort(a+1,a+n+1,cmp);
	int ans=0;
	for (int i=1;i<=n;i++) 
		if (a[i].x!=1) 
			if (a[i].x!=a[i-1].x) {
				ans+=max(mp[a[i].x],mp[a[i].y]);
				mp[a[i].x]=0; mp[a[i].y]=0;
			}
	if (a[1].x==1) ans++;	
	cout << ans << endl;
}