#include <bits/stdc++.h>

using namespace std;
using int64 = long long;
using int128 = __int128;

constexpr int DEBUG = 0;

int64 PowerMod(int64 base, int64 power, int64 mod) {
  base %= mod;
  int64 result = 1;
  while (power > 0) {
    if (power % 2 == 1) {
      result = (static_cast<int128>(result) * base) % mod;
    }
    base = (static_cast<int128>(base) * base) % mod;
    power /= 2;
  }
  return result;
}

bool IsPrimeMillarRabin(int64 x) {
  if (x == 1) return false;
  if (x == 2) return true;
  if (x % 2 == 0) return false;
  int s = 0;
  int64 d = x - 1;
  while (d % 2 == 0) {
    s++;
    d /= 2;
  }
  for (int a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) {
    if (a >= x) continue;
    int64 y = PowerMod(a, d, x);
    if (y == 1 || y == x - 1) continue;
    for (int i = 0; i < s - 1; i++) {
      y = (static_cast<int128>(y) * y) % x;
      if (y == x - 1) break;
    }
    if (y == x - 1) continue;
    return false;
  }
  return true;
}

vector<int64> FactorizePollardRho(int64 n) {
  vector<int64> ps;
  for (int prime : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) {
    while (n % prime == 0) {
      n /= prime;
      ps.push_back(prime);
    }
  }
  function<void(int64, vector<int64>&)> extract_fn =
      [&extract_fn](int64 n, vector<int64>&ps) {
    if (n == 1) return;
    if (IsPrimeMillarRabin(n)) {
      ps.push_back(n);
      return;
    }
    for (int c = 1; c <= 100; c++) {
      int64 x = 2;
      int64 y = 2;
      int64 d = 1;
      while (d == 1) {
        x = (static_cast<int128>(x) * x + c) % n;
        y = (static_cast<int128>(y) * y + c) % n;
        y = (static_cast<int128>(y) * y + c) % n;
        d = __gcd(abs(x - y), n);
      }
      if (d == n) {
        continue;
      }
      extract_fn(d, ps);
      extract_fn(n / d, ps);
      return;
    }
    cerr << "FactorizePollardRho() failed!" << endl;
    exit(1);
  };
  extract_fn(n, ps);
  sort(ps.begin(), ps.end());

  return ps;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;
  vector<int64> xs(n);
  for (int i = 0; i < n; i++) {
    cin >> xs[i];
  }

  bool has_cube = false;

  map<int128, int128> conjugate_map;
  map<int128, int> group_map;

  for (int64 x : xs) {
    auto ps = FactorizePollardRho(x);
    map<int64, int> factor_map;
    for (int64 p : ps) {
      factor_map[p]++;
    }

    map<int64, int> new_factor_map;
    for (const auto& [p, c] : factor_map) {
      if (c % 3 != 0) {
        new_factor_map[p] = c % 3;
      }
    }

    if (new_factor_map.empty()) {
      has_cube = true;
      continue;
    }

    int128 a = 1;
    int128 b = 1;
    for (const auto& [p, c] : new_factor_map) {
      int128 p128 = static_cast<int128>(p);
      if (c == 1) {
        a *= p128;
        b *= p128 * p128;
      } else {
        a *= p128 * p128;
        b *= p128;
      }
    }

    // cout << "a: " << static_cast<int64>(a) << endl;
    conjugate_map[a] = b;
    group_map[a]++;
  }

  int sum = 0;
  set<int128> visited;
  for (const auto& [a, c] : group_map) {
    if (visited.find(a) != visited.end()) continue;
    int128 b = conjugate_map[a];
    // cout << "a: " << static_cast<int64>(a) << " b: " << static_cast<int64>(b) << endl;
    // cout << max(group_map[a], group_map[b]) << endl;
    sum += max(group_map[a], group_map[b]);
    visited.insert(a);
    visited.insert(b);
  }
  if (has_cube) {
    sum++;
  }
  cout << sum << endl;
}

Measured memory_bytes: 39908