#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
const long long tmp=1e9+7;
string s;
int a[5005];
long long hash1[5005];
long long hash2[5005];
int k[5005][5005];
int ans[5005];
int len;
long long Pow[5005];
bool palin(int x,int y){
	long long Hash1=hash1[y]-hash1[x-1]*Pow[y-x+1];
	long long Hash2=hash2[x]-hash2[y+1]*Pow[y-x+1];
	if (Hash1==Hash2){
		return true;
	}
	else{
		return false;
	}
}
void getans(int x,int y){
	if (k[x][y]!=-1){
		return;
	}
	if (!palin(x,y)){
		k[x][y]=0;
		return;
	}
	int len=(y-x+1)/2;
	if (len==0){
		k[x][y]=1;
		return;
	}
	getans(x,x+len-1);
	k[x][y]=1+k[x][x+len-1];
	return;
}
int main(){
	memset(k,-1,sizeof(k));
	cin>>s;
	len=s.size();
	//if (s[0]=='d')cout<<"len="<<len<<endl;
	for (int i=0;i<len;i++){
		a[i+1]=s[i]-'a'+1;
	}
	//if (s[0]=='d')cout<<"??"<<endl;
	for (int i=1;i<=len;i++){
		hash1[i]=hash1[i-1]*tmp+a[i];
	}
	for (int i=len;i>=1;i--){
		hash2[i]=hash2[i+1]*tmp+a[i];
	}
	Pow[0]=1;
	for (int i=1;i<=len+1;i++){
		Pow[i]=Pow[i-1]*tmp;
	}
	//if (s[0]=='d')cout<<"?";
	for (int i=1;i<=len;i++){
		for (int j=i;j<=len;j++){
			getans(i,j);
			ans[k[i][j]]++;
		}
	}
	vector<int> Out;
	int Ans=0;
	for (int i=len;i>=1;i--){
		Ans+=ans[i];
		//cout<<Ans<<" ";
		Out.push_back(Ans);
	}
	for (int i=Out.size()-1;i>=0;i--){
		cout<<Out[i]<<" ";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
long long tmp=10;
long long Tmp=1;
long long hash1[5005],hash2[5005];
string s;
int len;
int a[5005];
int ans[10005];
int dp[5005][5005];
long long ksm(long long x,int y){
	if (y==0){
		return 1ll;
	}
	if (y==1){
		return x;
	}
	if (y%2==0){
		return ksm(x*x,y/2);
	}
	else{
		return x*ksm(x*x,y/2);
	}
}
long long gethash1(int l,int r){
	long long re=hash1[r]-hash1[l-1]*ksm(tmp,r-l+1);//ksm(tmp,l-1);
	if (s[0]=='d')cout<<re<<" ";
	return re;
}
long long gethash2(int l,int r){
	long long re=(hash2[r]-hash2[l-1])/ksm(tmp,l-1);
	if (s[0]=='d')cout<<re<<" ";
	return re;
}
int main(){
	cin>>s;
	len=s.size();
	if (s[0]=='d')cout<<"len="<<len<<endl;
	for (int i=1;i<=len;i++){
		a[i]=s[i-1]-'a'+1;
	}
	for (int i=1;i<=len;i++){
		hash1[i]=hash1[i-1]*tmp+(long long)a[i];
	}
	for (int i=1;i<=len;i++){
		hash2[i]=hash2[i-1]+(long long)a[i]*Tmp;
		Tmp*=tmp;
	}
	/*for (int i=1;i<=len;i++){
		cout<<hash1[i]<<" ";
	}
	cout<<endl;
	for (int i=1;i<=len;i++){
		cout<<hash2[i]<<" ";
	}
	cout<<endl;*/
	//cout<<ksm(2,10);
	for (int L=1;L<=len;L++){
		for (int i=1;i<=len;i++){
			if (i+L-1>len){
				break;
			}
			//cout<<i<<" "<<i+L/2-1<<" "<<i+L-1-L/2+1<<" "<<i+L-1<<endl;
			int x1=i;
			int x2=i+L/2;
			if (L%2==0){
				x2--;
			}
			int y1=i+L-1-L/2;
			if (L%2==0){
				y1++;
			}
			int y2=i+L-1;
			if (L!=1 && x2==y1){
				x2--;
				y1++;
			}
			//cout<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl;
			//cout<<gethash1(x1,x2)<<" "<<gethash2(y1,y2)<<endl;
			if (gethash1(x1,x2)==gethash2(y1,y2)){
				dp[i][i+L-1]=dp[i][x2]+1;
				//cout<<dp[i][i+L-1]<<endl;
				ans[dp[i][i+L-1]]++;
			}
		}
	}
	vector<int> Out;
	int Ans=0;
	for (int i=len;i>=1;i--){
		Ans+=ans[i];
		//cout<<Ans<<" ";
		Out.push_back(Ans);
	}
	for (int i=Out.size()-1;i>=0;i--){
		cout<<Out[i]<<" ";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
long long tmp=10;
long long Tmp=1;
long long hash1[5005],hash2[5005];
string s;
int len;
int a[5005];
int ans[10005];
int dp[5005][5005];
long long ksm(long long x,int y){
	if (y==0){
		return 1ll;
	}
	if (y==1){
		return x;
	}
	if (y%2==0){
		return ksm(x*x,y/2);
	}
	else{
		return x*ksm(x*x,y/2);
	}
}
long long gethash1(int l,int r){
	long long re=hash1[r]-hash1[l-1]*ksm(tmp,r-l+1);//ksm(tmp,l-1);
	if (s[0]=='d')cout<<re<<" ";
	return re;
}
long long gethash2(int l,int r){
	long long re=(hash2[r]-hash2[l-1])/ksm(tmp,l-1);
	if (s[0]=='d')cout<<re<<" ";
	return re;
}
int main(){
	cin>>s;
	len=s.size();
	cout<<"len="<<len<<endl;
	for (int i=1;i<=len;i++){
		a[i]=s[i-1]-'a'+1;
	}
	for (int i=1;i<=len;i++){
		hash1[i]=hash1[i-1]*tmp+(long long)a[i];
	}
	for (int i=1;i<=len;i++){
		hash2[i]=hash2[i-1]+(long long)a[i]*Tmp;
		Tmp*=tmp;
	}
	/*for (int i=1;i<=len;i++){
		cout<<hash1[i]<<" ";
	}
	cout<<endl;
	for (int i=1;i<=len;i++){
		cout<<hash2[i]<<" ";
	}
	cout<<endl;*/
	//cout<<ksm(2,10);
	for (int L=1;L<=len;L++){
		for (int i=1;i<=len;i++){
			if (i+L-1>len){
				break;
			}
			//cout<<i<<" "<<i+L/2-1<<" "<<i+L-1-L/2+1<<" "<<i+L-1<<endl;
			int x1=i;
			int x2=i+L/2;
			if (L%2==0){
				x2--;
			}
			int y1=i+L-1-L/2;
			if (L%2==0){
				y1++;
			}
			int y2=i+L-1;
			if (L!=1 && x2==y1){
				x2--;
				y1++;
			}
			//cout<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl;
			//cout<<gethash1(x1,x2)<<" "<<gethash2(y1,y2)<<endl;
			if (gethash1(x1,x2)==gethash2(y1,y2)){
				dp[i][i+L-1]=dp[i][x2]+1;
				//cout<<dp[i][i+L-1]<<endl;
				ans[dp[i][i+L-1]]++;
			}
		}
	}
	vector<int> Out;
	int Ans=0;
	for (int i=len;i>=1;i--){
		Ans+=ans[i];
		//cout<<Ans<<" ";
		Out.push_back(Ans);
	}
	for (int i=Out.size()-1;i>=0;i--){
		cout<<Out[i]<<" ";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
const long long tmp=1e9+7;
string s;
int a[5005];
long long hash1[5005];
long long hash2[5005];
int k[5005][5005];
int ans[5005];
int len;
long long Pow[5005];
bool palin(int x,int y){
	long long Hash1=hash1[y]-hash1[x-1]*Pow[y-x+1];
	long long Hash2=hash2[x]-hash2[y+1]*Pow[y-x+1];
	if (Hash1==Hash2){
		return true;
	}
	else{
		return false;
	}
}
void getans(int x,int y){
	if (k[x][y]!=-1){
		return;
	}
	if (!palin(x,y)){
		k[x][y]=0;
		return;
	}
	int len=(y-x+1)/2;
	if (len==0){
		k[x][y]=1;
		return;
	}
	getans(x,x+len-1);
	k[x][y]=1+k[x][x+len-1];
	return;
}
int main(){
	memset(k,-1,sizeof(k));
	cin>>s;
	len=s.size();
	if (s[0]=='d')cout<<"len="<<len<<endl;
	for (int i=0;i<len;i++){
		a[i+1]=s[i]-'a'+1;
	}
	if (s[0]=='d')cout<<"??"<<endl;
	for (int i=1;i<=len;i++){
		hash1[i]=hash1[i-1]*tmp+a[i];
	}
	for (int i=len;i>=1;i--){
		hash2[i]=hash2[i+1]*tmp+a[i];
	}
	Pow[0]=1;
	for (int i=1;i<=len+1;i++){
		Pow[i]=Pow[i-1]*tmp;
	}
	if (s[0]=='d')cout<<"?";
	for (int i=1;i<=len;i++){
		for (int j=i;j<=len;j++){
			getans(i,j);
			ans[k[i][j]]++;
		}
	}
	vector<int> Out;
	int Ans=0;
	for (int i=len;i>=1;i--){
		Ans+=ans[i];
		//cout<<Ans<<" ";
		Out.push_back(Ans);
	}
	for (int i=Out.size()-1;i>=0;i--){
		cout<<Out[i]<<" ";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
long long tmp=10;
long long Tmp=1;
long long hash1[5005],hash2[5005];
string s;
int len;
int a[5005];
int ans[10005];
int dp[5005][5005];
long long ksm(long long x,int y){
	if (y==0){
		return 1ll;
	}
	if (y==1){
		return x;
	}
	if (y%2==0){
		return ksm(x*x,y/2);
	}
	else{
		return x*ksm(x*x,y/2);
	}
}
long long gethash1(int l,int r){
	long long re=hash1[r]-hash1[l-1]*ksm(tmp,r-l+1);//ksm(tmp,l-1);
	if (s[0]=='d')cout<<re<<" ";
	return re;
}
long long gethash2(int l,int r){
	long long re=(hash2[r]-hash2[l-1])/ksm(tmp,l-1);
	if (s[0]=='d')cout<<re<<" ";
	return re;
}
int main(){
	cin>>s;
	len=s.size();
	if (s[0]=='d')cout<<"len="<<len<<endl;
	for (int i=1;i<=len;i++){
		a[i]=s[i-1]-'a'+1;
	}
	if (s[0]=='d')cout<<"?"<<endl;
	for (int i=1;i<=len;i++){
		hash1[i]=hash1[i-1]*tmp+(long long)a[i];
	}
	for (int i=1;i<=len;i++){
		hash2[i]=hash2[i-1]+(long long)a[i]*Tmp;
		Tmp*=tmp;
	}
	if (s[0]=='d')cout<<"?"<<endl;
	/*for (int i=1;i<=len;i++){
		cout<<hash1[i]<<" ";
	}
	cout<<endl;
	for (int i=1;i<=len;i++){
		cout<<hash2[i]<<" ";
	}
	cout<<endl;*/
	//cout<<ksm(2,10);
	for (int L=1;L<=len;L++){
		for (int i=1;i<=len;i++){
			if (i+L-1>len){
				break;
			}
			//cout<<i<<" "<<i+L/2-1<<" "<<i+L-1-L/2+1<<" "<<i+L-1<<endl;
			int x1=i;
			int x2=i+L/2;
			if (L%2==0){
				x2--;
			}
			int y1=i+L-1-L/2;
			if (L%2==0){
				y1++;
			}
			int y2=i+L-1;
			if (L!=1 && x2==y1){
				x2--;
				y1++;
			}
			//cout<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl;
			//cout<<gethash1(x1,x2)<<" "<<gethash2(y1,y2)<<endl;
			if (gethash1(x1,x2)==gethash2(y1,y2)){
				dp[i][i+L-1]=dp[i][x2]+1;
				//cout<<dp[i][i+L-1]<<endl;
				ans[dp[i][i+L-1]]++;
			}
		}
	}
	vector<int> Out;
	int Ans=0;
	for (int i=len;i>=1;i--){
		Ans+=ans[i];
		//cout<<Ans<<" ";
		Out.push_back(Ans);
	}
	for (int i=Out.size()-1;i>=0;i--){
		cout<<Out[i]<<" ";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
const long long tmp=1e9+7;
string s;
int a[5005];
long long hash1[5005];
long long hash2[5005];
int k[5005][5005];
int ans[5005];
int len;
long long Pow[5005];
bool palin(int x,int y){
	long long Hash1=hash1[y]-hash1[x-1]*Pow[y-x+1];
	long long Hash2=hash2[x]-hash2[y+1]*Pow[y-x+1];
	if (Hash1==Hash2){
		return true;
	}
	else{
		return false;
	}
}
void getans(int x,int y){
	if (k[x][y]!=-1){
		return;
	}
	if (!palin(x,y)){
		k[x][y]=0;
		return;
	}
	int len=(y-x+1)/2;
	if (len==0){
		k[x][y]=1;
		return;
	}
	k[x][y]=1+k[x][x+len-1];
	return;
}
int main(){
	memset(k,-1,sizeof(k));
	cin>>s;
	len=s.size();
	for (int i=0;i<len;i++){
		a[i+1]=s[i]-'a'+1;
	}
	for (int i=1;i<=len;i++){
		hash1[i]=hash1[i-1]*tmp+a[i];
	}
	for (int i=len;i>=1;i--){
		hash2[i]=hash2[i+1]*tmp+a[i];
	}
	Pow[0]=1;
	for (int i=1;i<=len+5;i++){
		Pow[i]=Pow[i-1]*tmp;
	}
	for (int i=1;i<=len;i++){
		for (int j=i;j<=len;j++){
			getans(i,j);
			ans[k[i][j]]++;
		}
	}
	vector<int> Out;
	int Ans=0;
	for (int i=len;i>=1;i--){
		Ans+=ans[i];
		//cout<<Ans<<" ";
		Out.push_back(Ans);
	}
	for (int i=Out.size()-1;i>=0;i--){
		cout<<Out[i]<<" ";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
long long tmp=10;
long long Tmp=1;
long long hash1[5005],hash2[5005];
string s;
int len;
int a[5005];
int ans[10005];
int dp[5005][5005];
long long ksm(long long x,int y){
	if (y==0){
		return 1ll;
	}
	if (y==1){
		return x;
	}
	if (y%2==0){
		return ksm(x*x,y/2);
	}
	else{
		return x*ksm(x*x,y/2);
	}
}
long long gethash1(int l,int r){
	long long re=hash1[r]-hash1[l-1]*ksm(tmp,r-l+1);//ksm(tmp,l-1);
	return re;
}
long long gethash2(int l,int r){
	long long re=(hash2[r]-hash2[l-1])/ksm(tmp,l-1);
	return re;
}
int main(){
	cin>>s;
	len=s.size();
	for (int i=1;i<=len;i++){
		a[i]=s[i-1]-'a'+1;
	}
	for (int i=1;i<=len;i++){
		hash1[i]=hash1[i-1]*tmp+(long long)a[i];
	}
	for (int i=1;i<=len;i++){
		hash2[i]=hash2[i-1]+(long long)a[i]*Tmp;
		Tmp*=tmp;
	}
	/*for (int i=1;i<=len;i++){
		cout<<hash1[i]<<" ";
	}
	cout<<endl;
	for (int i=1;i<=len;i++){
		cout<<hash2[i]<<" ";
	}
	cout<<endl;*/
	//cout<<ksm(2,10);
	for (int L=1;L<=len;L++){
		for (int i=1;i<=len;i++){
			if (i+L-1>len){
				break;
			}
			//cout<<i<<" "<<i+L/2-1<<" "<<i+L-1-L/2+1<<" "<<i+L-1<<endl;
			int x1=i;
			int x2=i+L/2;
			if (L%2==0){
				x2--;
			}
			int y1=i+L-1-L/2;
			if (L%2==0){
				y1++;
			}
			int y2=i+L-1;
			if (L!=1 && x2==y1){
				x2--;
				y1++;
			}
			//cout<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl;
			//cout<<gethash1(x1,x2)<<" "<<gethash2(y1,y2)<<endl;
			if (gethash1(x1,x2)==gethash2(y1,y2)){
				dp[i][i+L-1]=dp[i][x2]+1;
				//cout<<dp[i][i+L-1]<<endl;
				ans[dp[i][i+L-1]]++;
			}
		}
	}
	vector<int> Out;
	int Ans=0;
	for (int i=len;i>=1;i--){
		Ans+=ans[i];
		//cout<<Ans<<" ";
		Out.push_back(Ans);
	}
	for (int i=Out.size()-1;i>=0;i--){
		cout<<Out[i]<<" ";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
const long long tmp=1e9+7;
string s;
int a[5005];
long long hash1[5005];
long long hash2[5005];
int k[5005][5005];
int ans[5005];
int len;
long long Pow[5005];
bool palin(int x,int y){
	long long Hash1=hash1[y]-hash1[x-1]*Pow[y-x+1];
	long long Hash2=hash2[x]-hash2[y+1]*Pow[y-x+1];
	if (Hash1==Hash2){
		return true;
	}
	else{
		return false;
	}
}
void getans(int x,int y){
	if (k[x][y]!=-1){
		return;
	}
	if (!palin(x,y)){
		k[x][y]=0;
		return;
	}
	int len=(y-x+1)/2;
	if (len==0){
		k[x][y]=1;
		return;
	}
	getans(x,x+len-1);
	k[x][y]=1+k[x][x+len-1];
	return;
}
int main(){
	memset(k,-1,sizeof(k));
	cin>>s;
	len=s.size();
	for (int i=0;i<len;i++){
		a[i+1]=s[i]-'a'+1;
	}
	for (int i=1;i<=len;i++){
		hash1[i]=hash1[i-1]*tmp+a[i];
	}
	for (int i=len;i>=1;i--){
		hash2[i]=hash2[i+1]*tmp+a[i];
	}
	Pow[0]=1;
	for (int i=1;i<=len+5;i++){
		Pow[i]=Pow[i-1]*tmp;
	}
	if (s[0]=='d')cout<<"?";
	for (int i=1;i<=len;i++){
		for (int j=i;j<=len;j++){
			getans(i,j);
			ans[k[i][j]]++;
		}
	}
	vector<int> Out;
	int Ans=0;
	for (int i=len;i>=1;i--){
		Ans+=ans[i];
		//cout<<Ans<<" ";
		Out.push_back(Ans);
	}
	for (int i=Out.size()-1;i>=0;i--){
		cout<<Out[i]<<" ";
	}
	return 0;
}


/* <3 <3 <3 */
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ull unsigned long long
#define ii pair <int,int>
#define iii pair <ii,int>
#define fi first
#define se second
#define pb push_back

const int HashMod=1125022017;
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
const int oo = 2e9;
const int nmax=5e3+9;

ll sufhash[nmax];
ll prehash[nmax];
ll pow26[nmax];
string s;
int dp[nmax][nmax];
int res[nmax];

bool check(int x1,int y1)
{
    ll hash1=(sufhash[y1]-sufhash[x1-1]*pow26[y1-x1+1]+HashMod)%HashMod;
    ll hash2=(prehash[x1]-prehash[y1+1]*pow26[y1-x1+1]+HashMod)%HashMod;
    return hash1==hash2;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    //freopen("Test.inp","r",stdin);
    //freopen("Test.out","w",stdout);
    cin >> s;
    pow26[0]=1;
    sufhash[0]=s[0]-'a';
    for (int i=1;i<s.length();i++)
    {
        pow26[i]=(pow26[i-1]*26)%HashMod;
        sufhash[i]=(26*sufhash[i-1]+s[i]-'a')%HashMod;
    }
    prehash[(int)s.length()-1]=s[(int)s.length()-1]-'a';
    for (int i=s.length()-2;i>=0;i--)
        prehash[i]=(26*prehash[i+1]+s[i]-'a')%HashMod;
    for (int i=1;i<=s.length();i++)
        for (int j=0;j<s.length();j++)
        {
            int j_=j+i-1;
            if (j_>=s.length())
                break;
            if (i==1)
            {
                dp[j][j_]=1;
                res[1]+=1;
            }
            else
                if (check(j,j_))
                {
                    int mid = j+j_;
                    if (mid%2==0)
                    {
                        mid/=2;
                        mid-=1;
                        dp[j][j_]=min(dp[j][mid],dp[mid+2][j_])+1;
                        res[dp[j][j_]]+=1;
                    }
                    else
                    {
                        mid/=2;
                        dp[j][j_]=min(dp[j][mid],dp[mid+1][j_])+1;
                        res[dp[j][j_]]+=1;
                    }
                }
                else
                    dp[j][j_]=0;
        }
    for (int i=s.length();i>=1;i--)
        res[i]+=res[i+1];
    for (int i=1;i<=s.length();i++)
        cout << res[i] << " ";
    return 0;
}


/* <3 <3 <3 */
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ull unsigned long long
#define ii pair <int,int>
#define iii pair <ii,int>
#define fi first
#define se second
#define pb push_back

const int HashMod=1196948531;
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
const int oo = 2e9;
const int nmax=5e3+9;

ll sufhash[nmax];
ll prehash[nmax];
ll pow26[nmax];
string s;
int dp[nmax][nmax];
int res[nmax];

bool check(int x1,int y1)
{
    ll hash1=(sufhash[y1]-(sufhash[x1-1]*pow26[y1-x1+1])%HashMod+HashMod)%HashMod;
    ll hash2=(prehash[x1]-(prehash[y1+1]*pow26[y1-x1+1])%HashMod+HashMod)%HashMod;
    return hash1==hash2;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    //freopen("Test.inp","r",stdin);
    //freopen("Test.out","w",stdout);
    cin >> s;
    pow26[0]=1;
    sufhash[0]=s[0]-'a';
    for (int i=1;i<s.length();i++)
    {
        pow26[i]=(pow26[i-1]*26)%HashMod;
        sufhash[i]=(26*sufhash[i-1]+s[i]-'a')%HashMod;
    }
    prehash[(int)s.length()-1]=s[(int)s.length()-1]-'a';
    for (int i=s.length()-2;i>=0;i--)
        prehash[i]=(26*prehash[i+1]+s[i]-'a')%HashMod;
    for (int i=1;i<=s.length();i++)
        for (int j=0;j<s.length();j++)
        {
            int j_=j+i-1;
            if (j_>=s.length())
                break;
            if (i==1)
            {
                dp[j][j_]=1;
                res[1]+=1;
            }
            else
                if (check(j,j_))
                {
                    int mid = j+j_;
                    if (mid%2==0)
                    {
                        mid/=2;
                        mid-=1;
                        dp[j][j_]=min(dp[j][mid],dp[mid+2][j_])+1;
                        res[dp[j][j_]]+=1;
                    }
                    else
                    {
                        mid/=2;
                        dp[j][j_]=min(dp[j][mid],dp[mid+1][j_])+1;
                        res[dp[j][j_]]+=1;
                    }
                }
                else
                    dp[j][j_]=0;
        }
    /*for (int i=0;i<s.length();i++)
        cout << sufhash[i] << " " << prehash[i] << endl;
    */
    for (int i=s.length();i>=1;i--)
        res[i]+=res[i+1];
    for (int i=1;i<=s.length();i++)
        cout << res[i] << " ";
    return 0;
}


/* <3 <3 <3 */
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ull unsigned long long
#define ii pair <int,int>
#define iii pair <ii,int>
#define fi first
#define se second
#define pb push_back

const int HashMod=1125022017;
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
const int oo = 2e9;
const int nmax=5e3+9;

ll sufhash[nmax];
ll prehash[nmax];
ll pow26[nmax];
string s;
int dp[nmax][nmax];
int res[nmax];

bool check(int x1,int y1)
{
    ll hash1=(sufhash[y1]-(sufhash[x1-1]*pow26[y1-x1+1])%HashMod+HashMod)%HashMod;
    ll hash2=(prehash[x1]-(prehash[y1+1]*pow26[y1-x1+1])%HashMod+HashMod)%HashMod;
    return hash1==hash2;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    //freopen("Test.inp","r",stdin);
    //freopen("Test.out","w",stdout);
    cin >> s;
    pow26[0]=1;
    sufhash[0]=s[0]-'a';
    for (int i=1;i<s.length();i++)
    {
        pow26[i]=(pow26[i-1]*26)%HashMod;
        sufhash[i]=(26*sufhash[i-1]+s[i]-'a')%HashMod;
    }
    prehash[(int)s.length()-1]=s[(int)s.length()-1]-'a';
    for (int i=s.length()-2;i>=0;i--)
        prehash[i]=(26*prehash[i+1]+s[i]-'a')%HashMod;
    for (int i=1;i<=s.length();i++)
        for (int j=0;j<s.length();j++)
        {
            int j_=j+i-1;
            if (j_>=s.length())
                break;
            if (i==1)
            {
                dp[j][j_]=1;
                res[1]+=1;
            }
            else
                if (check(j,j_))
                {
                    int mid = j+j_;
                    if (mid%2==0)
                    {
                        mid/=2;
                        mid-=1;
                        dp[j][j_]=min(dp[j][mid],dp[mid+2][j_])+1;
                        res[dp[j][j_]]+=1;
                    }
                    else
                    {
                        mid/=2;
                        dp[j][j_]=min(dp[j][mid],dp[mid+1][j_])+1;
                        res[dp[j][j_]]+=1;
                    }
                }
                else
                    dp[j][j_]=0;
        }
    /*for (int i=0;i<s.length();i++)
        cout << sufhash[i] << " " << prehash[i] << endl;
    */
    for (int i=s.length();i>=1;i--)
        res[i]+=res[i+1];
    for (int i=1;i<=s.length();i++)
        cout << res[i] << " ";
    return 0;
}


#include<bits/stdc++.h>
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define mod 1000000007
using namespace std;

int cnt[5005][5005];
long long pref_hash[5005];
long long sim[5005];
int jawab[5005];

long long cari(int kiri,int kanan){
	long long jawab = pref_hash[kanan];
	if(kiri != 0){
		jawab = jawab - pref_hash[kiri-1];
	}
//	if(jawab < 0) jawab += mod;
	return jawab;
}

int main(){
	string baca; cin>>baca;

	memset(jawab,0,sizeof(jawab));
	pref_hash[0] = baca[0] - 'a';
	long long kali = 31;
	sim[0] = 1;
	for(int i=1;i<baca.length();i++){
		pref_hash[i] = (pref_hash[i-1] + kali * (baca[i] - 'a'));//%mod;
	//	cout<<i<<" "<<pref_hash[i]<<"\n";
		sim[i] = kali;
		kali = (kali * 31);//%mod;
	}
	for(int i=1;i<=baca.length();i++){
		for(int l=0;l<=baca.length()-i;l++){
			int r = l + i - 1;
			if(i == 1){
				cnt[l][r] = 1;
				//cout<<l<<" "<<r<<" haha\n";
				jawab[1]++;
			}else{
				long long kiri = (cari(l,l + (i/2) - 1) * sim[r - l - (i/2) + 1]);//%mod;
				long long kanan = cari(r - (i/2) + 1,r);
				if(baca[l]!=baca[r] || (r - l >= 2 && cnt[l+1][r-1] == 0)){
					cnt[l][r] = 0;
				}else{
					cnt[l][r] = cnt[l][l + (i/2) - 1] + 1;
					for(int j=cnt[l][r];j>=1;j--){
						jawab[j]++;
					}
				}
			}
		//	cout<<l<<" "<<r<<" "<<cnt[l][r]<<"\n";
		}
	}

	for(int i=1;i<=baca.length();i++){
		if(i != 1){
			cout<<" ";
		}
		cout<<jawab[i];
	}
	cout<<"\n";
}


#include<bits/stdc++.h>
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define mod 1000000007
using namespace std;

int cnt[5005][5005];
long long pref_hash[5005];
long long sim[5005];
int jawab[5005];

long long cari(int kiri,int kanan){
	long long jawab = pref_hash[kanan];
	if(kiri != 0){
		jawab = jawab - pref_hash[kiri-1];
	}
	return jawab;
}

int main(){
	string baca; cin>>baca;

	memset(jawab,0,sizeof(jawab));
	pref_hash[0] = baca[0] - 'a';
	long long kali = 29;
	sim[0] = 1;
	for(int i=1;i<baca.length();i++){
		pref_hash[i] = (pref_hash[i-1] + kali * (baca[i] - 'a'));
	//	cout<<i<<" "<<pref_hash[i]<<"\n";
		sim[i] = kali;
		kali = kali * 29;
	}
	for(int i=1;i<=baca.length();i++){
		for(int l=0;l<=baca.length()-i;l++){
			int r = l + i - 1;
			if(i == 1){
				cnt[l][r] = 1;
				//cout<<l<<" "<<r<<" haha\n";
				jawab[1]++;
			}else{
				long long kiri = cari(l,l + (i/2) - 1) * sim[r - l - (i/2) + 1];
				long long kanan = cari(r - (i/2) + 1,r);
			//	cout<<kiri<<" "<<kanan<<" "<<l<<" "<<r<<"\n";
				if(kiri == kanan){
					cnt[l][r] = cnt[l][l + (i/2) - 1] + 1;
		//			cout<<l<<" "<<r<<" hihi\n";
					for(int y=cnt[l][r];y>=1;y--){
						jawab[y]++;
					}
				}else{
					bool palin = true;
					int x = l, y = r;
					while(x < y){
						if(baca[x] != baca[y]){
							palin = false;
							break;
						}
						x++;
						y--;
					}
					if(palin){
						cnt[l][r] = 1;
		//				cout<<l<<" "<<r<<" haha\n";
						jawab[1]++;
					}else{
						cnt[l][r] = 0;
					}
				}
			}
		//	cout<<l<<" "<<r<<" "<<cnt[l][r]<<"\n";
		}
	}

	for(int i=1;i<=baca.length();i++){
		if(i != 1){
			cout<<" ";
		}
		cout<<jawab[i];
	}
	cout<<"\n";
}


#include<bits/stdc++.h>
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define mod 1000000007
using namespace std;

int cnt[5005][5005];
long long pref_hash[5005];
long long sim[5005];
int jawab[5005];

long long cari(int kiri,int kanan){
	long long jawab = pref_hash[kanan];
	if(kiri != 0){
		jawab = jawab - pref_hash[kiri-1];
	}
//	if(jawab < 0) jawab += mod;
	return jawab;
}

int main(){
	string baca; cin>>baca;

	memset(jawab,0,sizeof(jawab));
	pref_hash[0] = baca[0] - 'a';
	long long kali = 31;
	sim[0] = 1;
	for(int i=1;i<baca.length();i++){
		pref_hash[i] = (pref_hash[i-1] + kali * (baca[i] - 'a'));//%mod;
	//	cout<<i<<" "<<pref_hash[i]<<"\n";
		sim[i] = kali;
		kali = (kali * 31);//%mod;
	}
	for(int i=1;i<=baca.length();i++){
		for(int l=0;l<=baca.length()-i;l++){
			int r = l + i - 1;
			if(i == 1){
				cnt[l][r] = 1;
				//cout<<l<<" "<<r<<" haha\n";
				jawab[1]++;
			}else{
				long long kiri = (cari(l,l + (i/2) - 1) * sim[r - l - (i/2) + 1]);//%mod;
				long long kanan = cari(r - (i/2) + 1,r);
			//	cout<<kiri<<" "<<kanan<<" "<<l<<" "<<r<<"\n";
				if(kiri == kanan){
					cnt[l][r] = cnt[l][l + (i/2) - 1] + 1;
		//			cout<<l<<" "<<r<<" hihi\n";
					for(int y=cnt[l][r];y>=1;y--){
						jawab[y]++;
					}
				}else{
					bool palin = true;
					int x = l, y = r;
					while(x < y){
						if(baca[x] != baca[y]){
							palin = false;
							break;
						}
						x++;
						y--;
					}
					if(palin){
						cnt[l][r] = 1;
		//				cout<<l<<" "<<r<<" haha\n";
						jawab[1]++;
					}else{
						cnt[l][r] = 0;
					}
				}
			}
		//	cout<<l<<" "<<r<<" "<<cnt[l][r]<<"\n";
		}
	}

	for(int i=1;i<=baca.length();i++){
		if(i != 1){
			cout<<" ";
		}
		cout<<jawab[i];
	}
	cout<<"\n";
}


#include<bits/stdc++.h>
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define mod 1000000007
using namespace std;

int cnt[5005][5005];
long long pref_hash[5005];
long long sim[5005];
int jawab[5005];

long long cari(int kiri,int kanan){
	long long jawab = pref_hash[kanan];
	if(kiri != 0){
		jawab = jawab - pref_hash[kiri-1];
	}
	if(jawab < 0) jawab += mod;
	return jawab;
}

int main(){
	string baca; cin>>baca;

	memset(jawab,0,sizeof(jawab));
	pref_hash[0] = baca[0] - 'a';
	long long kali = 29;
	sim[0] = 1;
	for(int i=1;i<baca.length();i++){
		pref_hash[i] = (pref_hash[i-1] + kali * (baca[i] - 'a'))%mod;
	//	cout<<i<<" "<<pref_hash[i]<<"\n";
		sim[i] = kali;
		kali = (kali * 29)%mod;
	}
	for(int i=1;i<=baca.length();i++){
		for(int l=0;l<=baca.length()-i;l++){
			int r = l + i - 1;
			if(i == 1){
				cnt[l][r] = 1;
				//cout<<l<<" "<<r<<" haha\n";
				jawab[1]++;
			}else{
				long long kiri = (cari(l,l + (i/2) - 1) * sim[r - l - (i/2) + 1])%mod;
				long long kanan = cari(r - (i/2) + 1,r);
			//	cout<<kiri<<" "<<kanan<<" "<<l<<" "<<r<<"\n";
				if(kiri == kanan){
					cnt[l][r] = cnt[l][l + (i/2) - 1] + 1;
		//			cout<<l<<" "<<r<<" hihi\n";
					for(int y=cnt[l][r];y>=1;y--){
						jawab[y]++;
					}
				}else{
					bool palin = true;
					int x = l, y = r;
					while(x < y){
						if(baca[x] != baca[y]){
							palin = false;
							break;
						}
						x++;
						y--;
					}
					if(palin){
						cnt[l][r] = 1;
		//				cout<<l<<" "<<r<<" haha\n";
						jawab[1]++;
					}else{
						cnt[l][r] = 0;
					}
				}
			}
		//	cout<<l<<" "<<r<<" "<<cnt[l][r]<<"\n";
		}
	}

	for(int i=1;i<=baca.length();i++){
		if(i != 1){
			cout<<" ";
		}
		cout<<jawab[i];
	}
	cout<<"\n";
}


#include<bits/stdc++.h>
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define mod 1000000007
using namespace std;

int cnt[5005][5005];
long long pref_hash[5005];
long long sim[5005];
int jawab[5005];

long long cari(int kiri,int kanan){
	long long jawab = pref_hash[kanan];
	if(kiri != 0){
		jawab = jawab - pref_hash[kiri-1];
	}
	return jawab;
}

int main(){
	string baca; cin>>baca;

	memset(jawab,0,sizeof(jawab));
	pref_hash[0] = baca[0] - 'a';
	long long kali = 26;
	sim[0] = 1;
	for(int i=1;i<baca.length();i++){
		pref_hash[i] = (pref_hash[i-1] + kali * (baca[i] - 'a'));
	//	cout<<i<<" "<<pref_hash[i]<<"\n";
		sim[i] = kali;
		kali = kali * 26;
	}
	for(int i=1;i<=baca.length();i++){
		for(int l=0;l<=baca.length()-i;l++){
			int r = l + i - 1;
			if(i == 1){
				cnt[l][r] = 1;
				//cout<<l<<" "<<r<<" haha\n";
				jawab[1]++;
			}else{
				long long kiri = cari(l,l + (i/2) - 1) * sim[r - l - (i/2) + 1];
				long long kanan = cari(r - (i/2) + 1,r);
			//	cout<<kiri<<" "<<kanan<<" "<<l<<" "<<r<<"\n";
				if(kiri == kanan){
					cnt[l][r] = cnt[l][l + (i/2) - 1] + 1;
		//			cout<<l<<" "<<r<<" hihi\n";
					for(int y=cnt[l][r];y>=1;y--){
						jawab[y]++;
					}
				}else{
					bool palin = true;
					int x = l, y = r;
					while(x < y){
						if(baca[x] != baca[y]){
							palin = false;
							break;
						}
						x++;
						y--;
					}
					if(palin){
						cnt[l][r] = 1;
		//				cout<<l<<" "<<r<<" haha\n";
						jawab[1]++;
					}else{
						cnt[l][r] = 0;
					}
				}
			}
		//	cout<<l<<" "<<r<<" "<<cnt[l][r]<<"\n";
		}
	}

	for(int i=1;i<=baca.length();i++){
		if(i != 1){
			cout<<" ";
		}
		cout<<jawab[i];
	}
	cout<<"\n";
}


#include<bits/stdc++.h>
#define maxn 5010
using namespace std;
int f[maxn][maxn],tmp[maxn][maxn],yuan[maxn][maxn],mx,id,p[maxn],sum,alr;
char s[maxn],t[maxn];
int main()
{
	scanf("%s",&s);
	int len=strlen(s),tlen=len;
	t[1]='?'; t[2]='#';
	for (int i=1;i<=len;i++)
	{
		t[2*i+1]=s[i-1]; t[2*i+2]='#';
	}
	p[1]=p[2]=1; mx=id=2; len=2*len+3; t[len]='$';
	for (int i=3;i<=len;i++)
	{
		if (i<=mx) p[i]=min(p[2*id-i],mx-i+1); else p[i]=1;
		while (t[i+p[i]]==t[i-p[i]]) p[i]++;
		if (i%2==1)
		{
			int l=i/2,r=i/2;
			for (int j=1;j<=p[i];j+=2)
			{
				f[l][r]=1; l--; r++;
			}
		}
		else
		{
			int l=i/2-1,r=i/2;
			for (int j=2;j<=p[i];j+=2)
			{
				f[l][r]=1; l--; r++;
			}
		}
		if (i+p[i]-1>=mx)
		{
			mx=i+p[i]-1; id=i;
		}
	}
	for (int i=1;i<=tlen;i++)
		for (int j=i;j<=tlen;j++) sum+=f[i][j];
	printf("%d",sum); alr=1;
	memcpy(yuan,f,sizeof(f));
	for (int now=2;now<=tlen;now*=2)
	{
		sum=0;
		memset(tmp,0,sizeof(tmp));
		for (int i=1;i<=tlen;i++)
			for (int j=i+now-1;j<=tlen;j++)
			{
				int len=j-i+1;
				tmp[i][j]=yuan[i][j] & f[i][i+len/2-1] & f[j-len/2+1][j];
				sum+=tmp[i][j];
			}
		memcpy(f,tmp,sizeof(f));
		printf(" %d",sum);
		alr++;
	}
	alr++;
	for (alr;alr<=tlen;alr++)
	printf(" 0");
	printf("\n");
	return 0;

}


#include<bits/stdc++.h>
#define maxn 5010
using namespace std;
int mx,id,p[maxn],sum,alr;
bool f[maxn][maxn],tmp[maxn][maxn],yuan[maxn][maxn];
char s[maxn],t[maxn];
int main()
{
	scanf("%s",&s);
	int len=strlen(s),tlen=len;
	t[1]='?'; t[2]='#';
	for (int i=1;i<=len;i++)
	{
		t[2*i+1]=s[i-1]; t[2*i+2]='#';
	}
	p[1]=p[2]=1; mx=id=2; len=2*len+3; t[len]='$';
	for (int i=3;i<=len;i++)
	{
		if (i<=mx) p[i]=min(p[2*id-i],mx-i+1); else p[i]=1;
		while (t[i+p[i]]==t[i-p[i]]) p[i]++;
		if (i%2==1)
		{
			int l=i/2,r=i/2;
			for (int j=1;j<=p[i];j+=2)
			{
				f[l][r]=1; l--; r++;
			}
		}
		else
		{
			int l=i/2-1,r=i/2;
			for (int j=2;j<=p[i];j+=2)
			{
				f[l][r]=1; l--; r++;
			}
		}
		if (i+p[i]-1>=mx)
		{
			mx=i+p[i]-1; id=i;
		}
	}
	for (int i=1;i<=tlen;i++)
		for (int j=i;j<=tlen;j++) sum+=f[i][j];
	printf("%d",sum); alr=1;
	memcpy(yuan,f,sizeof(f));
	for (int now=2;now<=tlen;now*=2)
	{
		sum=0;
		memset(tmp,0,sizeof(tmp));
		for (int i=1;i<=tlen;i++)
			for (int j=i+now-1;j<=tlen;j++)
			{
				int len=j-i+1;
				tmp[i][j]=yuan[i][j] & f[i][i+len/2-1] & f[j-len/2+1][j];
				sum+=tmp[i][j];
			}
		memcpy(f,tmp,sizeof(f));
		printf(" %d",sum);
		alr++;
	}
	alr++;
	for (alr;alr<=tlen;alr++)
	printf(" 0");
	printf("\n");
	return 0;

}


#include<bits/stdc++.h>
#define maxn 5010
using namespace std;
int mx,id,p[maxn*3],sum,alr;
bool f[maxn][maxn],tmp[maxn][maxn],yuan[maxn][maxn];
char s[maxn],t[maxn];
int main()
{
	scanf("%s",&s);
	int len=strlen(s),tlen=len;
	t[1]='?'; t[2]='#';
	for (int i=1;i<=len;i++)
	{
		t[2*i+1]=s[i-1]; t[2*i+2]='#';
	}
	p[1]=p[2]=1; mx=id=2; len=2*len+3; t[len]='$';
	for (int i=3;i<=len;i++)
	{
		if (i<=mx) p[i]=min(p[2*id-i],mx-i+1); else p[i]=1;
		while (t[i+p[i]]==t[i-p[i]]) p[i]++;
		if (i%2==1)
		{
			int l=i/2,r=i/2;
			for (int j=1;j<=p[i];j+=2)
			{
				f[l][r]=1; l--; r++;
			}
		}
		else
		{
			int l=i/2-1,r=i/2;
			for (int j=2;j<=p[i];j+=2)
			{
				f[l][r]=1; l--; r++;
			}
		}
		if (i+p[i]-1>=mx)
		{
			mx=i+p[i]-1; id=i;
		}
	}
	for (int i=1;i<=tlen;i++)
		for (int j=i;j<=tlen;j++) sum+=f[i][j];
	printf("%d",sum); alr=1;
	memcpy(yuan,f,sizeof(f));
	for (int now=2;now<=tlen;now*=2)
	{
		sum=0;
		memset(tmp,0,sizeof(tmp));
		for (int i=1;i<=tlen;i++)
			for (int j=i+now-1;j<=tlen;j++)
			{
				int len=j-i+1;
				tmp[i][j]=yuan[i][j] & f[i][i+len/2-1] & f[j-len/2+1][j];
				sum+=tmp[i][j];
			}
		memcpy(f,tmp,sizeof(f));
		printf(" %d",sum);
		alr++;
	}
	alr++;
	for (alr;alr<=tlen;alr++)
	printf(" 0");
	printf("\n");
	return 0;
}


#include <fstream>
#include <string>
using namespace std;

ifstream cin("data.in");
ofstream cout("data.out");

string str;
int dp[5005][5005],k[5005];

int main()
{
    cin>>str;
    int n=str.length();
    for(int i=n-1; i>=0; i--)
    {
        dp[i][i]=1;
        if(str[i]==str[i-1]) dp[i-1][i]=2;

        for(int j=i+2; j<n; j++)
        {
            if(str[i]!=str[j] || !dp[i+1][j-1])
                dp[i][j]=0;
            else dp[i][j]=dp[i][(i+j-1)/2]+1;
        }
    }

    for(int i=0; i<n; i++)
    for(int j=i; j<n; j++)
        k[dp[i][j]]++;

    for(int i=n; i>=1; i--)
        k[i]+=k[i+1];

    for(int i=1; i<=n; i++)
        cout<<k[i]<<' ';

    return 0;
}


#include <iostream>
#include <string>
using namespace std;

string str;
int dp[5005][5005],k[5005];

int main()
{
    cin>>str;
    int n=str.length();
    for(int i=n-1; i>=0; i--)
    {
        dp[i][i]=1;
        if(str[i]==str[i-1]) dp[i-1][i]=2;

        for(int j=i+2; j<n; j++)
        {
            if(str[i]!=str[j] || !dp[i+1][j-1])
                dp[i][j]=0;
            else dp[i][j]=dp[i][(i+j-1)/2]+1;
        }
    }

    for(int i=0; i<n; i++)
    for(int j=i; j<n; j++)
        k[dp[i][j]]++;

    for(int i=n; i>=1; i--)
        k[i]+=k[i+1];

    for(int i=1; i<=n; i++)
        cout<<k[i]<<' ';

    return 0;
}


#include<iostream>
#include<stdio.h>
#include<string>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 5010;
#define LL long long
LL hashnum = 131;
int ans[maxn];
LL p[maxn];
LL S[maxn],RS[maxn];
int len;
char s1[maxn];
int dp[maxn][maxn];
void init()
{
    p[0]=1;
    for(int i=1;i<=5000;i++)
        p[i]=p[i-1]*hashnum;
}
LL RL(int l,int ll)
{
    ll++;
    return S[ll]-S[l]*p[ll-l];
}
LL RR(int rr,int r)
{
  r=len-r-1,rr=len-rr-1;
  rr++;
  return RS[rr]-RS[r]*p[rr-r];
}
int main()
{
    init();
    scanf("%s",s1);
    len=strlen(s1);
    for(int i=1;i<=len;i++) S[i]=S[i-1]*hashnum+s1[i-1];
    for(int i=1;i<=len;i++) RS[i]=RS[i-1]*hashnum+s1[len-i];
    for(int i=1;i<=len;i++)
    {
        for(int j=0;j<len;j++)
        {
            if(i==1) {dp[j][j]=1;continue;}
            int l=j,r=j+i-1;
            int ll,rr;
            if(i%2){ll=l+i/2-1,rr=l+i/2+1;}
            else {ll=l+i/2-1,rr=l+i/2;}
            if(RL(l,ll)==RR(rr,r))
                dp[l][r]=dp[l][ll]+1;
        }
    }
    for(int i=0;i<len;i++)
        for(int j=0;j<len;j++)
            if(dp[i][j]) ans[dp[i][j]]++;
    for(int i=len;i>=1;i--)
        ans[i-1]+=ans[i];
    for(int i=1;i<=len;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

#define LL long long
#define inf 1000000007

const int maxn = 5005;
char s[maxn];
int dp[maxn][maxn];
int num[maxn];
int main()
{
    scanf("%s",s);
    int slen=strlen(s);
    for(int i=0;i<slen;i++)
        dp[i][i]=1;
    for(int i=2;i<=slen;i++)
    {
        for(int j=0;j<slen;j++)
        {
            int bg=j,ed=j+i-1,l,r;
            if(ed>=slen) break;
            if(i%2) {l=bg+i/2-1;r=bg+i/2+1;}
            else {l=bg+i/2-1;r=bg+i/2;}
            if(dp[bg][l]==dp[r][ed]&&s[bg]==s[ed]&&s[l]==s[r])
              dp[bg][ed]=dp[bg][l]+1;
            else dp[bg][ed]=0;
        }
    }
    num[1]=slen;
    for(int i=0;i<slen;i++)
    {
        for(int j=i+1;j<slen;j++)
        {
            if((dp[i][j])){
            num[dp[i][j]]++;
            }
        }
    }
    for(int i=slen;i>=1;i--)
        num[i-1]+=num[i];
    for(int i=1;i<=slen;i++)
        printf("%d\n",num[i]);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

#define LL long long
#define inf 1000000007

const int maxn = 5005;
char s[maxn];
int dp[maxn][maxn];
int num[maxn];
int main()
{
    scanf("%s",s);
    int slen=strlen(s);
    for(int i=0;i<slen;i++)
        dp[i][i]=1;
    for(int i=2;i<=slen;i++)
    {
        for(int j=0;j<slen;j++)
        {
            int bg=j,ed=j+i-1,l,r;
            if(ed>=slen) break;
            if(i%2) {l=bg+i/2-1;r=bg+i/2+1;}
            else {l=bg+i/2-1;r=bg+i/2;}
            if(dp[bg][l]==dp[r][ed])
            {
                if(dp[bg][l]==0)
                {
                    int g=ed,flag=0;
                    for(int k=bg;k<=l;k++)
                    if(s[k]!=s[g--]){flag=1;break;}
                    if(!flag) dp[bg][ed]=1;
                }
                else if(dp[bg][l]&&s[l]==s[r])dp[bg][ed]=dp[bg][l]+1;
            }
        }
    }
    num[1]=slen;
    for(int i=0;i<slen;i++)
    {
        for(int j=i+1;j<slen;j++)
        {
            if(dp[i][j]){
            num[dp[i][j]]++;
            }
        }
    }
    for(int i=slen;i>=1;i--)
        num[i-1]+=num[i];
    for(int i=1;i<=slen;i++)
        printf("%d\n",num[i]);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

#define LL long long
#define inf 1000000007
const int maxn = 10005;
char s1[maxn],s2[maxn];
int p[maxn],ans[maxn];
int sum[maxn];
int k;
int first(char *s1,char *s2,int j)
{
    memset(s2,'\0',sizeof(s2));
   // cout<<s2<<endl;
    int len = 1;
    s2[0]='$';
    int i=j;
    while(i<=k)
    {
        s2[len++]='#';
        s2[len++]=s1[i++];
       // cout<<s2[len-1]<<endl;
    }
    s2[len++]='#';
    //cout<<s2<<endl;
    return len;
}

void Manacher(int *p,char *str,int len)
{
    memset(p,0,sizeof(p));
    int mx=0,id=0;
    for(int i=0;i<len;i++)
    {
        p[i]=mx>i?min(p[2*id-i],mx-i):1;
        while(str[i+p[i]]==str[i-p[i]]) p[i]++;
        if(i+p[i]>mx)
        {
            mx=i+p[i];
            id=i;
        }
    }
}
int main()
{
    scanf("%s",s1);
    k=strlen(s1);
    for(int i=0;i<k;i++)
    {
        int len=first(s1,s2,i);
        Manacher(p,s2,len);
        memset(sum,0,sizeof(sum));
        for(int i=2;i<len;i++)
        {
            if(p[i]==i)
            {
                sum[i]=sum[i-i/2]+1;
                ans[sum[i]]++;
            }
        }
    }
    for(int i=k;i>=1;i--)
        ans[i-1]+=ans[i];
    for(int i=1;i<=k;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

#define LL long long
#define inf 1000000007

const int maxn = 5005;
char s[maxn];
int dp[maxn][maxn];
int p[maxn][maxn];
int num[maxn];
int main()
{
    scanf("%s",s);
    int slen=strlen(s);
    for(int i=0;i<slen;i++)
        dp[i][i]=1;
    for(int i=0;i<slen;i++)
        p[i][i]=1;
    for(int i=2;i<=slen;i++)
    {
        for(int j=0;j<slen;j++)
        {
            int bg=j,ed=j+i-1;
            if(s[bg]==s[ed])
            {
                if(bg==(ed-1)) p[bg][ed]=1;
                else p[bg][ed]=p[bg+1][ed-1];
            }
        }
    }
    for(int i=2;i<=slen;i++)
    {
        for(int j=0;j<slen;j++)
        {
            int bg=j,ed=j+i-1,l,r;
            if(ed>=slen) break;
            if(i%2) {l=bg+i/2-1;r=bg+i/2+1;}
            else {l=bg+i/2-1;r=bg+i/2;}
            if(dp[bg][l]==dp[r][ed]&&p[bg][ed])
                dp[bg][ed]=dp[bg][l]+1;
        }
    }
    num[1]=slen;
    for(int i=0;i<slen;i++)
    {
        for(int j=i+1;j<slen;j++)
        {
            if(dp[i][j]){
            num[dp[i][j]]++;
            }
        }
    }
    for(int i=slen;i>=1;i--)
        num[i-1]+=num[i];
    for(int i=1;i<=slen;i++)
        printf("%d\n",num[i]);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

#define LL long long
#define inf 1000000007

const int maxn = 5005;
char s[maxn];
int dp[maxn][maxn];
int p[maxn][maxn];
int num[maxn];
int main()
{
    scanf("%s",s);
    int slen=strlen(s);
    for(int i=1;i<=slen;i++)//
    {
        for(int j=0;j<slen;j++)
        {
            int bg=j,ed=j+i-1;
            if(i==1) p[bg][ed]=1;
            else if(s[bg]==s[ed]){if(i==2)p[bg][ed]=1;else p[bg][ed]=p[bg+1][ed-1];}
        }
    }
    for(int len=1;len<=slen;len++)
    {
        for(int i=0;i<slen;i++)
        {
            int j=i+len-1;
            if(j>=slen) break;
            int mid=i+(j-i+1)/2-1;
            if(p[i][j])
                dp[i][j]=dp[i][mid]+1;
        }
    }
    num[1]=slen;
    for(int i=0;i<slen;i++)
        for(int j=i+1;j<slen;j++)
            if(dp[i][j]) num[dp[i][j]]++;
    for(int i=slen;i>=1;i--)
        num[i-1]+=num[i];
    for(int i=1;i<=slen;i++)
        printf("%d\n",num[i]);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

#define LL long long
#define inf 1000000007

const int maxn = 5005;
char s[maxn];
int dp[maxn][maxn];
int num[maxn];
int main()
{
    scanf("%s",s);
    int slen=strlen(s);
    for(int i=0;i<slen;i++)
        dp[i][i]=1;
    for(int i=2;i<=slen;i++)
    {
        for(int j=0;j<slen;j++)
        {
            int bg=j,ed=j+i-1,l,r;
            if(ed>=slen) break;
            if(i%2) {l=bg+i/2-1;r=bg+i/2+1;}
            else {l=bg+i/2-1;r=bg+i/2;}
            if(dp[bg][l]==dp[r][ed])
            {
                int g=ed,flag=0;
                for(int k=bg;k<=l;k++)
                if(s[k]!=s[g--]){flag=1;break;}
                if(!flag) dp[bg][ed]=dp[bg][l]+1;
            }
        }
    }
    num[1]=slen;
    for(int i=0;i<slen;i++)
    {
        for(int j=i+1;j<slen;j++)
        {
            if(dp[i][j]){
            num[dp[i][j]]++;
            }
        }
    }
    for(int i=slen;i>=1;i--)
        num[i-1]+=num[i];
    for(int i=1;i<=slen;i++)
        printf("%d\n",num[i]);
    return 0;
}


#include <bits/stdc++.h>
#define mod 1000000007
#define N 5050

using namespace std;
typedef long long LL;
inline int rd() {
	int x=0,f=1;char ch=getchar();
	while (ch>'9'||ch<'0') {if(ch=='-')f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}

bool vis[N][N],ok[N][N];
int sum[N],n;
short dp[N][N];
int hash[N][N], e[N];
char s[N];

short F(int l,int r) {
	if (vis[l][r]) return dp[l][r];
	vis[l][r] = 1;
	short ret = ok[l][r];
	if (l == r) {
		hash[l][r] = s[l]-'a'+1;
		dp[l][r] = 1;
		return 1;
	}

	int h = (r-l+1) >> 1;

	short p1 = F(l,l+h-1);
	short p2 = F(r-h+1,r);

	if (hash[l][l+h-1] == hash[r-h+1][r] && p1 == p2) ret = max(ret, (short)(p1+1));
	return dp[l][r] = ret;
}

int main() {
	scanf("%s",s+1); n = strlen(s+1);
	e[0] = 1;
	for (int i=1;i<=n;i++) e[i] = 1LL * e[i-1] * 26 % mod;

	for (int j=1;j<=n;j++)
		for (int i=1;i+j-1<=n;i++) {
			int x = i+j-1;
			if (i==x) ok[i][x] = 1; else {
				if (i+1 == x) ok[i][x] = s[i]==s[x]; else {
					if (s[i] == s[x]) ok[i][x] = ok[i+1][x-1];
				}
			}
		}

	for (int j=1;j<=n;j++)
		for (int i=1;i+j-1<=n;i++) {
			int x = i+j-1;
			hash[i][x] = 1LL * hash[i][x-1] * 26 % mod + (s[x]-'a'+1);
			hash[i][x] %= mod;
		}

	for (int i=1;i<=n;i++)
		for (int j=i;j<=n;j++)
			sum[ F(i,j) ]++;
	for (int i=n;i>=1;i--) sum[i] += sum[i+1];
	for (int i=1;i<=n;i++) printf("%d%c",sum[i],i==n?'\n':' ');
	return 0;
}


#include <bits/stdc++.h>
#define mod 1000000007
#define N 5050

using namespace std;
typedef long long LL;
inline int rd() {
	int x=0,f=1;char ch=getchar();
	while (ch>'9'||ch<'0') {if(ch=='-')f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}

bool vis[N][N],ok[N][N];
int sum[N],n;
short dp[N][N];
int hash[N][N], e[N];
char s[N];

short F(int l,int r) {
	if (vis[l][r]) return dp[l][r];
	vis[l][r] = 1;
	short ret = ok[l][r];
	if (l == r) {
		hash[l][r] = s[l]-'a'+1;
		dp[l][r] = 1;
		return 1;
	}

	int h = (r-l+1) >> 1;

	short p1 = F(l,l+h-1);
	short p2 = F(r-h+1,r);
	if ((r-l+1) % 2 == 0) {
		hash[l][r] = hash[l][l+h-1] + 1LL * hash[r-h+1][r] * e[h] % mod;
	} else {
		hash[l][r] = hash[l][l+h-1] + 1LL * (s[l+h-1]-'a'+1) * e[h] % mod + 1LL * hash[r-h+1][r] * e[h+1] % mod;
	}

	if (hash[l][l+h-1] == hash[r-h+1][r] && p1 == p2) ret = max(ret, (short)(p1+1));
	return dp[l][r] = ret;
}

int main() {
	scanf("%s",s+1); n = strlen(s+1);
	e[0] = 1;
	for (int i=1;i<=n;i++) e[i] = 1LL * e[i-1] * 26 % mod;

	for (int j=1;j<=n;j++)
		for (int i=1;i+j-1<=n;i++) {
			int x = i+j-1;
			if (i==x) ok[i][x] = 1; else {
				if (i+1 == x) ok[i][x] = s[i]==s[x]; else {
					if (s[i] == s[x]) ok[i][x] = ok[i+1][x-1];
				}
			}
		}

	for (int i=1;i<=n;i++)
		for (int j=i;j<=n;j++)
			sum[ F(i,j) ]++;
	for (int i=n;i>=1;i--) sum[i] += sum[i+1];
	for (int i=1;i<=n;i++) printf("%d%c",sum[i],i==n?'\n':' ');
	return 0;
}


#include <bits/stdc++.h>
#define N 5050

using namespace std;
typedef unsigned long long uLL;
inline int rd() {
	int x=0,f=1;char ch=getchar();
	while (ch>'9'||ch<'0') {if(ch=='-')f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}

bool vis[N][N],ok[N][N];
int dp[N][N],sum[N],n;
uLL hash[N][N], e[N];
char s[N];

int F(int l,int r) {
	if (vis[l][r]) return dp[l][r];
	vis[l][r] = 1;
	int ret = ok[l][r];
	if (l == r) {
		hash[l][r] = s[l]-'a'+1;
		dp[l][r] = 1;
		return 1;
	}

	int h = (r-l+1) >> 1;

	int p1 = F(l,l+h-1);
	int p2 = F(r-h+1,r);
	if ((r-l+1) % 2 == 0) {
		hash[l][r] = hash[l][l+h-1] + hash[r-h+1][r] * e[h];
	} else {
		hash[l][r] = hash[l][l+h-1] + (s[l+h-1]-'a'+1) * e[h] + hash[r-h+1][r] * e[h+1];
	}

	if (hash[l][l+h-1] == hash[r-h+1][r] && p1 == p2) ret = max(ret, p1+1);
	return dp[l][r] = ret;
}

int main() {
	scanf("%s",s+1); n = strlen(s+1);
	e[0] = 1;
	for (int i=1;i<=n;i++) e[i] = (uLL)e[i-1] * (uLL)26;

	for (int j=1;j<=n;j++)
		for (int i=1;i+j-1<=n;i++) {
			int x = i+j-1;
			if (i==x) ok[i][x] = 1; else {
				if (i+1 == x) ok[i][x] = s[i]==s[x]; else {
					if (s[i] == s[x]) ok[i][x] = ok[i+1][x-1];
				}
			}
		}

	for (int i=1;i<=n;i++)
		for (int j=i;j<=n;j++)
			sum[ F(i,j) ]++;
	for (int i=n;i>=1;i--) sum[i] += sum[i+1];
	for (int i=1;i<=n;i++) printf("%d%c",sum[i],i==n?'\n':' ');
	return 0;
}


#include <bits/stdc++.h>
#define mod 1000000007
#define N 5050

using namespace std;
typedef long long LL;
inline int rd() {
	int x=0,f=1;char ch=getchar();
	while (ch>'9'||ch<'0') {if(ch=='-')f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}

bool vis[N][N],ok[N][N];
int sum[N],n;
short dp[N][N];
int hash[N][N];
char s[N];

short F(int l,int r) {
	if (vis[l][r]) return dp[l][r];
	vis[l][r] = 1;
	short ret = ok[l][r] ? 1 : -n;
	if (l == r) {
		hash[l][r] = s[l]-'a'+1;
		dp[l][r] = 1;
		return 1;
	}

	int h = (r-l+1) >> 1;

	short p1 = F(l,l+h-1);
	short p2 = F(r-h+1,r);

	if (hash[l][l+h-1] == hash[r-h+1][r] && p1 == p2) ret = max(ret, (short)(p1+1));
	return dp[l][r] = ret;
}

int main() {
	scanf("%s",s+1); n = strlen(s+1);

	for (int j=1;j<=n;j++)
		for (int i=1;i+j-1<=n;i++) {
			int x = i+j-1;
			if (i==x) ok[i][x] = 1; else {
				if (i+1 == x) ok[i][x] = s[i]==s[x]; else {
					if (s[i] == s[x]) ok[i][x] = ok[i+1][x-1];
				}
			}
		}

	for (int j=1;j<=n;j++)
		for (int i=1;i+j-1<=n;i++) {
			int x = i+j-1;
			hash[i][x] = 1LL * hash[i][x-1] * 26 % mod + (s[x]-'a'+1);
			hash[i][x] %= mod;
		}

	for (int i=1;i<=n;i++)
		for (int j=i;j<=n;j++) if (F(i, j)>0)
			sum[ F(i,j) ]++;
	for (int i=n;i>=1;i--) sum[i] += sum[i+1];
	for (int i=1;i<=n;i++) printf("%d%c",sum[i],i==n?'\n':' ');
	return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;
char s[10000];
int dp[6000][6000]={0},t,ans[6000];
int	dfs(int i,int j)
{
	int k;
	if(dp[i][j])
		return dp[i][j];
	if(dp[i+1][j-1]&&s[i]==s[j]&&j-i>1)
	{
		dp[i][j]=dfs(i,i+(j-i+1)/2-1)+1;
		dp[i][j]=dfs(j-(j-i+1)/2+1,j)+1;
	}
	else if(j-i==1&&s[i]==s[j])
	{
		dp[i][j]=2;
	}
	return dp[i][j];
}
int main()
{
	memset(dp,0,sizeof(dp));
	memset(ans,0,sizeof(dp));
	scanf("%s",s);
	t=strlen(s);
	for(int i=0;i<t;i++)
		dp[i][i]=1;
	for(int i=1;i<=t;i++)
	{
		for(int j=0;j+i-1<t;j++)
		{
			int k=dfs(j,j+i-1);
			ans[k]++;
		}
	}
	for(int i=t-1;i>=1;i--)
	{
		ans[i]+=ans[i+1];
	}
	printf("%d",ans[1]);
	for(int i=2;i<=t;i++)
		printf(" %d",ans[i]);
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;
char s[10000];
int dp[6000][6000]={0},t,ans[40];
int	dfs(int i,int j)
{
	int k;
	if(dp[i][j])
		return dp[i][j];
	if(dp[i+1][j-1]&&s[i]==s[j]&&j-i>1)
	{
		dp[i][j]=dfs(i,i+(j-i+1)/2-1)+1;
		dp[i][j]=dfs(j-(j-i+1)/2+1,j)+1;
	}
	else if(j-i==1&&s[i]==s[j])
	{
		dp[i][j]=2;
	}
	return dp[i][j];
}
int main()
{
	memset(dp,0,sizeof(dp));
	scanf("%s",s);
	t=strlen(s);
	for(int i=0;i<t;i++)
		dp[i][i]=1;
	for(int i=1;i<=t;i++)
	{
		for(int j=0;j+i-1<t;j++)
		{
			int k=dfs(j,j+i-1);
			ans[k]++;
		}
	}
	for(int i=t-1;i>=1;i--)
	{
		ans[i]+=ans[i+1];
	}
	printf("%d",ans[1]);
	for(int i=2;i<=t;i++)
		printf(" %d",ans[i]);
	printf("\n");
	return 0;
}


#include <cstdio>
#include <cstring>
#define N 5010
char s[N];
int dp[N][N],ans[N],n;
int main(){
//  freopen("a.in","r",stdin);
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=1;i<=n;++i) dp[i][i]=1,ans[1]++;
    for(int len=2;len<=n;++len)
        for(int i=1;i+len-1<=n;++i){
            int j=i+len-1;
            if(s[i]!=s[j]||i+1<=j-1&&dp[i+1][j-1]==0) dp[i][j]=0;
            else dp[i][j]=dp[i][i+len/2-1]+1;
            if(dp[i][j]) ans[dp[i][j]]++;
        }
    for(int i=n;i>=1;--i) ans[i]+=ans[i+1];
    for(int i=1;i<=n;++i) printf("%d ",ans[i]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 5500
using namespace std;

int dp[maxn][maxn],ans[maxn];

int main()
{
   char s[maxn];
   while(~scanf("%s",s+1))
   {
       memset(ans,0,sizeof(ans));
        int slen=strlen(s+1);
        if (slen==1)
            {printf("1\n");continue;}

        for (int k=1;k<=slen;k++)
        {
            dp[k][k]=1;
            ans[1]++;
        }

        for (int len=2;len<=slen;len++)
            for (int l=1;l<=slen;l++)
        {
            int r=l+len-1;
            if (r>slen) break;

            if(s[l]!=s[r]||(l+1<=r-1&&dp[l+1][r-1]==0))
                dp[l][r]=0;
            else
                dp[l][r]=dp[l][l+len/2-1]+1;

            if(dp[l][r]) ans[dp[l][r]]++;
        }

        for(int i=slen;i>=1;i--)
            ans[i]+=ans[i+1];
        printf("%d",ans[1]);
        for (int k=2;k<=slen;k++)
            printf(" %d",ans[k]);
        printf("\n");
   }
   return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<char> vc;
typedef pair<int, int> pi;
const int mod = 1e9 + 7;
const double EPS = 1e-9;
const int INF = 1 << 29;
#define mp make_pair
#define el putchar('\n')
#define sp putchar(' ')
#define Fill(a,val) memset(a,val,sizeof a)
#define all(a) a.begin(),a.end()
#ifndef ONLINE_JUDGE
#define tr(a, it) for (decltype(a.begin()) it = a.begin(); it != a.end(); ++it)
#else
#define tr(a, it) for (typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#endif
#define in(n) scanf("%d",&n)
#define inl(n) scanf("%I64d",&n)
#define out(n) printf("%d",n);
#define outl(n) printf("%I64d",n);

int const NN = 5e3 + 5;
bool dp[NN][NN][14];
map<int, int>mm;

struct entry
{
	int nr[2];
	int p;
} L[NN];

int P[14][NN];

int cmp(entry a, entry b){
	return a.nr[0] == b.nr[0] ? a.nr[1] < b.nr[1] : a.nr[0] < b.nr[0];
}

int lcp(int x, int y, int n, int stp){//O(logn)
	int ret = 0;
	if (x == y) return n - x;
	for (int k = stp - 1; k >= 0 && x < n && y < n; k--){
		if (P[k][x] == P[k][y]){
			x += 1 << k, y += 1 << k, ret += 1 << k;
		}
	}
	return ret;
}

int main(){
	string s; cin >> s;
	int n = s.length();

	for (int i = 0; i < n; ++i){
		P[0][i] = s[i] - 'a';
	}
	int stp, cnt;
	for (stp = 1, cnt = 1; cnt < n; ++stp, cnt <<= 1){
		for (int i = 0; i < n; ++i){
			L[i].nr[0] = P[stp - 1][i];
			L[i].nr[1] = ((i + cnt) < n ? P[stp - 1][i + cnt] : -1);
			L[i].p = i;
		}
		sort(L, L + n, cmp);
		for (int i = 0; i < n; ++i){
			P[stp][L[i].p] = i > 0 && L[i].nr[0] == L[i - 1].nr[0]
				&& L[i].nr[1] == L[i - 1].nr[1] ? P[stp][L[i - 1].p] : i;
		}
	}

	for (int len = 1; len <= n; ++len){
		for (int i = 0; i + len - 1 < n; ++i){
			if (len == 1){
				dp[i][i][1] = true;
				continue;
			}
			if (len == 2){
				dp[i][i + 1][1] = (s[i] == s[i + 1]);
				continue;
			}
			int j = i + len - 1;
			dp[i][j][1] = (s[i] == s[j] && dp[i + 1][j - 1][1]);
		}
	}
	for (int k = 2; k <= 13; ++k){
		for (int i = 0; i < n; ++i){
			for (int j = i; j < n; ++j){
				int len = (j - i + 1); len >>= 1;
				dp[i][j][k] = dp[i][i + len - 1][k - 1] &&
					dp[j - len + 1][j][k - 1] &&
					(lcp(i, j - len + 1, n, stp) >= len);
			}
		}
	}
	for (int i = 0; i < n; ++i){
		for (int j = 0; j < n; ++j){
			for (int k = 1; k <= 13; ++k){
				if (dp[i][j][k])++mm[k];
			}
		}
	}
	for (int i = 0; i < n; ++i){
		int k = i + 1;
		out(mm[k]); sp;
	}el;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<char> vc;
typedef pair<int, int> pi;
const int mod = 1e9 + 7;
const double EPS = 1e-9;
const int INF = 1 << 29;
#define mp make_pair
#define el putchar('\n')
#define sp putchar(' ')
#define Fill(a,val) memset(a,val,sizeof a)
#define all(a) a.begin(),a.end()
#ifndef ONLINE_JUDGE
#define tr(a, it) for (decltype(a.begin()) it = a.begin(); it != a.end(); ++it)
#else
#define tr(a, it) for (typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#endif
#define in(n) scanf("%d",&n)
#define inl(n) scanf("%I64d",&n)
#define out(n) printf("%d",n);
#define outl(n) printf("%I64d",n);

int const NN = 5e3 + 3;
bool dp[NN][NN][2];
bool pal[NN][NN];
int ans[NN];

int main(){
	string s; cin >> s;
	int n = s.length();
	for (int i = 0; i < n; ++i)pal[i][i] = true;
	for (int i = 0; i + 1 < n; ++i)pal[i][i + 1] = (s[i] == s[i + 1]);
	for (int len = 3; len <= n; ++len){
		for (int i = 0; i + len - 1 < n; ++i){
			int j = i + len - 1;
			pal[i][j] = pal[i + 1][j - 1] && s[i] == s[j];
		}
	}
	for (int i = 0; i < n; ++i){
		for (int j = i; j < n; ++j)
			dp[i][j][0] = pal[i][j], ans[1] += dp[i][j][0];
	}
	for (int k = 2; k <= 13; ++k){
		for (int len = 1<<(k-1); len <= n; ++len){
			for (int i = 0; i + len - 1 < n; ++i){
				int j = i + len - 1;
				dp[i][j][1] = dp[i][i + len / 2 - 1][0] && pal[i][j];
				ans[k] += dp[i][j][1];
			}
		}
		for (int i = 0; i < n; ++i){
			for (int j = 0; j < n; ++j)
				dp[i][j][0] = dp[i][j][1];
		}
	}
	for (int i = 1; i <= n; ++i){
		out(ans[i]); sp;
	}el;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<char> vc;
typedef pair<int, int> pi;
const int mod = 1e9 + 7;
const double EPS = 1e-9;
const int INF = 1 << 29;
#define mp make_pair
#define el putchar('\n')
#define sp putchar(' ')
#define Fill(a,val) memset(a,val,sizeof a)
#define all(a) a.begin(),a.end()
#ifndef ONLINE_JUDGE
#define tr(a, it) for (decltype(a.begin()) it = a.begin(); it != a.end(); ++it)
#else
#define tr(a, it) for (typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#endif
#define in(n) scanf("%d",&n)
#define inl(n) scanf("%I64d",&n)
#define out(n) printf("%d",n);
#define outl(n) printf("%I64d",n);

int const NN = 5e3 + 3;
bool dp[NN][NN][2];
bool pal[NN][NN];
int ans[NN];

int main(){
	string s; cin >> s;
	int n = s.length();
	for (int i = 0; i < n; ++i)pal[i][i] = true;
	for (int i = 0; i + 1 < n; ++i)pal[i][i + 1] = (s[i] == s[i + 1]);
	for (int len = 3; len <= n; ++len){
		for (int i = 0; i + len - 1 < n; ++i){
			int j = i + len - 1;
			pal[i][j] = pal[i + 1][j - 1] && s[i] == s[j];
		}
	}
	for (int i = 0; i < n; ++i){
		for (int j = i; j < n; ++j)
			dp[i][j][0] = pal[i][j], ans[1] += dp[i][j][0];
	}
	for (int k = 2; k <= 13; ++k){
		for (int len = 2; len <= n; ++len){
			for (int i = 0; i + len - 1 < n; ++i){
				int j = i + len - 1;
				dp[i][j][1] = dp[i][i + len / 2 - 1][0] && pal[i][j];
			}
		}
		for (int i = 0; i < n; ++i){
			for (int j = 0; j < n; ++j)
				dp[i][j][0] = dp[i][j][1], ans[k] += dp[i][j][0];
		}
	}
	for (int i = 1; i <= n; ++i){
		out(ans[i]); sp;
	}el;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;

typedef long long LL;

const int N=5005;
const int MOD=1000000007;
const int P=2333333;

int n,ans[N],len[N*2],a[N*2],hash[N][N],w[P],tot[P];
char s[N];

void ins(int x)
{
	int now=x%P;
	while (w[now]>0&&w[now]!=x) now=(now+1)%P;
	w[now]=x;tot[now]++;
}

int query(int x)
{
	int now=x%P;
	while (w[now]>0&&w[now]!=x) now=(now+1)%P;
	return now;
}

int work(int l,int r)
{
	if (l>r||hash[l][r]!=hash[r][l]) return 0;
	int len=(r-l+1)/2;
	return work(l,l+len-1)+1;
}

void solve(int l,int r)
{
	if (!tot[query(hash[l][r])]) return;
	int k=work(l,r),e=query(hash[l][r]);
	ans[k]+=tot[e];tot[e]=0;
}

void manachar()
{
	for (int i=1;i<=n;i++) a[i*2]=s[i]-'a',a[i*2-1]=30;
	a[n*2+1]=30;
	int mx=0,po=0;
	for (int i=1;i<=n*2+1;i++)
	{
		if (mx>i) len[i]=min(mx-i+1,len[po*2-i]);
        else len[i]=1;
        while (i+len[i]<=n*2+1&&i-len[i]>=1&&a[i+len[i]]==a[i-len[i]])
		{
			len[i]++;
			if (i+len[i]-1>mx)
			{
				if (a[i]==30) solve(i/2-len[i]/2+1,i/2+len[i]/2);
				else solve(i/2-len[i]/2+1,i/2+len[i]/2-1);
				mx=i+len[i]-1;po=i;
			}
		}
	}
}

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int i=1;i<=n;i++)
	{
		int now=0;
		for (int j=i;j<=n;j++)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
			ins(now);
		}
	}
	for (int i=n;i>=1;i--)
	{
		int now=0;
		for (int j=i;j>=1;j--)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
		}
	}
	manachar();
	for (int i=n;i>=1;i--) ans[i]+=ans[i+1];
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;

typedef long long LL;

const int N=5005;

int n,ans[N],hash[N][N],f[N][N];
char s[N];
bool vis[N][N];

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int i=1;i<=n;i++) vis[i][i]=vis[i][i-1]=1;
	for (int l=1;l<n;l++)
		for (int i=1;i+l<=n;i++)
		{
			int j=i+l;
			vis[i][j]=(s[i]==s[j]&&vis[i+1][j-1]);
		}
	for (int i=1;i<=n;i++) f[i][i]=1;
	for (int l=1;l<n;l++)
		for (int i=1;i+l<=n;i++)
		{
			int j=i+l;
			if (!vis[i][j]) continue;
			int len=(j-i+1)/2;
			f[i][j]=f[i][i+len-1]+1;
		}
	for (int i=1;i<=n;i++)
		for (int j=i;j<=n;j++)
			ans[f[i][j]]++;
	for (int i=n;i>=1;i--) ans[i]+=ans[i+1];
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;

typedef long long LL;

const int N=5005;
const int MOD=1000000007;

int n,ans[N],hash[N][N],f[N][N];
char s[N];

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int i=1;i<=n;i++)
	{
		int now=0;
		for (int j=i;j<=n;j++)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
		}
	}
	for (int i=n;i>=1;i--)
	{
		int now=0;
		for (int j=i;j>=1;j--)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
		}
	}
	for (int i=1;i<=n;i++) f[i][i]=1;
	for (int l=1;l<n;l++)
		for (int i=1;i+l<=n;i++)
		{
			int j=i+l;
			if (hash[i][j]!=hash[j][i]) continue;
			int len=(j-i+1)/2;
			f[i][j]=f[i][i+len-1]+1;
		}
	for (int i=1;i<=n;i++)
		for (int j=i;j<=n;j++)
			ans[f[i][j]]++;
	for (int i=n;i>=1;i--) ans[i]+=ans[i+1];
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;

typedef long long LL;

const int N=5005;
const int MOD=1000000007;
const int P=7333333;

int n,ans[N],len[N*2],a[N*2],hash[N][N],w[P],tot[P];
char s[N];

void ins(int x)
{
	int now=x%P;
	while (w[now]>0&&w[now]!=x) now=(now+1)%P;
	w[now]=x;tot[now]++;
}

int query(int x)
{
	int now=x%P;
	while (w[now]>0&&w[now]!=x) now=(now+1)%P;
	return now;
}

int work(int l,int r)
{
	if (l>r||hash[l][r]!=hash[r][l]) return 0;
	int len=(r-l+1)/2;
	return work(l,l+len-1)+1;
}

void solve(int l,int r)
{
	if (!tot[query(hash[l][r])]) return;
	int k=work(l,r),e=query(hash[l][r]);
	ans[k]+=tot[e];tot[e]=0;
}

void manachar()
{
	for (int i=1;i<=n;i++) a[i*2]=s[i]-'a',a[i*2-1]=30;
	a[n*2+1]=30;
	int mx=0,po=0;
	for (int i=1;i<=n*2+1;i++)
	{
		if (mx>i) len[i]=min(mx-i+1,len[po*2-i]);
        else len[i]=1;
        while (i+len[i]<=n*2+1&&i-len[i]>=1&&a[i+len[i]]==a[i-len[i]])
		{
			len[i]++;
			if (i+len[i]-1>mx)
			{
				if (a[i]==30) solve(i/2-len[i]/2+1,i/2+len[i]/2);
				else solve(i/2-len[i]/2+1,i/2+len[i]/2-1);
			}
		}
        if (i+len[i]-1>mx) mx=i+len[i]-1,po=i;
	}
}

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int i=1;i<=n;i++)
	{
		int now=0;
		for (int j=i;j<=n;j++)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
			ins(now);
		}
	}
	for (int i=n;i>=1;i--)
	{
		int now=0;
		for (int j=i;j>=1;j--)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
		}
	}
	manachar();
	for (int i=n;i>=1;i--) ans[i]+=ans[i+1];
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;

typedef long long LL;

const int N=5005;
const int MOD=1000000007;

map<int,int> tong;
int n,ans[N],len[N*2],a[N*2],hash[N][N];
char s[N];

int work(int l,int r)
{
	if (l>r||hash[l][r]!=hash[r][l]) return 0;
	int len=(r-l+1)/2;
	return work(l,l+len-1)+1;
}

void solve(int l,int r)
{
	int k=work(l,r);
	ans[k]+=tong[hash[l][r]];tong[hash[l][r]]=0;
}

void manachar()
{
	for (int i=1;i<=n;i++) a[i*2]=s[i]-'a',a[i*2-1]=30;
	a[n*2+1]=30;
	int mx=0,po=0;
	for (int i=1;i<=n*2+1;i++)
	{
		if (mx>i) len[i]=min(mx-i+1,len[po*2-i]);
        else len[i]=1;
        while (i+len[i]<=n*2+1&&i-len[i]>=1&&a[i+len[i]]==a[i-len[i]])
		{
			len[i]++;
			if (i+len[i]-1>mx)
			{
				if (a[i]==30) solve(i/2-len[i]/2+1,i/2+len[i]/2);
				else solve(i/2-len[i]/2+1,i/2+len[i]/2-1);
			}
		}
        if (i+len[i]-1>mx) mx=i+len[i]-1,po=i;
	}
}

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int i=1;i<=n;i++)
	{
		int now=0;
		for (int j=i;j<=n;j++)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
			tong[now]++;
		}
	}
	for (int i=n;i>=1;i--)
	{
		int now=0;
		for (int j=i;j>=1;j--)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
		}
	}
	manachar();
	for (int i=n;i>=1;i--) ans[i]+=ans[i+1];
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;

typedef long long LL;

const int N=5005;
const int MOD=1000000007;
const int P=2333333;

int n,ans[N],len[N*2],a[N*2],hash[N][N],w[P],tot[P];
char s[N];

void ins(int x)
{
	int now=x%P;
	while (w[now]>0&&w[now]!=x) now=(now+1)%P;
	w[now]=x;tot[now]++;
}

int query(int x)
{
	int now=x%P;
	while (w[now]>0&&w[now]!=x) now=(now+1)%P;
	return now;
}

int work(int l,int r)
{
	if (l>r||hash[l][r]!=hash[r][l]) return 0;
	int len=(r-l+1)/2;
	return work(l,l+len-1)+1;
}

void solve(int l,int r)
{
	int k=work(l,r),e=query(hash[l][r]);
	ans[k]+=tot[e];tot[e]=0;
}

void manachar()
{
	for (int i=1;i<=n;i++) a[i*2]=s[i]-'a',a[i*2-1]=30;
	a[n*2+1]=30;
	int mx=0,po=0;
	for (int i=1;i<=n*2+1;i++)
	{
		if (mx>i) len[i]=min(mx-i+1,len[po*2-i]);
        else len[i]=1;
        while (i+len[i]<=n*2+1&&i-len[i]>=1&&a[i+len[i]]==a[i-len[i]])
		{
			len[i]++;
			if (i+len[i]-1>mx)
			{
				if (a[i]==30) solve(i/2-len[i]/2+1,i/2+len[i]/2);
				else solve(i/2-len[i]/2+1,i/2+len[i]/2-1);
			}
		}
        if (i+len[i]-1>mx) mx=i+len[i]-1,po=i;
	}
}

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int i=1;i<=n;i++)
	{
		int now=0;
		for (int j=i;j<=n;j++)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
			ins(now);
		}
	}
	for (int i=n;i>=1;i--)
	{
		int now=0;
		for (int j=i;j>=1;j--)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
		}
	}
	manachar();
	for (int i=n;i>=1;i--) ans[i]+=ans[i+1];
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;

typedef long long LL;

const int N=5005;
const int MOD=1000000007;
const int P=2333333;

int n,ans[N],len[N*2],a[N*2],hash[N][N],w[P],tot[P];
char s[N];

void ins(int x)
{
	int now=x%P;
	while (w[now]>0&&w[now]!=x) now=(now+1)%P;
	w[now]=x;tot[now]++;
}

int query(int x)
{
	int now=x%P;
	while (w[now]>0&&w[now]!=x) now=(now+1)%P;
	return now;
}

int work(int l,int r)
{
	if (l>r||hash[l][r]!=hash[r][l]) return 0;
	int len=(r-l+1)/2;
	return work(l,l+len-1)+1;
}

void solve(int l,int r)
{
	int e=query(hash[l][r]);;
	if (!tot[e]) return;
	int k=work(l,r);
	ans[k]+=tot[e];tot[e]=0;
}

void manachar()
{
	for (int i=1;i<=n;i++) a[i*2]=s[i]-'a',a[i*2-1]=30;
	a[n*2+1]=30;
	int mx=0,po=0;
	for (int i=1;i<=n*2+1;i++)
	{
		if (mx>i) len[i]=min(mx-i+1,len[po*2-i]);
        else len[i]=1;
        while (i+len[i]<=n*2+1&&i-len[i]>=1&&a[i+len[i]]==a[i-len[i]])
		{
			len[i]++;
			if (i+len[i]-1>mx)
			{
				if (a[i]==30) solve(i/2-len[i]/2+1,i/2+len[i]/2);
				else solve(i/2-len[i]/2+1,i/2+len[i]/2-1);
				mx=i+len[i]-1;po=i;
			}
		}
        if (i+len[i]-1>mx)
		{
			if (a[i]==30) solve(i/2-len[i]/2+1,i/2+len[i]/2);
			else solve(i/2-len[i]/2+1,i/2+len[i]/2-1);
			mx=i+len[i]-1,po=i;
		}
	}
}

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int i=1;i<=n;i++)
	{
		int now=0;
		for (int j=i;j<=n;j++)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
			ins(now);
		}
	}
	for (int i=n;i>=1;i--)
	{
		int now=0;
		for (int j=i;j>=1;j--)
		{
			now=((LL)now*27%MOD+s[j]-'a'+1)%MOD;
			hash[i][j]=now;
		}
	}
	manachar();
	for (int i=n;i>=1;i--) ans[i]+=ans[i+1];
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
const int INF = 1e9 + 7;
const int Maxn = 5111;
const int L = 37;
const int MOD = 999983;
const int MOD2 = 100000007;
int n;
int sum[Maxn], rsum[Maxn], sum2[Maxn], rsum2[Maxn], pw[Maxn], pw2[Maxn], f[Maxn][Maxn], vis[Maxn][Maxn];
char s[Maxn], rs[Maxn];
struct HASH{
	struct node{int x, y, v2; string s;};
	vector<node> h[MOD];
	void push(int v, int x, int y, int v2){
		v = (v + MOD) % MOD, v2 = (v2 + MOD2) % MOD2;
		h[v].pb((node){x, y, v2});
	}
}h;
struct BIT{
	int tr[Maxn];
	void modify(int x, int k){for (; x < Maxn; x += x & -x) tr[x] += k;}
	int query(int x){int ans = 0;for (; x; x -= x & -x) ans += tr[x]; return ans;}
} tr;

int main(){
	scanf("%s", s + 1); n = strlen(s + 1);
	strcat(rs + 1, s + 1), reverse(rs + 1, rs + n + 1);
	rep(i, 1, n) sum[i] = (1ll * sum[i-1] * L + s[i] - 'a') % MOD;
	rep(i, 1, n) rsum[i] = (1ll * rsum[i-1] * L + rs[i] - 'a') % MOD;
	pw[0] = 1; rep(i, 1, n) pw[i] = 1ll * pw[i-1] * L % MOD;
	rep(i, 1, n) sum2[i] = (1ll * sum2[i-1] * L + s[i] - 'a') % MOD2;
	rep(i, 1, n) rsum2[i] = (1ll * rsum2[i-1] * L + rs[i] - 'a') % MOD2;
	pw2[0] = 1; rep(i, 1, n) pw2[i] = 1ll * pw2[i-1] * L % MOD2;
	rep(i, 1, n) rep(j, i, n)
		h.push(rsum[j] - (ll)rsum[i-1] * pw[j-i+1] % MOD, i, j, rsum2[j] - (ll)rsum2[i-1] * pw2[j-i+1] % MOD2);
	rep(i, 1, n) rep(j, i, n){
		int v = (sum[j] - (ll)sum[i-1] * pw[j-i+1] % MOD + MOD) % MOD;
		int v2 = (sum2[j] - (ll)sum2[i-1] * pw2[j-i+1] % MOD2 + MOD2) % MOD2;
		for (int p = 0; p < h.h[v].size(); ++p) if (h.h[v][p].v2 == v2){
			if (h.h[v][p].x + j == n + 1&&h.h[v][p].y + i == n + 1)
				{f[i][j] = 1; break;}
		}
	}
	rep(len, 2, n) rep(i, 1, n - len + 1){
		int mid = i + (len % 2 ? len / 2 : len / 2 - 1);
		if (!f[i][i+len-1]) continue;
		if (len % 2) f[i][i+len-1] = max(f[i][mid-1], f[mid+1][i+len-1]) + 1;
		else f[i][i+len-1] = max(f[i][mid], f[mid+1][i+len-1]) + 1;
	}
//	rep(i, 1, n) {rep(j, 1, n) printf("%d ", f[i][j]); puts("");}
	rep(i, 1, n) rep(j, i, n) tr.modify(1, 1), tr.modify(f[i][j] + 1, -1);
	rep(i, 1, n) printf("%d%c", tr.query(i), " \n"[i == n]);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
const int INF = 1e9 + 7;
const int N = 5111;
const ll K = 31;
int n;
int f[N][N], ans[N];
ll hs[N], hs2[N], po[N];
char s[N];

ll get(int l, int r){return hs[r] - hs[l-1] * po[r-l+1];}
ll get2(int l, int r){return hs2[r] - hs2[l+1] * po[l-r+1];}

int main(){
	scanf("%s", s + 1); n = strlen(s + 1);
	rep(i, 1, n) hs[i] = hs[i-1] * K + s[i] - 'a';
	per(i, n, 1) hs2[i] = hs2[i+1] * K + s[i] - 'a';
	po[0] = 1; rep(i, 1, n) po[i] = po[i-1] * K;
	rep(i, 1, n) f[i][i] = 1;
	rep(i, 1, n) rep(j, i + 1, n){
		int hf = (j - i + 1) / 2;
		if (get(i, i + hf - 1) == get2(j, j - hf + 1))
			f[i][j] = 1;
	}
	rep(len, 2, n) rep(i, 1, n - len + 1){
		int j = i + len - 1, hf = len / 2;
		if (get(i, i + hf - 1) == get(j - hf + 1, j)&&f[i][i+hf-1])
			f[i][j] = f[i][i+hf-1] + 1;
	}
	rep(i, 1, n) rep(j, i, n) ans[f[i][j]]++;
	int sum = 0;
	per(i, n, 1) sum += ans[i], ans[i] = sum;
	rep(i, 1, n) printf("%d%c", ans[i], " \n"[i == n]);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
const int INF = 1e9 + 7;
const int N = 5111;
const ll K = 31;
int n;
int f[N][N], ans[N];
ll hs[N], hs2[N], po[N];
char s[N];

ll get(int l, int r){return hs[r] - hs[l-1] * po[r-l+1];}
ll get2(int l, int r){return hs2[r] - hs[l+1] * po[l-r+1];}

int main(){
	scanf("%s", s + 1); n = strlen(s + 1);
	rep(i, 1, n) hs[i] = hs[i-1] * K + s[i] - 'a';
	per(i, n, 1) hs2[i] = hs2[i+1] * K + s[i] - 'a';
	po[0] = 1; rep(i, 1, n) po[i] = po[i-1] * K;
	rep(i, 1, n) f[i][i] = 1;
	rep(i, 1, n) rep(j, i + 1, n){
		int hf = (j - i + 1) / 2;
		if (get(i, i + hf - 1) == get2(j, j - hf + 1))
			f[i][j] = 1;
	}
	rep(len, 2, n) rep(i, 1, n - len + 1){
		int j = i + len - 1, hf = len / 2;
		if (get(i, i + hf - 1) == get(j - hf + 1, j))
			f[i][j] = f[i][i+hf-1] + 1;
	}
	rep(i, 1, n) rep(j, 1, n) ans[f[i][j]]++;
	ll sum = 0;
	per(i, n, 1) ans[i] += sum, sum += ans[i];
	rep(i, 1, n) printf("%d%c", ans[i], " \n"[i == n]);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
const int INF = 1e9 + 7;
const int Maxn = 5010;
const int L = 37;
const int MOD = 999983;
const int MOD2 = 100000007;
int n;
int sum[Maxn], rsum[Maxn], sum2[Maxn], rsum2[Maxn], pw[Maxn], pw2[Maxn], f[Maxn][Maxn];
char s[Maxn], rs[Maxn];
struct HASH{
	struct node{int x, y, v2; string s;};
	vector<node> h[MOD];
	void push(int v, int x, int y, int v2){
		v = (v + MOD) % MOD, v2 = (v2 + MOD2) % MOD2;
		h[v].pb((node){x, y, v2});
	}
}h;
struct BIT{
	int tr[Maxn];
	void modify(int x, int k){for (; x < Maxn; x += x & -x) tr[x] += k;}
	int query(int x){int ans = 0;for (; x; x -= x & -x) ans += tr[x]; return ans;}
} tr;

int main(){
	scanf("%s", s + 1); n = strlen(s + 1);
	strcat(rs + 1, s + 1), reverse(rs + 1, rs + n + 1);
	rep(i, 1, n) sum[i] = (1ll * sum[i-1] * L + s[i] - 'a') % MOD;
	rep(i, 1, n) rsum[i] = (1ll * rsum[i-1] * L + rs[i] - 'a') % MOD;
	pw[0] = 1; rep(i, 1, n) pw[i] = 1ll * pw[i-1] * L % MOD;
	rep(i, 1, n) sum2[i] = (1ll * sum2[i-1] * L + s[i] - 'a') % MOD2;
	rep(i, 1, n) rsum2[i] = (1ll * rsum2[i-1] * L + rs[i] - 'a') % MOD2;
	pw2[0] = 1; rep(i, 1, n) pw2[i] = 1ll * pw2[i-1] * L % MOD2;
	rep(i, 1, n) rep(j, i, n)
		h.push(rsum[j] - (ll)rsum[i-1] * pw[j-i+1] % MOD, i, j, rsum2[j] - (ll)rsum2[i-1] * pw2[j-i+1] % MOD2);
	rep(i, 1, n) rep(j, i, n){
		int v = (sum[j] - (ll)sum[i-1] * pw[j-i+1] % MOD + MOD) % MOD;
		int v2 = (sum2[j] - (ll)sum2[i-1] * pw2[j-i+1] % MOD2 + MOD2) % MOD2;
		for (int p = 0; p < h.h[v].size(); ++p) if (h.h[v][p].v2 == v2){
			if (h.h[v][p].x + j == n + 1&&h.h[v][p].y + i == n + 1)
				{f[i][j] = 1; break;}
		}
	}
	rep(len, 2, n) rep(i, 1, n - len + 1){
		int mid = i + (len % 2 ? len / 2 : len / 2 - 1);
		if (!f[i][i+len-1]) continue;
		if (len % 2) f[i][i+len-1] = max(f[i][mid-1], f[mid+1][i+len-1]) + 1;
		else f[i][i+len-1] = max(f[i][mid], f[mid+1][i+len-1]) + 1;
	}
//	rep(i, 1, n) {rep(j, 1, n) printf("%d ", f[i][j]); puts("");}
	rep(i, 1, n) rep(j, i, n) tr.modify(1, 1), tr.modify(f[i][j] + 1, -1);
	rep(i, 1, n) printf("%d%c", tr.query(i), " \n"[i == n]);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
const int INF = 1e9 + 7;
const int N = 5111;
const ll K = 31;
int n;
ll f[N][N], ans[N], hs[N], hs2[N], po[N];
char s[N];

ll get(int l, int r){return hs[r] - hs[l-1] * po[r-l+1];}
ll get2(int l, int r){return hs2[r] - hs[l+1] * po[l-r+1];}

int main(){
	scanf("%s", s + 1); n = strlen(s + 1);
	rep(i, 1, n) hs[i] = hs[i-1] * K + s[i] - 'a';
	per(i, n, 1) hs2[i] = hs2[i+1] * K + s[i] - 'a';
	po[0] = 1; rep(i, 1, n) po[i] = po[i-1] * K;
	rep(i, 1, n) f[i][i] = 1;
	rep(i, 1, n) rep(j, i + 1, n){
		int hf = (j - i + 1) / 2;
		if (get(i, i + hf - 1) == get2(j, j - hf + 1))
			f[i][j] = 1;
	}
	rep(len, 2, n) rep(i, 1, n - len + 1){
		int j = i + len - 1, hf = len / 2;
		if (get(i, i + hf - 1) == get(j - hf + 1, j))
			f[i][j] = f[i][i+hf-1] + 1;
	}
	rep(i, 1, n) rep(j, 1, n) ans[f[i][j]]++;
	ll sum = 0;
	per(i, n, 1) ans[i] += sum, sum += ans[i];
	rep(i, 1, n) printf("%I64d%c", ans[i], " \n"[i == n]);
	return 0;
}


#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <bitset>
#define LL long long
#define ULL unsigned long long
using namespace std;
const int maxn = 5005;

char str[maxn];
int dp[maxn][maxn];
int ans[maxn];

int main()
{
    cin >> str;
    int n = strlen(str);
    memset(dp, 0, sizeof(dp));
    for(int len = 1; len <= n; len++)
    {
	for(int l = 0; l+len-1 < n; l++)
	{
	    int r = l + len - 1;
	    if(len == 1)
		dp[l][r] = 1;
	    else if(len == 2)
		dp[l][r] = (str[l] == str[r]? 2 : 0);
	    else if(str[l] != str[r] || dp[l+1][r-1] == 0)
		dp[l][r] = 0;
	    else
	    {
		int m = (l+r)/2 + 1;
		dp[l][r] = dp[m][r] + 1;
	    }
	}
    }
    for(int l = 0; l < n; l++)
	for(int r = 0; r < n; r++)
	    ans[dp[l][r]]++;
    for(int i = n - 1; i >= 1; i--)
	ans[i] += ans[i+1];
    for(int i = 1; i <= n; i++)
	cout << ans[i] << ' ';
    cout<<"\n";
    return 0;
}


#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <bitset>
#define LL long long
#define ULL unsigned long long
using namespace std;
const int maxn = 5005;

char str[maxn];
int dp[maxn][maxn];
int ans[maxn];

int main()
{
    scanf("%s", str);
    int n = strlen(str);
    memset(dp, 0, sizeof(dp));
    for(int len = 1; len <= n; len++)
    {
	for(int l = 0; l+len-1 < n; l++)
	{
	    int r = l + len - 1;
	    if(len == 1)
		dp[l][r] = 1;
	    else if(len == 2)
		dp[l][r] = (str[l] == str[r]? 2 : 0);
	    else if(str[l] != str[r] || dp[l+1][r-1] == 0)
		dp[l][r] = 0;
	    else
	    {
		int m = (l+r)/2 + 1;
		dp[l][r] = dp[m][r] + 1;
	    }
	}
    }
    for(int l = 0; l < n; l++)
	for(int r = 0; r < n; r++)
	    ans[dp[l][r]]++;
    for(int i = n - 1; i >= 1; i--)
	ans[i] += ans[i+1];
    for(int i = 1; i <= n; i++)
	printf("%d ", ans[i]);
    printf("\n");
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5050;

typedef long long ll;

typedef char HType;

const int P1 = 31, P2 = 37, MOD = (int)1e9 + 7;

struct Hash {
  ll h1, h2;
  Hash(ll a = 0, ll b = 0) { h1 = a; h2 = b; }
  void append(HType c) {
    h1 = (P1*h1 + c) % MOD;
    h2 = (P2*h2 + c) % MOD;
  }
  bool operator== (Hash that) const {
    return h1 == that.h1 && h2 == that.h2;
  }
  bool operator!= (Hash that) const {
    return h1 != that.h1 || h2 != that.h2;
  }
  Hash operator* (Hash that) const {
    return Hash((h1*that.h1)%MOD, (h2*that.h2)%MOD);
  }
  Hash operator- (Hash that) const {
    return Hash( (h1 - that.h1 + MOD)%MOD, (h2 - that.h2 + MOD)%MOD);
  }
};

Hash pot[N];

vector<Hash> build_hash(int n, HType *v) {
  pot[0] = Hash(1,1);
 	vector<Hash> ret;
 	Hash acc;
 	for(int i = 0; i < n; i++) {
   	acc.append(v[i]);
   	ret.push_back(acc);
   	if(i > 0) pot[i] = pot[i-1] * Hash(P1, P2);
	}
  return ret;
}

inline Hash get_hash(int l, int r, vector<Hash> &hashv) {
	if(l == 0) return hashv[r];
	return hashv[r] - hashv[l-1] * pot[r-l+1];
}

char s[N];
int n;
int isPal[N][N];
vector<Hash>hs;

int palindromic(int l, int r) {
  if(l >= r) return isPal[l][r] = 1;
  if(isPal[l][r] != -1) return isPal[l][r];
  if(s[l] == s[r]) return isPal[l][r] = palindromic(l + 1, r - 1);
  else return isPal[l][r] = 0;
}

int sol[N];
int pd[N][N];

int solve(int l, int r) {
  if(pd[l][r] != -1) return pd[l][r];
  if(l > r) return 0;
  if(l == r) return pd[l][r] = 1;
  int ret = palindromic(l, r);
  int len = (r - l + 1) / 2;
  if(get_hash(l, l + len - 1, hs) == get_hash(r - len + 1, r, hs)) ret |= ((solve(l, l + len - 1) << 1) & (solve(r - len + 1, r) << 1));
  return pd[l][r] = ret;
}

int main() {
  cin >> s;
  n = strlen(s);
  memset(isPal, -1, sizeof isPal);
  memset(pd, -1, sizeof pd);
  hs = build_hash(n, s);

  for(int i = 0; i < n; i++) {
    for(int j = i; j < n; ++j) {
      int at = solve(i, j);
      if(at == 0) continue;
      //printf("%d - %d\n", at, __builtin_clz(at));
      sol[31 - __builtin_clz(at)]++;
      /*
      while(at) {
        if(at & 1) sol[k]++;
        k++;
        at >>= 1;
      }
      */
    }
  }
  for(int i = n - 1; i >= 0; --i) sol[i] += sol[i + 1];
  for(int i = 0; i < n; ++i) printf("%d ", sol[i]);

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5050;

typedef long long ll;

typedef char HType;

const int P1 = 31, P2 = 37, MOD = (int)1e9 + 7;

struct Hash {
  ll h1, h2;
  Hash(ll a = 0, ll b = 0) { h1 = a; h2 = b; }
  void append(HType c) {
    h1 = (P1*h1 + c) % MOD;
    h2 = (P2*h2 + c) % MOD;
  }
  bool operator== (Hash that) const {
    return h1 == that.h1 && h2 == that.h2;
  }
  bool operator!= (Hash that) const {
    return h1 != that.h1 || h2 != that.h2;
  }
  Hash operator* (Hash that) const {
    return Hash((h1*that.h1)%MOD, (h2*that.h2)%MOD);
  }
  Hash operator- (Hash that) const {
    return Hash( (h1 - that.h1 + MOD)%MOD, (h2 - that.h2 + MOD)%MOD);
  }
};

Hash pot[N];

vector<Hash> build_hash(int n, HType *v) {
  pot[0] = Hash(1,1);
 	vector<Hash> ret;
 	Hash acc;
 	for(int i = 0; i < n; i++) {
   	acc.append(v[i]);
   	ret.push_back(acc);
   	if(i > 0) pot[i] = pot[i-1] * Hash(P1, P2);
	}
  return ret;
}

inline Hash get_hash(int l, int r, vector<Hash> &hashv) {
	if(l == 0) return hashv[r];
	return hashv[r] - hashv[l-1] * pot[r-l+1];
}

char s[N];
int n;
int isPal[N][N];
vector<Hash>hs;

int palindromic(int l, int r) {
  if(l >= r) return isPal[l][r] = 1;
  if(isPal[l][r] != -1) return isPal[l][r];
  if(s[l] == s[r]) return isPal[l][r] = palindromic(l + 1, r - 1);
  else return isPal[l][r] = 0;
}

int sol[N];
int pd[N][N];

int solve(int l, int r) {
  if(pd[l][r] != -1) return pd[l][r];
  if(l > r) return 0;
  if(l == r) return pd[l][r] = 1;
  int ret = palindromic(l, r);
  int len = (r - l + 1) / 2;
  if(get_hash(l, l + len - 1, hs) == get_hash(r - len + 1, r, hs)) ret |= ((solve(l, l + len - 1) << 1) & (solve(r - len + 1, r) << 1));
  return pd[l][r] = ret;
}

int main() {
  scanf(" %s", s);
  n = strlen(s);
  memset(isPal, -1, sizeof isPal);
  memset(pd, -1, sizeof pd);
  hs = build_hash(n, s);

  for(int i = 0; i < n; i++) {
    for(int j = i; j < n; ++j) {
      int at = solve(i, j);
      if(at == 0) continue;
      sol[31 - __builtin_clz(at)]++;
    }
  }
  for(int i = n - 1; i >= 0; --i) sol[i] += sol[i + 1];
  for(int i = 0; i < n; ++i) printf("%d ", sol[i]);

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5050;

typedef long long ll;

typedef char HType;

const int P1 = 31, P2 = 37, MOD = (int)1e9 + 7;

struct Hash {
  ll h1, h2;
  Hash(ll a = 0, ll b = 0) { h1 = a; h2 = b; }
  void append(HType c) {
    h1 = (P1*h1 + c) % MOD;
    h2 = (P2*h2 + c) % MOD;
  }
  bool operator== (Hash that) const {
    return h1 == that.h1 && h2 == that.h2;
  }
  bool operator!= (Hash that) const {
    return h1 != that.h1 || h2 != that.h2;
  }
  Hash operator* (Hash that) const {
    return Hash((h1*that.h1)%MOD, (h2*that.h2)%MOD);
  }
  Hash operator- (Hash that) const {
    return Hash( (h1 - that.h1 + MOD)%MOD, (h2 - that.h2 + MOD)%MOD);
  }
};

Hash pot[N];

vector<Hash> build_hash(int n, HType *v) {
  pot[0] = Hash(1,1);
 	vector<Hash> ret;
 	Hash acc;
 	for(int i = 0; i < n; i++) {
   	acc.append(v[i]);
   	ret.push_back(acc);
   	if(i > 0) pot[i] = pot[i-1] * Hash(P1, P2);
	}
  return ret;
}

inline Hash get_hash(int l, int r, vector<Hash> &hashv) {
	if(l == 0) return hashv[r];
	return hashv[r] - hashv[l-1] * pot[r-l+1];
}

char s[N];
int n;
int isPal[N][N];
vector<Hash>hs;

int palindromic(int l, int r) {
  if(l >= r) return isPal[l][r] = 1;
  if(isPal[l][r] != -1) return isPal[l][r];
  if(s[l] == s[r]) return isPal[l][r] = palindromic(l + 1, r - 1);
  else return isPal[l][r] = 0;
}

int sol[N];
int pd[N][N];

int solve(int l, int r) {
  if(pd[l][r] != -1) return pd[l][r];
  if(l > r) return 0;
  if(l == r) return pd[l][r] = 1;
  int ret = palindromic(l, r);
  int len = (r - l + 1) / 2;
  if(get_hash(l, l + len - 1, hs) == get_hash(r - len + 1, r, hs)) ret = min(solve(l, l + len - 1), solve(r - len + 1, r)) + 1;
  return pd[l][r] = ret;
}

int main() {
  cin >> s;
  n = strlen(s);
  memset(isPal, -1, sizeof isPal);
  memset(pd, -1, sizeof pd);
  hs = build_hash(n, s);
  for(int i = 0; i < n; i++) {
    for(int j = i; j < n; ++j) {
      int at = solve(i, j);
      if(at == 0) continue;
      sol[at - 1]++;
    }
  }
  for(int i = n - 1; i >= 0; --i) sol[i] += sol[i + 1];
  for(int i = 0; i < n; ++i) printf("%d ", sol[i]);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5050;

typedef long long ll;

typedef char HType;

const int P1 = 31, P2 = 37, MOD = (int)1e9 + 7;

struct Hash {
  ll h1, h2;
  Hash(ll a = 0, ll b = 0) { h1 = a; h2 = b; }
  void append(HType c) {
    h1 = (P1*h1 + c) % MOD;
    h2 = (P2*h2 + c) % MOD;
  }
  bool operator== (Hash that) const {
    return h1 == that.h1 && h2 == that.h2;
  }
  bool operator!= (Hash that) const {
    return h1 != that.h1 || h2 != that.h2;
  }
  Hash operator* (Hash that) const {
    return Hash((h1*that.h1)%MOD, (h2*that.h2)%MOD);
  }
  Hash operator- (Hash that) const {
    return Hash( (h1 - that.h1 + MOD)%MOD, (h2 - that.h2 + MOD)%MOD);
  }
};

Hash pot[N];

vector<Hash> build_hash(int n, HType *v) {
  pot[0] = Hash(1,1);
 	vector<Hash> ret;
 	Hash acc;
 	for(int i = 0; i < n; i++) {
   	acc.append(v[i]);
   	ret.push_back(acc);
   	if(i > 0) pot[i] = pot[i-1] * Hash(P1, P2);
	}
  return ret;
}

inline Hash get_hash(int l, int r, vector<Hash> &hashv) {
	if(l == 0) return hashv[r];
	return hashv[r] - hashv[l-1] * pot[r-l+1];
}

char s[N];
int n;
int isPal[N][N];
vector<Hash>hs;

int palindromic(int l, int r) {
  if(l >= r) return isPal[l][r] = 1;
  if(isPal[l][r] != -1) return isPal[l][r];
  if(s[l] == s[r]) return isPal[l][r] = palindromic(l + 1, r - 1);
  else return isPal[l][r] = 0;
}

int sol[N];
int pd[N][N];

int solve(int l, int r) {
  if(pd[l][r] != -1) return pd[l][r];
  if(l > r) return 0;
  if(l == r) return pd[l][r] = 1;
  int ret = palindromic(l, r);
  int len = (r - l + 1) / 2;
  if(get_hash(l, l + len - 1, hs) == get_hash(r - len + 1, r, hs)) ret |= ((solve(l, l + len - 1) << 1) & (solve(r - len + 1, r) << 1));
  return pd[l][r] = ret;
}

int main() {
  cin >> s;
  n = strlen(s);
  memset(isPal, -1, sizeof isPal);
  memset(pd, -1, sizeof pd);
  hs = build_hash(n, s);

  for(int i = 0; i < n; i++) {
    for(int j = i; j < n; ++j) {
      int at = solve(i, j);
      int k = 0;
      while(at) {
        if(at & 1) sol[k]++;
        k++;
        at >>= 1;
      }
    }
  }
  for(int i = 0; i < n; ++i) printf("%d ", sol[i]);

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5050;

typedef long long ll;

typedef char HType;

const int P1 = 31, P2 = 37, MOD = (int)1e9 + 7;

struct Hash {
  ll h1, h2;
  Hash(ll a = 0, ll b = 0) { h1 = a; h2 = b; }
  void append(HType c) {
    h1 = (P1*h1 + c) % MOD;
    h2 = (P2*h2 + c) % MOD;
  }
  bool operator== (Hash that) const {
    return h1 == that.h1 && h2 == that.h2;
  }
  bool operator!= (Hash that) const {
    return h1 != that.h1 || h2 != that.h2;
  }
  Hash operator* (Hash that) const {
    return Hash((h1*that.h1)%MOD, (h2*that.h2)%MOD);
  }
  Hash operator- (Hash that) const {
    return Hash( (h1 - that.h1 + MOD)%MOD, (h2 - that.h2 + MOD)%MOD);
  }
};

Hash pot[N];

vector<Hash> build_hash(int n, HType *v) {
  pot[0] = Hash(1,1);
 	vector<Hash> ret;
 	Hash acc;
 	for(int i = 0; i < n; i++) {
   	acc.append(v[i]);
   	ret.push_back(acc);
   	if(i > 0) pot[i] = pot[i-1] * Hash(P1, P2);
	}
  return ret;
}

inline Hash get_hash(int l, int r, vector<Hash> &hashv) {
	if(l == 0) return hashv[r];
	return hashv[r] - hashv[l-1] * pot[r-l+1];
}

char s[N];
int n;
int isPal[N][N];
vector<Hash>hs;

int palindromic(int l, int r) {
  if(l >= r) return isPal[l][r] = 1;
  if(isPal[l][r] != -1) return isPal[l][r];
  if(s[l] == s[r]) return isPal[l][r] = palindromic(l + 1, r - 1);
  else return isPal[l][r] = 0;
}

int sol[N];
int pd[N][N];

int solve(int l, int r) {
  if(pd[l][r] != -1) return pd[l][r];
  if(l > r) return 0;
  if(l == r) return pd[l][r] = 1;
  int ret = palindromic(l, r);
  int len = (r - l + 1) / 2;
  if(get_hash(l, l + len - 1, hs) == get_hash(r - len + 1, r, hs)) ret |= ((solve(l, l + len - 1) << 1) & (solve(r - len + 1, r) << 1));
  return pd[l][r] = ret;
}

int main() {
  cin >> s;
  n = strlen(s);
  memset(isPal, -1, sizeof isPal);
  memset(pd, -1, sizeof pd);
  hs = build_hash(n, s);

  for(int i = 0; i < n; i++) {
    for(int j = i; j < n; ++j) {
      int at = solve(i, j);
      for(int k = 0; k < 20; ++k) if((at >> k) & 1) {
        sol[k]++;
      }
    }
  }
  for(int i = 0; i < n; ++i) printf("%d ", sol[i]);

	return 0;
}


#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<bitset>
#include<utility>
#include<functional>
#include<iomanip>
#include<sstream>
#include<ctime>
#include<cassert>
using namespace std;
#define y0 y0z
#define y1 y1z
#define yn ynz
#define j0 j0z
#define j1 j1z
#define jn jnz
#define tm tmz
#define buli(x) (__builtin_popcountll(x))
#define bur0(x) (__builtin_ctzll(x))
#define bul2(x) (63-__builtin_clzll(x))
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define fil(a,b) memset((a),(b),sizeof(a))
#define cl(a) fil(a,0)
#define siz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
#define rep(i,a,b) for (int i=(a),_ed=(b);i<_ed;i++)
#define per(i,a,b) for (int i=(b)-1,_ed=(a);i>=_ed;i--)
#define forg(i,gu) for (int i=gu;~i;i=e[i].next)
#define pw(x) ((ll(1))<<(x))
#define upmo(a,b) (((a)=((a)+(b))%mo)<0?(a)+=mo:(a))
#define mmo(a,b) (((a)=1ll*(a)*(b)%mo)<0?(a)+=mo:(a))
void getre(){int x=0;printf("%d\n",1/x);}
void gettle(){int res=1;while(1)res<<=1;printf("%d\n",res);}
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<pii> vpii;
template<typename T,typename S>inline bool upmin(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool upmax(T&a,const S&b){return a<b?a=b,1:0;}
template<typename N,typename PN>inline N flo(N a,PN b){return a>=0?a/b:-((-a-1)/b)-1;}
template<typename N,typename PN>inline N cei(N a,PN b){return a>0?(a-1)/b+1:-(-a/b);}
template<typename N>N gcd(N a,N b){return b?gcd(b,a%b):a;}
template<typename N>inline int sgn(N a){return a>0?1:(a<0?-1:0);}
#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
#define lld "%I64d"
#else
#define lld "%lld"
#endif
inline void gn(long long&x){
	int sg=1;char c;while(((c=getchar())<'0'||c>'9')&&c!='-');c=='-'?(sg=-1,x=0):(x=c-'0');
	while((c=getchar())>='0'&&c<='9')x=x*10+c-'0';x*=sg;
}
inline void gn(int&x){long long t;gn(t);x=t;}
inline void gn(unsigned long long&x){long long t;gn(t);x=t;}
inline void gn(double&x){double t;scanf("%lf",&t);x=t;}
inline void gn(long double&x){double t;scanf("%lf",&t);x=t;}
inline void gs(char *s){scanf("%s",s);}
inline void gc(char &c){while((c=getchar())>126 || c<33);}
inline void pc(char c){putchar(c);}
#ifdef JCVB
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif
typedef long long ll;
typedef double db;
inline ll sqr(ll a){return a*a;}
inline db sqrf(db a){return a*a;}
const int inf=0x3f3f3f3f;
//const ll inf=0x3f3f3f3f3f3f3f3fll;
const db pi=3.14159265358979323846264338327950288L;
const db eps=1e-6;
//const int mo=0;
//int qp(int a,ll b){int n=1;do{if(b&1)n=1ll*n*a%mo;a=1ll*a*a%mo;}while(b>>=1);return n;}

vi verlist[111111];
int ord[111111],pos[111111];
int regtot=0;

int cmp(int i,int j){
	for (int k=0;;k++){
		int iv=k<verlist[i].size()?verlist[i][k]:-1;
		int jv=k<verlist[j].size()?verlist[j][k]:-1;
		if(iv!=jv){
			return iv<jv;
		}
	}
}
vi adjlist[111111];
int n,m;

int getnex(int u,int v){
	int i=lower_bound(all(adjlist[u]),v)-adjlist[u].begin();
	if(i==0)return adjlist[u].back();
	else return adjlist[u][i-1];
}

map<pii,int>vis;//fi -> se

const int TREE_MAXV=300000+5;
struct edge{int v,next;}e[TREE_MAXV*2];int g[TREE_MAXV],etot;
int qu[TREE_MAXV],pre[TREE_MAXV];
void ae(int u,int v){
	if(u>v)return;
	e[etot].v=v; e[etot].next=g[u];g[u]=etot++;
	e[etot].v=u; e[etot].next=g[v];g[v]=etot++;
}
void bfs(int rt){
	int p=0,q=0;
	pre[rt]=0;
	qu[q++]=rt;
	while(p!=q){
		int u=qu[p++];
		for (int i=g[u];~i;i=e[i].next)if(e[i].v!=pre[u]){
			pre[e[i].v]=u;
			qu[q++]=e[i].v;
		}
	}
}
void tree_init(){
	static bool ini=0;
	if(!ini){
		ini=1;
		memset(g,-1,sizeof(g));
	}else{
		for (int i=0;i<=n;i++)g[i]=-1;
	}
	etot=0;
}

int f[333333];
int ret[333333];
void work(int u){
	int gg=0,tmp=0;
	for (int i=g[u];~i;i=e[i].next)if(e[i].v!=pre[u]){
		gg|=f[e[i].v]&tmp;
		tmp|=f[e[i].v];
	}
	if(gg>0){
		while(gg&(gg-1))gg&=gg-1;
		tmp|=gg|(gg-1);
	}

	f[u]=tmp+1;
	ret[u]=bul2(f[u]&-f[u]);
}
int main()
{
#ifdef JCVB
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	int _time_jc=clock();
#endif
	gn(n);gn(m);

	rep(i,1,m+1){
		int a,b;
		gn(a);gn(b);
		a--,b--;
		adjlist[a].pb(b);
		adjlist[b].pb(a);
	}
	rep(i,0,n){
		int a=i,b=(i+1)%n;
		adjlist[a].pb(b);
		adjlist[b].pb(a);
		vis[mp(b,a)]=-1;
	}

	rep(i,0,n){
		sort(all(adjlist[i]));
	}

	rep(u,0,n){
		rep(j,0,siz(adjlist[u])){
			int v=adjlist[u][j];
			if(!vis[mp(u,v)]){
				regtot++;
				int curu=u;
				int curv=v;
				while(1){
					int nex=getnex(curv,curu);
					vis[mp(curu,curv)]=regtot;
					verlist[regtot].pb(curu);
					if(curv==u)break;
					curu=curv;
					curv=nex;
				}
			}
		}
	}

	rep(r,1,regtot+1){
		ord[r]=r;
		sort(all(verlist[r]));
		reverse(all(verlist[r]));
	}
	sort(ord+1,ord+1+regtot,cmp);

	rep(i,1,regtot+1)pos[ord[i]]=i;

	tree_init();

	for (auto it=vis.begin();it!=vis.end();it++){
		int a=it->fi.fi,b=it->fi.se;
		int to=vis[mp(b,a)];
		if(it->se==-1 || to==-1)continue;
		ae(pos[to],pos[it->se]);
	}

	n=regtot;

	bfs(1);

	for(int i=n-1;i>=0;i--)work(qu[i]);
	int ma=0;
	rep(i,1,n+1)upmax(ma,ret[i]);
	rep(i,1,n+1) printf("%d ",ma+1-ret[i]);

#ifdef JCVB
	debug("time: %d\n",int(clock()-_time_jc));
#endif
	return 0;
}


#include <bits/stdc++.h>
#define debug if (0)

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

const int N = 2e5+7;

int ed[N][2], p[N];
int n, m;

struct Node {
    set<int> vtx;
    vector<int> adj;
    int sz;
    int rs;

    bool operator < (const Node & ot) const {
        auto it = vtx.rbegin();
        auto jt = ot.vtx.rbegin();

        while (it != vtx.rend() && jt != ot.vtx.rend()) {
            if (*it != *jt)
                return *it < *jt;
            ++it; ++jt;
        }
        return (it == vtx.rend());
    }
} nd[N];
int ns;

map<pii, vector<int> > mp;
int cn[N];
set<int> avail;

int inner (int i)
{ return ed[i][1] - ed[i][0]; }
int outer (int i)
{ return n - ed[i][1] + ed[i][0]; }

int getsz (int u, int p) {
    nd[u].sz = 1;
    for (int v : nd[u].adj) {
        if (v == p || nd[v].sz == -1) continue;
        nd[u].sz += getsz(v, u);
    }
    return nd[u].sz;
}

void centroid (int u, int d) {
    int siz = getsz(u,u);

    int w = u;
    do {
        u = w;
        for (int v : nd[u].adj) {
            if (nd[v].sz == -1 || nd[v].sz >= nd[u].sz || nd[v].sz + nd[v].sz < siz)
                continue;
            w = v;
            break;
        }
    } while (u != w);

    nd[u].rs = d;
    nd[u].sz = -1;

    for (int v : nd[u].adj)
        if (nd[v].sz != -1)
            centroid(v, d+1);
}

void go (int l, int r, int x) {
    auto it = avail.upper_bound(l);
    while (it != avail.end() && *it <= r) {
        nd[x].vtx.insert(*it-1);
        nd[x].vtx.insert(*it);
        auto jt = next(it);
        avail.erase(it);
        it = jt;
    }
}

int main () {
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        cn[a]++; cn[b]++;

        if (a > b) swap(a,b);
        ed[i][0] = a;
        ed[i][1] = b;
        p[i] = i;
    }

    for (int i = 1; i <= n; i++)
        avail.insert(i);

    sort(p, p+m, [] (int i, int j) {
        return min(inner(i),outer(i)) < min(inner(j),outer(j));
    });

    for (int _i = 0; _i < m; _i++) {
        ns++;
        int i = p[_i];

        nd[ns].vtx.insert(ed[i][0]);
        nd[ns].vtx.insert(ed[i][1]);

        if (inner(i) <= outer(i)) {
            go(ed[i][0], ed[i][1], ns);
        } else {
            go(ed[i][1], n, ns);
            go(1, ed[i][0], ns);

            if (avail.find(1) != avail.end()) {
                avail.erase(1);
                nd[ns].vtx.insert(1);
                nd[ns].vtx.insert(n);
            }
        }

        assert(nd[ns].vtx.size() >= 3);
        int x = *prev(nd[ns].vtx.end());
        for (int y : nd[ns].vtx) {
            if ((x+1)%n != y%n) {
                pii aux(x,y);
                if (aux.first > aux.second)
                    swap(aux.first, aux.second);
                mp[aux].pb(ns);
            }
            cn[y]--;
            x = y;
        }
    }

    for (int i = 1; i <= n; i++) {
        cn[i]++; // standart region

        assert(cn[i] == 0 || cn[i] == 1);
        if (cn[i] == 1) {
            nd[0].vtx.insert(i);
        }
    }

    assert(nd[0].vtx.size() >= 3);

    int x = *prev(nd[0].vtx.end());
    for (int y : nd[0].vtx) {
        if ((x+1)%n != y%n) {
            pii aux(x,y);
            if (aux.first > aux.second)
                swap(aux.first, aux.second);
            mp[aux].pb(0);
        }
        x = y;
    }

    for (pair<const pii, vector<int> > & el : mp) {
        debug cout << "edge " << el.first.first << " " << el.first.second << " :";
        assert(el.second.size() == 2);
        nd[el.second[0]].adj.pb(el.second[1]);
        nd[el.second[1]].adj.pb(el.second[0]);
        debug cout << endl;
    }

    debug {
        for (int i = 0; i <= ns; i++) {
            cout << "region " << i << " :";
            for (int j : nd[i].vtx)
                cout << " " << j;
            cout << " :";
            for (int j : nd[i].adj)
                cout << " " << j;
            cout << endl;
        }
    }

    centroid(0,0);

    sort(nd, nd+ns+1);
    for (int i = 0; i <= ns; i++) {
        cout << nd[i].rs + 1 << " ";
    }
    cout << endl;
}