// Original C++ solution (slower):
#define _USE_MATH_DEFINES

#include <vector>

#include <string>

#include <iostream>

#include <fstream>

#include <sstream>

#include <list>

#include <algorithm>

#include <sstream>

#include <set>

#include <math.h>

#include <cmath>

#include <map>

#include <stack>

#include <queue>

#include <stdio.h>

#include <string.h>

#include <numeric>

 

using namespace std;

 

typedef unsigned long long ll;

 

int N,NP;

 

ll S[100000];

ll prime[100000];

bool is_prime[100001];

 

map <ll, ll> mp;

map <ll,ll>::iterator it;

set <ll> st;

 

int sieve(int n){

  int p=0;

  for(int i=0; i<=n; i++) is_prime[i]=true;

  is_prime[0]=is_prime[1]=false;

  for(int i=2; i<=n; i++){

    if(is_prime[i]){

      prime[p++]=i;

      for(int j=2*i; j<=n; j+=i) is_prime[j]=false;

    }

  }

  return p;

}

 

ll dv(ll x){

 

  for(int i=0; i<NP; i++){

 

    ll q=prime[i]; if(q>1000) break;

    ll t=q*q*q;

    if(t>x) break;

    while(x%t==0) x/=t;

 

  }

 

  return x;

 

}

 

ll tp(ll x){

 

  ll y=x*x; //cout<<y<<endl;

 

  for(int i=0; i<NP; i++){

 

    ll q=prime[i]; if(q>1000) break;

    ll t=q*q*q;

 

    if(t>y) break;

 

    while(y%t==0) y/=t;

 

  }

 

  return y;

 

}

 

int main(){

 

 scanf("%d",&N);

 

 NP=sieve(100000);

 

 for(int i=0; i<N; i++){

 

  scanf("%lld",&S[i]);

  ll x=dv(S[i]);

  mp[x]++;

  

 }

 

 int ans=0;

  

 for(it=mp.begin();it!=mp.end();it++){

 

  ll x=it->first; //cout<<x<<endl;

  ll y=tp(x);

 

  if(st.count(x)) continue;

 

  if(x!=1) ans+=max(mp[x],mp[y]);

  else ans++;

 

  st.insert(y);

 

 }

  

  cout<<ans<<endl;

 

 return 0;

 

}

// Optimized solution to the same problem (faster):
#define _USE_MATH_DEFINES

#include <vector>

#include <string>

#include <iostream>

#include <fstream>

#include <sstream>

#include <list>

#include <algorithm>

#include <sstream>

#include <set>

#include <math.h>

#include <cmath>

#include <map>

#include <stack>

#include <queue>

#include <stdio.h>

#include <string.h>

#include <numeric>

#define INF 100000000000000LL

 

using namespace std;

 

typedef long long ll;

 

int N;

 

map <ll, int> mp;

map <ll,int>::iterator it;

set <ll> st;

 

ll dv(ll x){

 

  for(ll i=2;; i++){

 

    ll t=i*i*i;

    if(t>x) break;

    while(x%t==0) x/=t;

 

  }

 

  return x;

 

}

 

ll tp(ll x){

	ll A=1,B=1;

	for(ll i=2;;i++){

		if(i*i*i>x) break;

		int cnt=0;

		while(x%i==0)

		{

			x/=i;

			cnt++;

		}

		if(cnt==1) A*=i;

		else if(cnt==2) B*=i;

	}

	

      ll dt=(ll) floor(sqrt(x)+0.5);

	if(dt*dt==x) B*=dt;

	else A*=x;

	ll ret=A*B;

	if(ret>INF/A+1) ret=INF;

	else ret*=A;

	return ret;



}

 

int main(){

 

 scanf("%d",&N);

 

 for(int i=0; i<N; i++){

 

  ll x;

  scanf("%lld",&x);

  x=dv(x);

  mp[x]++;

  //cout<<x<<endl;

 }

 

 int ans=0; //cout<<tp(1027243729)<<endl;

  

 for(it=mp.begin();it!=mp.end();it++){

 

  ll x=it->first; //cout<<x<<endl;

  int cn=it->second;

  ll y=tp(x);

 

  if(st.count(x)) continue;

 

  if(x!=1) ans+=max(cn,mp[y]);

  else ans++;

 

  st.insert(y);

 

 }

  

  cout<<ans<<endl;

 

 return 0;

 

}

// Fastest known solution for this problem: