//http://hihocoder.com/problemset/problem/1449
//感觉这个板子比上一个科学一点
//求长度为k的串中出现最多的串的出现次数是多少
//endpos为某个状态包含的子串的所有结束位置
#include<bits/stdc++.h>

using namespace std;

const int N = 1e6;
const int M = 26;

struct state {
  int maxlen, minlen, slink;
  int trans[M];
};

state st[N * 2 + 10];
int degree[N * 2 + 10];
int endpos[N * 2 + 10];
bool prefix[N * 2 + 10];

char s[N + 10];
int size, last;

int new_state(int maxlen, int minlen, int slink, int *trans) {
  prefix[size] = false;
  degree[size] = 0;
  endpos[size] = 0;
  st[size].maxlen = maxlen;
  st[size].minlen = minlen;
  st[size].slink = slink;
  for (int i = 0; i < M; i++) {
    if (trans == NULL)
      st[size].trans[i] = -1;
    else
      st[size].trans[i] = trans[i];
  }
  return size++;
}

int add_char(char ch, int u) {
  int c = ch - 'a', v, x, y;
  int cur = new_state(st[u].maxlen + 1, -1, -1, NULL);
  prefix[cur] = true;
  endpos[cur] = 1;
  
  for (v = u; v != -1 && st[v].trans[c] == -1; v = st[v].slink) {
    st[v].trans[c] = cur;
  }
  if (v == -1) {
    st[cur].minlen = 1;
    st[cur].slink = 0;
    degree[0]++;
    return cur;
  }
  x = st[v].trans[c];
  if (st[v].maxlen + 1 == st[x].maxlen) {
    st[cur].minlen = st[x].maxlen + 1;
    st[cur].slink = x;
    degree[x]++;
    return cur;
  }

  y = new_state(st[v].maxlen + 1, -1, st[x].slink, st[x].trans);
  for (int w = v; w != -1 && st[w].trans[c] == x; w = st[w].slink)
    st[w].trans[c] = y;
  st[x].slink = st[cur].slink = y;
  degree[y] += 2;
  st[x].minlen = st[cur].minlen = st[y].maxlen + 1;
  st[y].minlen = st[st[y].slink].maxlen + 1;

  return cur;
}

void topo() {
  queue<int> q;
  for (int i = 1; i < size; i++) {
    if (degree[i] == 0)
      q.push(i);
  }
  while (!q.empty()){
    int x = q.front(); q.pop();
    endpos[st[x].slink] += endpos[x];
    if (--degree[st[x].slink] == 0)
      q.push(st[x].slink);
  }
}

void init() {
  size = 0;
  last = new_state(0, 0, -1, NULL);
}

int ans[N + 10];

int main()
{
	scanf("%s",s+1);
	int len=strlen(s+1);
	init();
	for(int i=1;i<=len;i++)
	{
		last=add_char(s[i],last);
	}
	topo();
	for(int i=0;i<size;i++)
	{
		ans[st[i].maxlen]=max(ans[st[i].maxlen],endpos[i]);
	}
	for(int i=len-1;i>=1;i--)
	{
		ans[i]=max(ans[i],ans[i+1]);
	}
	for(int i=1;i<=len;i++)
	{
		printf("%d\n",ans[i]);
	}
	return 0;
}
