#include
using namespace std;
const int maxn = 3009;
int n, a[maxn], sa[maxn], rk[maxn], hi[maxn], ho[maxn]; char g[maxn];
inline bool equStr(int a, int b, int l) { if (rk[a] > rk[b]) return 0; else if (a + l >= n && b + l >= n) return 1; else if (a + l >= n || b + l >= n) return 0; else return rk[a + l] == rk[b + l]; }
void suffixArray() { static int w[maxn], nr[maxn], b[maxn]; memset(w, 0, sizeof(w)); for (int i = 0; i < n; ++ i) ++ w[rk[i] = a[i]]; w[1] += w[0]; for (int i = 0; i < n; ++ i) sa[– w[rk[i]]] = i; for (int l = 1; l < n; l «= 1) { for (int i = 0; i < l; ++ i) b[i] = n - i - 1; for (int i = 0, j = l; i < n; ++ i) if (sa[i] >= l) b[j ++] = sa[i] - l; memset(w, 0, sizeof(w)); for (int i = 0; i < n; ++ i) ++ w[rk[i]]; for (int i = 1; i < n; ++ i) w[i] += w[i - 1]; for (int i = n - 1; i >= 0; – i) sa[– w[rk[b[i]]]] = b[i]; nr[sa[0]] = 0; for (int i = 1; i < n; ++ i) if (equStr(sa[i], sa[i - 1], l)) nr[sa[i]] = nr[sa[i - 1]]; else nr[sa[i]] = nr[sa[i - 1]] + 1; memcpy(rk, nr, sizeof(rk)); } for (int i = 0; i < n; ++ i) ho[sa[i]] = i; for (int i = 0; i < n; ++ i) if (ho[i] < n - 1) { int p(ho[i]), j(sa[ho[i] + 1]); hi[p] = i ? max(hi[ho[i - 1]] - 1, 0) : 0; while (i + hi[p] < n && j + hi[p] < n && a[i + hi[p]] == a[j + hi[p]]) ++ hi[p]; } }
void cntAns() { for (int i = 0, pr = 0; i < n - 1; pr = hi[i ++]) { for (int j = pr + 1; j <= hi[i]; ++ j) { int k; for (k = i; k < n - 1 && hi[k] >= j; ++ k); printf("%d\n", k - i + 1); } } }
int main() { #ifndef ONLINE_JUDGE freopen(".in", “r”, stdin); #endif
scanf("%d%s", &n, g);
for (int i = 0; i < n; ++ i)
a[i] = g[i] - 48;
suffixArray();
cntAns();
}