// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<cmath>

#include<map>

#include<algorithm>

using namespace std;

const long long MAXN=100005,MAXP=21000;



long long prime[MAXP],pcnt;

bool npr[MAXP];



void LinerSieve()

{

	npr[1]=true;

	for(long long i=2;i<MAXP;i++)

	{

		if(!npr[i])

			prime[++pcnt]=i;

		for(long long j=1;j<=pcnt&&prime[j]*i<MAXP;j++)

		{

			npr[prime[j]*i]=true;

			if(i%prime[j]==0)

				break;

		}

	}

}

long long ans;

map<long long,long long> cnt;

long long n,A[MAXN];

long long F(long long x)

{

	long long res=1;

	for(long long j=1;j<=pcnt&&prime[j]*prime[j]*prime[j]<=x;j++)

		if(x%prime[j]==0)

		{

			long long cnt=0;

			while(x%prime[j]==0)

				x/=prime[j],cnt++;

			cnt%=3;

			for(long long k=1;k<=cnt;k++)

				res*=prime[j];

		}

	if(x!=1)

		res*=x;

	return res;

}



int main()

{



	LinerSieve();

    scanf("%lld",&n);

    for(long long i=1;i<=n;i++)

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

	for(long long i=1;i<=n;i++)

	{

		A[i]=F(A[i]);

		cnt[A[i]]++;

		//printf("(%lld)\n",A[i]);

	}

	

	bool flag=false;

	for(long long i=1;i<=n;i++)

	{

		if(A[i]==1)

			flag=true;

		else if(cnt[A[i]])

		{

			long long tmp=floor(sqrt(A[i])+0.5);

			long long y;

			if(tmp*tmp==A[i])

				y=tmp;

			else

				y=A[i]*A[i];

			y=F(y);

			//printf("[%lld][%lld]\n",A[i],y);

			if(cnt.count(y))

			{

				//puts("1");

				ans+=max(cnt[y],cnt[A[i]]);

				cnt[y]=cnt[A[i]]=0;

			}

			else

			{

				ans+=cnt[A[i]];

				cnt[A[i]]=0;

			}

		}

	}

	if(flag)

		ans++;

	printf("%d\n",ans);



    fclose(stdin);

    fclose(stdout);

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.1543038461889108x):
#include <bits/stdc++.h>

using namespace std;



#define visit fuckitwholefamily

#define ll long long

#define MAXN 100005

#define Int int



int n,ans;ll s[MAXN];

map <ll,int> tot;

map <ll,bool> vis;



template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}

template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}

template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}



int cnt,prime[3405],visit[3405];



void Euler (int up){

	for (Int i = 2;i <= up;++ i){

		if (!visit[i]) prime[++ cnt] = i;

		for (Int j = 1;j <= cnt && i * prime[j] <= up;++ j){

			visit[i * prime[j]] = 1;

			if (i % prime[j] == 0) break; 

		}

	}

}



signed main(){

	read (n);Euler (3400);

	for (Int i = 1;i <= n;++ i){

		read (s[i]);

		for (ll p = 2;p * p * p <= s[i];++ p) while (s[i] % (p * p * p) == 0) s[i] /= p * p * p; 

		if (s[i] != 1) tot[s[i]] ++;

		else ans = 1;

	}

	for (Int i = 1;i <= n;++ i) 

		if (vis[s[i]] || s[i] == 1) continue;

		else{

			ll now = s[i],nowto = 1;

			for (Int j = 1;1ll * prime[j] * prime[j] * prime[j] <= now;++ j){

				if (now % prime[j] == 0){

					nowto *= (now % (prime[j] * prime[j]) == 0 ? prime[j] : prime[j] * prime[j]);

					while (now % prime[j] == 0) now /= prime[j];

				}

			}

			ll w = sqrt (now);

			if (w * w == now) nowto *= w;

			else nowto *= now * now;

			vis[s[i]] = vis[nowto] = 1,ans += max (tot[s[i]],tot[nowto]);

		}

	write (ans),putchar ('\n');

	return 0;

}