#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
using graph = vector<vector<int>>;
using pii = pair<int,int>;

#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define repd(i,n) for(ll i=n-1;i>=0;i--)
#define FOR(i,a,b) for(ll i=a;i<=(ll)(b);i++)
#define FORD(i,a,b) for(ll i=a;i>=(ll)(b);i--)
//xにはvectorなどのコンテナ
#define all(x) (x).begin(),(x).end()
#define size(x) ((ll)(x).size())
#define MAX(x) *max_element(ALL(x))
#define MIN(x) *min_element(ALL(x))

#define INF 1000000000000
#define M 10000007
#define MAXR 100000

#define pb push_back
#define mp make_pair
#define f first
#define s second
#define FIND(x,y) find(all(x),y)!=x.end()
template<class T> inline bool chmax(T &a,T b) { if (a<b) { a=b; return true; } return false; }
template<class T> inline bool chmin(T &a,T b) { if (b<a) { a=b; return true; } return false; }

struct uf {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
    vector<int> rcount;

    uf(int N) : par(N) { //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++) par[i] = i;
    }

    int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }

    void unite(int x, int y) { // xとyの木を併合
        int rx = root(x); //xの根をrx
        int ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    }

    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }

};
class mint {
    long long x;
public:
    mint(long long x=0) : x((x%M+M)%M) {}
    mint operator-() const {
      return mint(-x);
    }
    mint& operator+=(const mint& a) {
        if ((x += a.x) >= M) x -= M;
        return *this;
    }
    mint& operator-=(const mint& a) {
        if ((x += M-a.x) >= M) x -= M;
        return *this;
    }
    mint& operator*=(const  mint& a) {
        (x *= a.x) %= M;
        return *this;
    }
    mint operator+(const mint& a) const {
        mint res(*this);
        return res+=a;
    }
    mint operator-(const mint& a) const {
        mint res(*this);
        return res-=a;
    }
    mint operator*(const mint& a) const {
        mint res(*this);
        return res*=a;
    }
    mint pow(ll t) const {
        if (!t) return 1;
        mint a = pow(t>>1);
        a *= a;
        if (t&1) a *= *this;
        return a;
    }
    // for prime M
    mint inv() const {
        return pow(M-2);
    }
    mint& operator/=(const mint& a) {
        return (*this) *= a.inv();
    }
    mint operator/(const mint& a) const {
        mint res(*this);
        return res/=a;
    }

    friend ostream& operator<<(ostream& os, const mint& m){
        os << m.x;
        return os;
    }
};


int main(){
	string s;cin>>s;
	vector<tuple<int,int,int>> x;
	vector<int>ans(size(s),0);
	int h,l=0,r=0,ho=0;
	rep(i,size(s)){
		if(i==0)continue;
		if(s[i]==s[i-1]){
			if(ho==0)l++;
			else r++;
		}
		else {
			if(ho==0){
				ho=1-ho;
				h=i;
			}
			else{
				ho=1-ho;
				x.pb(make_tuple(h,l+1,r+1));
				l=0;
				r=0;
			}
		}
		if(i==size(s)-1){
			x.pb(make_tuple(h,l+1,r+1));
		}
	}
	for(auto&v:x){
		if(!((get<1>(v)+get<2>(v))%2)){
			ans[get<0>(v)-1]=(get<1>(v)+get<2>(v))/2;
			ans[get<0>(v)]=(get<1>(v)+get<2>(v))/2;
		}
		else{
			if((get<1>(v)%2)){
				ans[get<0>(v)-1]=(get<1>(v)+get<2>(v))/2+1;
				ans[get<0>(v)]=(get<1>(v)+get<2>(v))/2;
			}
			else {
				ans[get<0>(v)-1]=(get<1>(v)+get<2>(v))/2;
				ans[get<0>(v)]=(get<1>(v)+get<2>(v))/2+1;
			}
		}
	}
	for(auto&v:ans){
		cout<<v<<" ";
	}
	cout<<endl;
}


Measured memory_bytes: 1724