#include <bits/stdc++.h>
using namespace std;
pair<int, int> arr[5005];
vector<int> primes;
int ans[5005];
int u[5005];
int n;
void pre() {
  vector<char> bad(10005);
  for (int i = 2; i <= 10000; ++i) {
    if (!bad[i]) {
      primes.push_back(i);
      for (int j = i * i; j <= 10000; j += i) {
        bad[j] = 1;
      }
    }
  }
}
int f(int x) {
  static vector<int> di;
  di.clear();
  if (x == 0) {
    return 0;
  }
  bool neg = 0;
  if (x < 0) {
    neg = 1;
    x *= -1;
  }
  int y = 1;
  for (int i = 0; i < primes.size(); ++i) {
    int cnt = 0;
    while (x % primes[i] == 0) {
      x /= primes[i];
      ++cnt;
    }
    if (cnt & 1) {
      y *= primes[i];
    }
  }
  x *= y;
  if (neg) {
    x *= -1;
  }
  return x;
}
void compress() {
  vector<int> vv;
  for (int i = 1; i <= n; ++i) {
    vv.push_back(arr[i].first);
  }
  sort((vv).begin(), (vv).end());
  vv.resize(unique((vv).begin(), (vv).end()) - vv.begin());
  for (int i = 1; i <= n; ++i) {
    arr[i].second =
        upper_bound((vv).begin(), (vv).end(), arr[i].first) - vv.begin();
  }
}
void solve() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &arr[i].first);
    arr[i].first = f(arr[i].first);
  }
  compress();
  int ptr = 0;
  for (int l = 1; l <= n; ++l) {
    int cur = 0;
    ++ptr;
    for (int r = l; r <= n; ++r) {
      if (arr[r].first != 0) {
        if (u[arr[r].second] != ptr) {
          u[arr[r].second] = ptr;
          ++cur;
        }
      }
      ++ans[max(1, cur)];
    }
  }
  for (int i = 1; i <= n; ++i) {
    printf("%d ", ans[i]);
  }
}
int main() {
  int tt = 1;
  pre();
  while (tt--) {
    solve();
  }
  return 0;
}
