#include <bits/stdc++.h>
static inline void setio(void);
int main(void) {
  setio();
  long long n;
  std::cin >> n;
  std::vector<long long> vec(n);
  std::vector<char> neg(n);
  for (long long i = 0; i < n; ++i) {
    std::cin >> vec[i];
    if (vec[i] < 0) {
      neg[i] = true;
      vec[i] = -vec[i];
    }
  }
  std::vector<long long> primes;
  std::vector<char> sieve(1000000, true);
  for (long long i = 2; i < sieve.size(); ++i) {
    if (!sieve[i]) continue;
    primes.push_back(i * i);
    if (primes.back() > 100000001LL) break;
    for (long long j = i + i; j < sieve.size(); j += i) sieve[j] = false;
  }
  for (auto& num : vec) {
    for (const auto& p : primes) {
      if (p > num) break;
      while (num % p == 0) num /= p;
    }
  }
  for (long long i = 0; i < n; ++i)
    if (neg[i]) vec[i] = -vec[i];
  std::vector<long long> cnts(n + 1, 0);
  std::vector<long long> last_time(n);
  std::map<long long, long long> bleh;
  for (long long i = 0; i < n; ++i) {
    last_time[i] = bleh[vec[i]] - 1;
    bleh[vec[i]] = i + 1;
  }
  bool seen_zero;
  for (long long i = 0; i < n; ++i) {
    long long count = 0;
    seen_zero = false;
    for (long long j = i; j < n; ++j) {
      count += last_time[j] < i;
      seen_zero = seen_zero || vec[j] == 0;
      if (count == 1 && seen_zero)
        cnts[count]++;
      else if (count > 0)
        cnts[count - (seen_zero)]++;
    }
  }
  for (long long i = 1; i <= n; ++i) std::cout << cnts[i] << " ";
  std::cout << "\n";
  return 0;
}
static inline void setio(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.precision(10);
  std::cout << std::fixed;
}
