// {{{ by WangYenJen
#include <bits/stdc++.h>
using namespace std;
// types
typedef long long ll;
typedef pair<int,int> pii;
// macro
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin() , (x).end()
#define REP(i , n) for(int i = 0; i < int(n); i++)
#define REP1(i , a , b) for(int i = a; i <= int(b); i++)
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define LC o<<1 , l , m
#define RC o<<1|1 , m + 1 , r
#define MS(x , v) memset(x , (v) , sizeof(x))
// input
inline bool SR(int &x) {
	return scanf("%d",&x) == 1;
}
inline bool SR(ll &x) {
	return scanf("%lld",&x) == 1;
}
inline bool SR(double &x) {
	return scanf("%lf",&x) == 1;
}
inline bool SR(char *s) {
	return scanf("%s",s) == 1;
}
inline bool RI() {
	return true;
}
template<typename I , typename... T> inline bool RI(I &x , T&... tail) {
	return SR(x) && RI(tail...);
}
// output
inline void SP(const int x) {
	printf("%d",x);
}
inline void SP(const ll x) {
	printf("%lld",x);
}
inline void SP(const double x) {
	printf("%.16lf",x);
}
inline void SP(const char *s) {
	printf("%s",s);
}
inline void PL() {
	puts("");
}
template<typename I , typename... T> inline void PL(const I x , const T... tail) {
	SP(x);
	if(sizeof...(tail)) putchar(' ');
	PL(tail...);
}
// debug
#define WangYenJen
#ifdef WangYenJen
template<typename I> void _DOING(const char *s , I&& x) {
    cerr << s << " = " << x << endl;
}
template<typename I , typename... T> void _DOING(const char *s , I&& x , T&&... tail) {
    int c = 0;
    while(*s != ',' || c != 0) {
        if(*s == '(' || *s == '[' || *s == '{') c++;
        if(*s == ')' || *s == ']' || *s == '}') c--;
        cerr << *s++;
    }
    cerr << " = " << x << " , ";
    _DOING(s + 1 , tail...);
}
#define debug(...) \
do {\
    fprintf(stderr , "%s:%d - ",__PRETTY_FUNCTION__,__LINE__);\
    _DOING(#__VA_ARGS__ , __VA_ARGS__);\
} while(0);
#else
#define debug(...)
#endif
// random function
inline int RAND() {
	static int x = 880301;
	return (x = x * 0xdefaced + 1) & 0x7fffffff;
}
// }}}

const int MAX_N = 100000 + 10;
const ll INF = 1000000000000LL;
bool is_prime[MAX_N];
vector<int> prime;
inline ll norm(ll x) {
    for(int p : prime) {
        ll t = ll(p) * ll(p) * ll(p);
        if(t > x) break;
        while(x % t == 0) x /= t;
    }
    return x;
}
inline ll mul(ll a , ll b) {
    if(INF / b < a) return INF;
    else return a * b;
}
inline ll conj(ll x) {
    ll res = 1;
    for(int p : prime) {
        if(ll(p) * ll(p) > x) break;
        if(x % p == 0) {
            if((x / p) % p == 0) res = mul(res , p) , x /= p , x /= p;
            else res = mul(res , mul(p , p)) , x /= p;
        }
    }
    if(x != 1) res = mul(res , mul(x , x));
    return res;
}
int main() {
    unordered_map<ll,int> cnt;
    REP1(i , 2 , MAX_N - 1) is_prime[i] = 1;
    REP1(i , 2 , MAX_N - 1) {
        if(!is_prime[i]) continue;
        prime.PB(i);
        for(int j = i + i; j < MAX_N; j += i) is_prime[j] = 0;
    }
    int n;
    RI(n);
    REP(i , n) {
        ll s;
        RI(s);
        s = norm(s);
        cnt[s]++;
    }
    int ans = 0;
    unordered_set<ll> used;
    for(auto p : cnt) {
        ll x = p.F;
        int c = p.S;
        if(used.count(x)) continue;
        ll y = conj(x);
        if(x == y) ans++;
        else {
            if(cnt.count(y)) {
                ans += max(c , cnt[y]);
                used.insert(x);
                used.insert(y);
            }
            else {
                ans += c;
                used.insert(x);
            }
        }
    }
    PL(ans);
    return 0;
}


Measured memory_bytes: 8612