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)

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << #x << " = " << x << endl;


#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

const int MAX_P = 4010; //max
bool prime[MAX_P+1];

void Eratosthenes(void){
  for(int i=2;i<=MAX_P;i++)
    prime[i]=true;
  
  for(int i=2;i*i<=MAX_P;i++)
    if(prime[i])  
      for(int j=i;i*j<=MAX_P;j++)
        prime[i*j]=false;
}

int main(){
  int n;
  ll in;
  vector<ll> s;
  vector<ll> prime_v,prime_v3;
  map<ll,int> mm;
  map<ll,ll> sq;
  
  Eratosthenes();

  for(ll i=2;i<=100010;i++){
    sq[i*i] = i;
  }

  for(ll i=2;i<4010;i++){
    if(prime[i]) prime_v.push_back(i);
    if(prime[i]) prime_v3.push_back(i*i*i);
  }
  
  scanf("%d",&n);
  
  for(int i=0;i<n;i++){
    scanf("%lld",&in);
    s.push_back(in);
  }
  
  for(int i=0;i<n;i++){
    ll t = s[i];

    for(int j=0;j<prime_v3.size();j++){
      if(t < prime_v3[j]) break;
      
      while(t%prime_v3[j]==0){
        t /= prime_v3[j];
      }
    }

    s[i] = t;
  }

  for(int i=0;i<n;i++){
    mm[s[i]]++;
  }

  sort(s.begin(),s.end());
  s.erase(unique(s.begin(),s.end()),s.end());

  n = s.size();

  int ans = 0;
  
  for(int i=0;i<n;i++){
    int f[1000] = {};

    ll t = s[i];
    
    for(int j=0;j<prime_v.size();j++){
      if(t%(prime_v[j]*prime_v[j])==0){
        t/=(prime_v[j]*prime_v[j]);
        f[j] = 2;
      }else if(t%prime_v[j]==0){
        t /= prime_v[j];
        f[j] = 1;
      }else{
        f[j] = 0;
      }
    }

    ll q = 1;

    auto it = sq.find(t);
    
    if(it != sq.end()){
      q = it->second; 
    }else if(t > 1){
      if(t > 100000){
        ans += mm[s[i]];
        continue;
      }
      
      q = t*t;
    }
    
    for(int j=0;j<prime_v.size();j++){
      if(f[j]==1)
        q *= (ll) prime_v[j] * prime_v[j];
      else if(f[j]==2)
        q *= prime_v[j];
    }
    
    if(mm[q]==0){
      ans += mm[s[i]];
    }else if(s[i] > q){
      ans += max(mm[s[i]],mm[q]);
    }
    
  }

  if(mm[1] > 0) ans ++;
  
  printf("%d\n",ans);
  
  return 0;
}