//cf835d 发现规律+打表
/*
连T几次后才发现规律。。
多写几组看出,k-回文串的必要条件是其本身是回文串,
在这个基础上,只要保证它的左半部分和右半部分分别都是回文串即可。
(如果用左半部分和右半部分比较是否相同必然超时。。)
这样一上来用n^2时间找出所有回文串并标记,接着从小到大枚举k,然后枚举k-回文串推k+1-回文串。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
#define ll long long
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define frr(i,a,b) for(int i=a;i>=b;i--)
#define ms(a,b) memset(a,b,sizeof(a))
#define scfd(a) scanf("%d",a)
#define scflf(a) scanf("%lf",a)
#define scfs(a) scanf("%s",a)
#define ptfd(a) printf("%d\n",a)
#define ptfs(a) printf("%s\n",a)
#define showd(a,b) printf(a"=%d\n",b)
#define showlf(a,b) printf(a"=%lf\n",b)
#define shows(a,b) printf(a"=%s\n",b)
#define mmcp(a,b) memcpy(a,b,sizeof(b))
using namespace std;
const int MAXN=5005;
struct pairs{
int l,r;
bool operator<(const pairs& a)const{
if(r-l+1!=a.r-a.l+1)
return r-l+1<a.r-a.l+1;
else
return l<a.l;
}
}p[MAXN*MAXN/2];
pairs t[MAXN*MAXN/2];
bool ok[MAXN][MAXN];
char s[MAXN];
int len;
int con[MAXN];
int main(){
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
ms(ok,false);
scfs(s);
len=strlen(s);
int l,r;
fr(i,0,len-1){
l=r=i;
while(l>=0&&r<=len-1&&s[l]==s[r]){
ok[l][r]=true;
p[con[1]++]=(pairs){l--,r++};
}
}
fr(i,0,len-2){
l=i,r=i+1;
while(l>=0&&r<=len-1&&s[l]==s[r]){
ok[l][r]=true;
p[con[1]++]=(pairs){l--,r++};
}
}
printf("%d",con[1]);
fr(i,2,len){
fr(j,0,con[i-1]-1){
if(ok[p[j].r+1][p[j].r+1+p[j].r-p[j].l]&&ok[p[j].l][p[j].r+1+p[j].r-p[j].l])
t[con[i]++]=(pairs){p[j].l,p[j].r+1+p[j].r-p[j].l};
if(ok[p[j].r+2][p[j].r+2+p[j].r-p[j].l]&&ok[p[j].l][p[j].r+2+p[j].r-p[j].l])
t[con[i]++]=(pairs){p[j].l,p[j].r+2+p[j].r-p[j].l};
}
fr(j,0,con[i]-1)
p[j]=t[j];
printf(" %d",con[i]);
}
printf("\n");
return 0;
}