#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;
}


Measured memory_bytes: 18872