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: Runtime Error)

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
#include <iostream>
#define MAXI 10000000000LL
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
int n;
ll s[300001];
bool prime[300005];
ll norm[300005];
ll pai[300005];
vector<ll> p;
vector<ll> ni;
int ncnt[300005];
ll pnum[300005];

int main(void){
	for(int i=1;i<=100000;i++){
		prime[i]=true;
	}
	prime[0]=false;
	prime[1]=false;
	for(int i=2;i<=100000;i++){
		if(prime[i]){
			p.push_back(i);
			for(int j=2*i;j<=100000;j+=i){
				prime[j]=false;
			}
		}
	}
	scanf("%d",&n);
	int res=0;
	bool norm1=false;
	for(int i=0;i<n;i++){
		scanf("%lld",&s[i]);
		norm[i]=s[i];
		for(int j=0;j<p.size();j++){
			if(p[j]*p[j]*p[j]>=10000000000LL)continue;
			while(norm[i]%(p[j]*p[j]*p[j])==0){
				norm[i]=norm[i]/(p[j]*p[j]*p[j]);
			}
		}
		if(norm[i]==1){
			norm1=true;
			continue;
		}
		ll v=1;
		bool flow=false;
		for(int j=0;j<p.size();j++){
			int cnts=0;
			if(p[j]*p[j]*p[j]>=10000000000LL)continue;
			while((ll)s[i]%(p[j])==0){
				s[i]=(ll)s[i]/(p[j]);
				cnts++;
			}
			cnts%=3;
			if(cnts==2)cnts=1;
			else if(cnts==1)cnts=2;
			for(int k=0;k<cnts;k++){
				if(v>10000000000LL)continue;
				v*=p[j];
			}
		}
		if(v>10000000000LL){
			res++;
			continue;
		}
		ll l=0,r=s[i]+1;
		while(l+1<r){
			ll mid=(l+r)/2LL;
			if(mid<=100000000LL && mid*mid<=s[i])l=mid;
			else r=mid;
		}
		if(l*l==s[i]){
			v=l*v;
		}else{
			for(int i=0;i<2;i++){
				if(v>10000000000LL)continue;
				v*=l;
			}
		}
		if(v>10000000000LL){
			res++;
			continue;
		}
		pai[i]=v;
		ni.push_back(pai[i]);
		ni.push_back(norm[i]);
		//printf("%lld %lld %lld\n",s[i],norm[i],pai[i]);
	}
	sort(ni.begin(),ni.end());
	ni.erase(unique(ni.begin(),ni.end()),ni.end());
	//printf("%d\n",res);
	for(int i=0;i<n;i++){
		ll v2=lower_bound(ni.begin(),ni.end(),norm[i])-ni.begin();
		if(ni[v2]==norm[i]){
			ncnt[v2]++;
			pnum[v2]=pai[i];
		}
	}
	for(int i=0;i<ni.size();i++){
		if(pnum[i]<=0)continue;
		int v=lower_bound(ni.begin(),ni.end(),pnum[i])-ni.begin();
		if(ncnt[i]>ncnt[v])res+=ncnt[i];
		if(ncnt[i]==ncnt[v] && i>v)res+=ncnt[i];
		//printf("%d %lld %d\n",i,ni[i],res);
	}
	if(norm1)res++;
	printf("%d\n",res);
	return 0;
}