#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void ckmax(T& x, T y) {
  x = (y > x ? y : x);
}
template <typename T>
inline void ckmin(T& x, T y) {
  x = (y < x ? y : x);
}
const int MAXN = 1e6;
const int INF = 1e9;
int n, ans[MAXN + 5], rest[MAXN + 5];
char s[MAXN + 5];
struct SegmentTree {
  int mx[MAXN * 4 + 5], mxpos[MAXN * 4 + 5], tag[MAXN * 4 + 5];
  int tl[MAXN * 4 + 5], tr[MAXN * 4 + 5];
  void push_up(int p) {
    if (mx[p << 1] > mx[p << 1 | 1]) {
      mx[p] = mx[p << 1];
      mxpos[p] = mxpos[p << 1];
    } else {
      mx[p] = mx[p << 1 | 1];
      mxpos[p] = mxpos[p << 1 | 1];
    }
  }
  void build(int p, int l, int r, const int arr[]) {
    tl[p] = l;
    tr[p] = r;
    tag[p] = -1;
    if (l == r) {
      mx[p] = arr[l] - l;
      mxpos[p] = l;
      return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid, arr);
    build(p << 1 | 1, mid + 1, r, arr);
    push_up(p);
  }
  void cover(int p, int v) {
    tag[p] = v;
    mx[p] = v - tl[p];
    mxpos[p] = tl[p];
  }
  void push_down(int p) {
    if (tag[p] != -1) {
      cover(p << 1, tag[p]);
      cover(p << 1 | 1, tag[p]);
      tag[p] = -1;
    }
  }
  void modify(int p, int ql, int qr, int v) {
    if (ql <= tl[p] && qr >= tr[p]) {
      cover(p, v);
      return;
    }
    push_down(p);
    int mid = (tl[p] + tr[p]) >> 1;
    if (ql <= mid) modify(p << 1, ql, qr, v);
    if (qr > mid) modify(p << 1 | 1, ql, qr, v);
    push_up(p);
  }
  SegmentTree() {}
};
SegmentTree T;
int main() {
  cin >> n;
  cin >> (s + 1);
  int i = 1;
  while (i <= n && s[i] == '?') ++i;
  for (int k = 1; k <= n; ++k) rest[k] = i - 1;
  if (i == n + 1) {
    for (int k = 1; k <= n; ++k) cout << n / k << " \n"[k == n];
    return 0;
  }
  T.build(1, 1, n, rest);
  for (; i <= n; ++i) {
    assert(s[i] != '?');
    int j = i;
    while (j + 1 <= n && (s[j + 1] == s[i] || s[j + 1] == '?')) ++j;
    int len = j - i + 1;
    int cr = 0;
    for (int k = j; k >= i; --k) {
      if (s[k] != '?') break;
      cr++;
    }
    vector<int> vec;
    while (1) {
      if (T.mx[1] < -len) break;
      int p = T.mxpos[1];
      int v = T.mx[1] + p;
      ans[p] += (v + len) / p;
      rest[p] = min(cr, (v + len) % p);
      vec.push_back(p);
      T.modify(1, p, p, -INF);
    }
    sort(vec.begin(), vec.end());
    int lst = 1;
    for (int k = 0; k < ((int)(vec).size()); ++k) {
      if (vec[k] > lst) {
        T.modify(1, lst, vec[k] - 1, cr);
      }
      T.modify(1, vec[k], vec[k], rest[vec[k]]);
      lst = vec[k] + 1;
    }
    if (lst <= n) {
      T.modify(1, lst, n, cr);
    }
    i = j;
  }
  for (int i = 1; i <= n; ++i) cout << ans[i] << " \n"[i == n];
  return 0;
}
