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 <bits/stdc++.h>
 
using ll = __int128;
 
const int max_N = 1e5 + 21;
 
int n,ans;
 
bool vis[max_N];
 
std::vector<int>pri;
 
ll Norm[max_N],Pair[max_N];

int N_tot,P_tot,N_siz[max_N],P_siz[max_N];

inline void jzp(int n){
	for(int x=2;x<=n;++x){
		if(!vis[x])pri.push_back(x);
		for(auto&y:pri){
			if((ll)x*y>n)break;
			vis[x*y]=1;
			if(!(x%y))break;
		}
	}
}
 
inline ll get_norm(ll x){
	for(auto&y:pri){
		ll z=1ll*y*y*y;
		if(z>x)break;
		while(!(x%z))x/=z;
	}
	return x;
}
 
inline ll get_pair(ll x){
	ll t=x,res=1;
	for(auto&y:pri){
		ll z=(ll)y*y*y;
		if(z<=t){
			while(!(x%z))x/=z;
			if(!(x%(y*y))){
				res*=y;
				x/=(y*y);	
			}
			else if(!(x%y)){
				res*=(y*y);
				x/=y;
			}
		}
		else{
			ll w=(ll)y*y;
			if(w>x){
				res*=((ll)x*x);
				break;
			}
			else if(!(x%y)){
				if(x==w)res*=y;
				else res*=((ll)x*x);
				break;
			}
		}
	}
	return res;
}
 
int main(){
	jzp(1e5);
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		long long s; scanf("%lld",&s);
		Norm[i]=get_norm(s);
		Pair[i]=get_pair(s);
	}
	std::sort(Norm+1,Norm+1+n);
	std::sort(Pair+1,Pair+1+n);
	for(int i=1;i<=n;++i){
		if(Norm[i]!=Norm[i-1])Norm[++N_tot]=Norm[i];
		++N_siz[N_tot];
		if(Pair[i]!=Pair[i-1])Pair[++P_tot]=Pair[i];
		++P_siz[P_tot];
	}
	int i=1,j=1;
	while(i<=N_tot||j<=P_tot){
		if(i<=N_tot&&j<=P_tot&&Norm[i]==Pair[j]){
			if(Norm[i]!=1)ans+=std::max(N_siz[i],P_siz[j]);
			++i,++j;
		}
		else if(i>N_tot||(j<=P_tot&&Norm[i]>Pair[j]))
			ans+=P_siz[j++];
		else
			ans+=N_siz[i++];
	}
	ans>>=1;
	if(Norm[1]==1)++ans;
	printf("%d\n",ans);
	return 0;
}