#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<sstream>
#include<iterator>
#include<list>

using namespace std;

typedef  long long int lint;

#define rep(i, n) for (lint i = 0; i < n; i++)
#define sort(v) sort((v).begin(), (v).end())
#define reverse(v) reverse((v).begin(), (v).end())
#define upper(v,hoge) upper_bound(v.begin(),v.end(),hoge)
#define lower(v,hoge) lower_bound(v.begin(),v.end(),hoge)
#define mp make_pair
#define enld endl
#define P pair<lint,lint>

string ten_to_two(lint N) {
	//10進数から2進数
	string ans;
	while (1) {
		ans.push_back(char('0' + N % 2));
		N /= 2;
		if (N == 0) {
			break;
		}
	}
	reverse(ans);
	return ans;
}

lint popcntlint(lint N) {
	lint ans = 0;
	string S = ten_to_two(N);
	rep(i, S.size()) {
		if (S[i] == '1') {
			ans++;
		}
	}
	return ans;
}

lint popcntstr(string S) {
	lint ans = 0;
	rep(i, S.size()) {
		if (S[i] == '1') {
			ans++;
		}
	}
	return ans;
}

lint f(lint N) {
	if (N == 0) {
		return 0;
	}
	lint cnt = 0;
	while (1) {
		cnt++;
		N = N % popcntlint(N);
		if (N == 0) {
			return cnt;
		}
	}
}

//Nで割ったあまりの配列(サイズSIZE)
vector<lint>DP(lint N,lint SIZE) {
	vector<lint>dp(SIZE);
	dp[0] = 1 % N;
	for (lint i = 1; i < SIZE; i++) {
		dp[i] = (dp[i - 1] * 2) % N;
	}
	//逆
	return dp;
}

int main() {
	lint N;
	string X;
	cin >> N >> X;



	reverse(X);
	lint pp = popcntstr(X);

	if (pp == 0) {
		

		vector<lint>Vp;
		Vp = DP(pp + 1, N);
		

		lint Mp = 0;
		

		rep(i, N) {
			if (X[i] == '1') {
				Mp += Vp[i];
				Mp %= pp + 1;
			}
		}

		for (lint i = N - 1; i >= 0; i--) {
			lint now = 0;
			if (X[i] == '0') {
				now = (Mp + Vp[i]) % (pp + 1);
				//cout << now << ' ';
				cout << f(now) + 1 << enld;
			}
			else {
				cout << 0 << endl;
			}

		}
		return 0;
	}

	if (pp == 1) {
		vector<lint>V;
		V = DP(pp, N);
		
		vector<lint>Vp;
		Vp = DP(pp + 1, N);
		lint M = 0;
		
		lint Mp = 0;
		rep(i, N) {
			if (X[i] == '1') {
				M += V[i];
				M %= pp;
			}
		}
		
		rep(i, N) {
			if (X[i] == '1') {
				Mp += Vp[i];
				Mp %= pp + 1;
			}
		}

		for (lint i = N - 1; i >= 0; i--) {
			lint now = 0;
			if (X[i] == '0') {
				now = (Mp + Vp[i]) % (pp + 1);
				//cout << now << ' ';
				cout << f(now) + 1 << enld;
			}
			else {
				cout << 0 << endl;
			}

		}
		return 0;
	}

	vector<lint>V;
	V = DP(pp, N);
	vector<lint>Vm;
	Vm = DP(pp-1, N);
	vector<lint>Vp;
	Vp = DP(pp+1, N);
	lint M = 0;
	lint Mm = 0;
	lint Mp = 0;
	rep(i, N) {
		if (X[i] == '1') {
			M += V[i];
			M %= pp;
		}
	}
	rep(i, N) {
		if (X[i] == '1') {
			Mm += Vm[i];
			Mm %= pp - 1;
		}
	}
	rep(i, N) {
		if (X[i] == '1') {
			Mp += Vp[i];
			Mp %= pp + 1;
		}
	}

	/*cout << "pp " << pp << enld;
	cout << "V" << enld;
	rep(i, N) {
		cout << V[i] << ' ';
	}
	cout << enld;
	cout << "Vm" << enld;
	rep(i, N) {
		cout << Vm[i] << ' ';
	}
	cout << enld;
	cout << "Vp" << enld;
	rep(i, N) {
		cout << Vp[i] << ' ';
	}
	cout << enld;
	cout << "M " << M << enld;
	cout << "Mm " << Mm << enld;
	cout << "Mp " << Mp << enld;*/
	
	for (lint i = N - 1; i >= 0; i--) {
		lint now = 0;
		if (X[i] == '0') {
			now = (Mp + Vp[i]) % (pp + 1);
			//cout << now << ' ';
			cout << f(now)+1 << enld;
		}
		else {
			now = (Mm - Vm[i]+10*(pp-1)) % (pp - 1);
			//cout << now << ' ';
			cout << f(now)+1 << enld;
		}

	}
}

Measured memory_bytes: 8212