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++ (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define Max(_A,_B) (_A>_B?_A:_B)
#define Min(_A,_B) (_A<_B?_A:_B)
#define maxn 100007
#define maxm 1000001
#define V e[i].v
#define ull unsigned long long
int n, m, k, tot;
inline int read(){
    int s = 0, f = 1; char c = getchar();
    while (c > '9' || c < '0') {if(c=='-') f= -1; c = getchar();}
    while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}
    return s * f;
}

/*
一个数是完全立方数的条件是 每个质因子的次数%3==0
先把输入里的完全立方数去掉并筛掉完全立方因子 得到s[i] 即原数l[i]
然后分解s[i]的 <= s[i]^{3}的质因数 算一下次数 计算s[i]的补数r[i]
*/
map<ll, int> cnt;
ll s[maxn], ans;
ll l[maxn], r[maxn];
int main() {
    n = read();
    for (int i = 1; i <= n; i++) {
        s[i] = read();
        for (ll j = 2; j * j * j <= s[i] ; j++){
            while (s[i] % (j * j * j) == 0) {
                s[i] /= (j * j * j);//相当于把所有质因子的次数%3
            }
        } 
        cnt[s[i]]++;
        l[i] = s[i];
        ll tmp = 1;
        for (ll j = 2; j * j * j <= s[i]; j++) {//计算补数tmp
            if (s[i] % j == 0) {
                if (s[i] % (j * j) == 0) tmp *= j;
                else tmp *= (j * j);
                //printf("s[i] == %lld tmp == %lld\n", s[i], tmp);
            }
            while (s[i] % j == 0) s[i] /= j;
        }
        // 剩下一个可能是一个较大的质因数或是一个较大质因数的平方 讨论一哈
        ll t = (ll)sqrt(s[i]);
        if (t * t == s[i]) {
            tmp *= t; //    s[i]被筛剩下一个质因数的平方 
        } else {
            tmp *= s[i] * s[i]; //s[i]是剩下的一个大质数
        }
        //这样筛完以后
        //补数即为tmp
        r[i] = tmp; 
    }
    if (cnt[1]) ans++, cnt[1] = 0;
    for (int i = 1; i <= n; i++) {
        ans += Max(cnt[l[i]], cnt[r[i]]);
        //printf("cnt[l[%d]==%lld] == %lld cnt[r[%d]==%lld] == %lld\n", i, l[i], cnt[l[i]], i, r[i], cnt[r[i]]);
        cnt[l[i]] = cnt[r[i]] = 0;
    }
    //ans += (cnt[1] > 0);
    printf("%lld\n", ans);
    return 0;
}