/*
 author : Anubhav Dinesh Patel
 date : 11.07.2020 12:18:08 IST 
*/

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long int
#define fast_io ios_base::sync_with_stdio(false); cin.tie(NULL)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define all(a) a.begin(),a.end() 
#define max_pqueue priority_queue< long long >
#define min_pqueue priority_queue< long long , vector<long long> , greater< long long >>
#define vi vector<int>
#define vii vector<pair<int, int>>
#define vl vector<long long>
#define vll vector<pair<long long, long long>>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define FF first
#define SS second
#define sz(x) (int)x.size()
#define gcase "Case #"<<tcase<<": "
using namespace std;
// using namespace __gnu_pbds;
// typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
// typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// typedef tree<int, int, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_map;

//~ setbase - cout << setbase (16); cout << 100 << endl; Prints 64
//~ setfill -   cout << setfill ('x') << setw (5); cout << 77 << endl; prints xxx77
//~ setprecision - cout << setprecision (14) << f << endl; Prints x.xxxx
//~ cout.precision(x)  cout<<fixed<<val;  // prints x digits after decimal in val

#ifndef LOCAL_MACHINE
#define cerr if (false) cerr
#endif

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
template<typename T>
void _printA(T *t, long long sz) { cout<<" { "; for (long long i=0; i<sz; i++) cout<<"["<<i<<"] = "<< t[i]<<endl; cout<<" } \n";}
#ifdef LOCAL_MACHINE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#define debugA(x, y) cerr << "[" << #x << "] = "; _printA(x, y)
#else
#define debug(x...)
#define debugA(x, y)
#endif

const ll _MOD = 1e9 + 7;

ll mod(ll a, ll m=_MOD) {
	return ((a % m) + m) % m;
}

ll gcd(ll a, ll b) { return __gcd(a, b); }

ll gcd(ll a, ll b, ll & x, ll & y) {
    if (a == 0) {
        x = 0;
        y = 1;
        return b;
    }
    ll x1, y1;
    ll d = gcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return d;
}

ll modinv(ll a, ll m=_MOD) {
	ll x, y;
	gcd(a, m, x, y);
	x = (x % m + m) % m;
    return x;
}

ll powm(ll a, ll b, ll m=_MOD) {
	if (b == 0) return 1;
	ll ans = powm(a, b/2, m);
	ans = (ans * ans) % m;
	return (b & 1) ? (ans * (a%m)) % m : ans;
}

/* 1. If you can't keep solution in mind, then visualize it on a paper.
 * 2. Try to identify the type of problem - DP, Greedy, Graph, Constructive, 
 * 	  Prefix/Suffix, Difference Array, BIT/Segment Tree, etc.
 * 3. Look at the problems from different perspectives - reverse the problem, 
 * 	  add instead of delete (maybe?)
 * 4. Divide difficult solutions into cases and/or sequences.
 * 5. Use math rules to solve Nested Summation.
 * 6. Optimisation problems are generally solved with DP, greedy, binary search or brute-force.
 * ------------------------------------------------------------------ 
 */
int bits[int(3e5)];
int pre[int(3e5)];
int n;

int get(ll v, int steps) {
	debug(v, steps);
	if (v == 0) return steps;
	int b = __builtin_popcount(v);
	v = v % b;
	return get(v, steps + 1);  
}

void solve(/* int tcase */) {
	cin>>n;
	for (int i=0; i<n; i++) {
		char c;
		cin>>c;
		bits[i] = c - '0';
	}
	pre[0] = bits[0];
	for (int i=1; i<n; i++)
		pre[i] = bits[i] + pre[i-1];
	
	int a = pre[n-1] - 1, b = pre[n-1] + 1;
	if (a <= 0)
		a = b;
	debug(a, b);
	ll pow2[2][n];
	pow2[0][n-1] = 1 % a;
	pow2[1][n-1] = 1 % b;
	for (int i=n-2; i>=0; i--) {
		pow2[0][i] = ((2 % a) * (pow2[0][i+1] % a)) % a;
		pow2[1][i] = ((2 % b) * (pow2[1][i+1] % b)) % b;
	}
	
	ll moda = 0, modb = 0;
	for (int i=n-1; i>=0; i--) {
		moda += (pow2[0][i] * (bits[i] % a)) % a;
		moda = moda % a;
		modb += (pow2[1][i] * (bits[i] % b)) % b;
		modb = modb % b;
	}
	debug(moda, modb);
	
	for (int i=0; i<n; i++) {
		// delete ith bit
		// int ans = 0;
		int bcnt = pre[n-1];
		if (bits[i] == 0)
			bcnt++;
		else
			bcnt--;
		if (bcnt == 0) {
			cout<<0<<endl;
			continue;
		}
		// int bh = max(0, n - 60);
		// ll v = 0;
		// for (int j=bh; j<n; j++) {
			// v = v << 1;
			// if (j == i) {
				// if (bits[j] == 0)
					// v += 1;
				// else
					// v += 0;
			// }
			// else	
				// v += bits[j];
		// }
		ll v;
		if (a == bcnt)
			v = moda;
		else
			v = modb;
		if (bits[i] == 0) {
			if (bcnt == a) {
				v += pow2[0][i] % a;
				v = v % a;
			} else {
				v += pow2[1][i] % b;
				v = v % b;
			}		
		}
		else {
			if (bcnt == a) {
				v -= pow2[0][i] % a;
				v = (v % a + a) % a;
			} else {
				v -= pow2[1][i] % b;
				v = (v % b + b ) % b;
			}	
		}
		debug(v, bcnt);
		// v = v % bcnt;
		debug(v, bcnt);
		cout<<get(v, 1)<<endl;
	}
}	

void preprocess() {
	
}

int main() {
#ifdef LOCAL_MACHINE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
freopen("in", "r", stdin);
#pragma GCC diagnostic pop
#endif

	fast_io;
	preprocess();
	ll T;
	T = 1;
	// cin>>T;
	for (ll t=0; t<T; t++) {
		solve(/* t */);
	}
}	


Measured memory_bytes: 8348