// Original C++ solution (slower):
#include<cstdio>

#include<map>

#include<algorithm>

#include<cmath>

using namespace std;

#define MAXN 100000

#define LL long long

int tot,vis[MAXN],n,ans;

LL prim[MAXN],a[MAXN+5],b[MAXN+5];

map<LL,int>cnt;

void Pre()

{

	for(int i=2;i<MAXN;i++)

	{

		if(!vis[i]) prim[tot++]=i;

		for(int j=0;prim[j]*i<MAXN;j++)

		{

			vis[i*prim[j]]=1;

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

		}

	}

}

void Solve(int i,LL x)

{

	a[i]=b[i]=1;

	for(int j=0;prim[j]*prim[j]*prim[j]<=x;j++)

	{

		int c=0;

		while(x%prim[j]==0) x/=prim[j],c++;

		if(c%3==1) a[i]*=prim[j],b[i]*=prim[j]*prim[j];

		else if(c%3==2) a[i]*=prim[j]*prim[j],b[i]*=prim[j];

	}

	if(x!=1)

	{

		LL k=sqrt(x);

		if(k*k==x) a[i]*=k*k,b[i]*=k;

		else a[i]*=x,b[i]*=x*x;

	}

}

int main()

{

	Pre();

	scanf("%d",&n);

	LL x;

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

	{

		scanf("%lld",&x);

		Solve(i,x);

		cnt[a[i]]++;

	}

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

	{

		if(cnt[a[i]]==0) continue;

		if(a[i]==b[i]) 	ans++,cnt[a[i]]=0;

		else ans+=max(cnt[a[i]],cnt[b[i]]),cnt[a[i]]=0,cnt[b[i]]=0;

	}

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

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/trie_policy.hpp>

#include <ext/rope>



#pragma 03



using namespace std;

using namespace __gnu_pbds;

using namespace __gnu_cxx;



mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());



#define fi first

#define se second

#define pb push_back

#define eb emplace_back

#define mp make_pair

#define gcd __gcd

#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define rep(i, n) for (int i=0; i<(n); i++)

#define rep1(i, n) for (int i=1; i<=(n); i++)

#define all(x) (x).begin(), (x).end()

#define rall(x) (x).rbegin(), (x).rend()

#define endl "\n"



typedef long long ll;

typedef unsigned long long ull;

typedef unsigned uint;

typedef long double ld;

typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

typedef vector<int> vi;

typedef vector<vector<int>> vvi;

typedef vector<ll> vll;

typedef vector<vector<ll>> vvll;

typedef vector<bool> vb;

typedef vector<vector<bool>> vvb;

template<typename _def> using ordered_set=tree<_def, null_type, less<_def>, rb_tree_tag, tree_order_statistics_node_update>;

typedef trie<string, null_type, trie_string_access_traits<>, pat_trie_tag, trie_prefix_search_node_update> pref_trie;



struct custom_hashes {

    inline static uint64_t splitmix64(uint64_t x) {

        // http://xorshift.di.unimi.it/splitmix64.c

        x += 0x9e3779b97f4a7c15;

        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;

        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;

        return x ^ (x >> 31);

    }



    template<typename T> //should take care of all types that can turn into integers

    size_t operator()(T x) const {

        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();

        return splitmix64((uint64_t)x + FIXED_RANDOM);

    }

};



template<typename _F, typename _T> using safe_map=gp_hash_table<_F, _T, custom_hashes>;



constexpr int N=1e5+1;

bitset<N+1> isprime;

void init() {

    isprime.set();

    for(int i=2; i*i<=N; i++) if(isprime[i]) for(int j=i*i; j<=N; j+=i) isprime[j]=0;

}



int32_t main() {

    //freopen("gen.txt", "r",  stdin);

    fastio;

    safe_map<ll, int> cnt;

    safe_map<ll, ll> rev;

    init();

    int n; cin>>n;

    rep(i, n) {

        ll x; cin>>x;

        if(x==1) cnt[1]++, rev[1]=1;

        else {

            ll val=1, rval=1;

            for(int i=2; 1LL*i*i*i<=x; i++) {

                if(x%i==0) {

                    int cnt=0;

                    while(x%i==0) x/=i, cnt++;

                    cnt%=3;

                    rep(j, cnt) val*=i;

                    rep(j, (3-cnt)%3) if(rval!=-1) {

                        rval*=i;

                        if(rval>1e11) rval=-1;

                    }

                }

            }

            if(x>1) {

                if(sqrt(x)==trunc(sqrt(x))&&isprime[trunc(sqrt(x))]) rval*=trunc(sqrt(x));

                else {

                    if(rval>1e11/x/x) rval=-1;

                    else rval*=x*x;

                }

                val*=x;

            }

            cnt[val]++; rev[val]=rval;

        }

    }

    int ans1=0, ans2=0;

    for(auto& it: cnt) {

        //cout<<it.fi<<' '<<it.se<<' '<<rev[it.fi]<<endl;

        if(rev[it.fi]!=it.fi&&cnt.find(rev[it.fi])!=cnt.end()) ans1+=max(it.se, cnt[rev[it.fi]]);

        else if(rev[it.fi]==it.fi) ans2++;

        else ans2+=it.se;

    }

    cout<<ans1/2+ans2<<endl;

}


// Fastest known solution for this problem: