#include <bits/stdc++.h>
using namespace std;
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << "\n";
  err(++it, args...);
}
int isprime[10003];
vector<int> prime;
void sieve() {
  int i, a;
  fill(isprime + 2, isprime + 10003, 1);
  for (i = 2; i * i < 10003; i++) {
    if (isprime[i])
      for (a = i * i; a < 10003; a += i) isprime[a] = 0;
  }
  for (i = 0; i < 10003; i++)
    if (isprime[i]) prime.emplace_back(i);
  return;
}
vector<int> compress(vector<int> &temp, int n) {
  vector<pair<int, int> > tp(n);
  int i, j, k;
  for (i = 0; i < n; i++) tp[i].first = temp[i], tp[i].second = i;
  sort(tp.begin(), tp.end());
  vector<int> v(n);
  i = 0, k = 1, j = 0;
  while (i < n) {
    while (j < n && tp[i].first == tp[j].first) v[tp[j].second] = k, j++;
    i = j, k++;
  }
  return v;
}
int dp[10003];
int main() {
  int n, m, i, a, x, f, g, j;
  sieve();
  m = prime.size();
  scanf("%d", &n);
  vector<int> v(n, 0);
  for (i = 0; i < n; i++) {
    scanf("%d", &a);
    if (a == 0) continue;
    for (j = 0; j < m; j++) {
      x = (prime[j] * prime[j]);
      while (a % x == 0) a /= x;
    }
    v[i] = a;
  }
  int zero = -1;
  for (i = 0; i < n; i++)
    if (v[i] == 0) zero = i;
  v = compress(v, n);
  if (zero >= 0) zero = v[zero];
  {
    string _s = "zero";
    replace(_s.begin(), _s.end(), ',', ' ');
    stringstream _ss(_s);
    istream_iterator<string> _it(_ss);
    err(_it, zero);
  };
  vector<int> ans(n + 1, 0);
  for (i = 0; i < n; i++) {
    fill(dp, dp + 10003, 0);
    f = 0, g = 0;
    for (j = i; j < n; j++) {
      a = v[j];
      dp[a]++;
      if (dp[a] == 1) g++;
      if (a == zero) f = 1;
      x = g - f;
      if (x == 0) x = 1;
      ans[x]++;
    }
  }
  for (i = 1; i < n + 1; i++) printf("%d ", ans[i]);
}
