#include <bits/stdc++.h>
using namespace std;
#define REP(i,x,n) for(int i=x;i<(int)n;i++)
#define rep(i,n) REP(i,0,n)
#define sp(p) cout<<setprecision(16)<<fixed<<p<<endl;
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define SORT(a) sort(all(a))
#define RSORT(a) sort(rall(a))
#define UNIQ(a) unique(all(a))
#define UNIQNUM(a) UNIQ(a)-a.begin()
#define UNIQIT(a) a.erase(UNIQ(a), a.end());
#define VOUT(v,i) rep(i,v.size())cout<<v[i]<<(i==v.size()-1?"\n":" ");
#define vout(v) VOUT(v,z);
#define vdbg(v,i) cout<<#v<<": ";for(int i=0;i<(int)v.size();i++){cout<<v[i]<<" ";}cout<<"\n";
#define vmin(v) *min_element(all(v))
#define vmax(v) *max_element(all(v))
#define vsum(v) accumulate(all(v), 0LL)
#define MOUT(m,r,c) rep(i,r){rep(j,c){cout<<m[i][j]<<" ";}cout<<endl;}
#define mout(m) MOUT(m,m.size(),m[0].size())
#define debg(a) cout<<#a<<": "<<a<<endl;
#define show(a) for(cont &y:a){for(cont &x:y){cout<<x<<" ";}cout<<endl;}
#define digit(a) to_string(a).length();
template<class T>inline int out(const T &t){ print(t); putchar('\n'); return 0; }
// template<class T>inline T gcd(T a,T b){if(b==0)return a; return(gcd(b,a%b));}
// template<class T>inline T lcm(T a,T b){return a/gcd(a,b)*b;}
bool is_palindrome(string s){return s == string(s.rbegin(),s.rend());}
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> P;
typedef vector<ll> V;
typedef vector<vector<ll>> VV;
// const long long MOD=1000000007;
const long long INF = 1e18;
#define EPS (1e-7)
#define PI (acos(-1))
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(a > b) { a = b; return true; }
    return false;
}

// Function to return the value of (str % k)  
int getMod(string str, int n, int k)  
{  
    // pwrTwo[i] will store ((2^i) % k)  
    int pwrTwo[n];  
    pwrTwo[0] = 1 % k;  
    for (int i = 1; i < n; i++)  
    {  
        pwrTwo[i] = pwrTwo[i - 1] * (2 % k);  
        pwrTwo[i] %= k;  
    }  
    // To store the result  
    int res = 0;  
    int i = 0, j = n - 1;  
    while (i < n)  
    {  
        // If current bit is 1  
        if (str[j] == '1')  
        {  
            // Add the current power of 2  
            res += (pwrTwo[i]);  
            res %= k;  
        }  
        i++;  
        j--;  
    }  
    return res;  
}  

int binary_remainder(string binary, int k){
    int rem = 0;
    for (long long i = 0; i < binary.length(); i++) {
        rem *= 2;
        if(binary[i]=='1') rem++;
        rem %= k;
    }
    return rem;
}

int main(){
    long long N;
    scanf("%lld",&N);
    std::string X;
    std::cin >> X;

  vector<int> dp(200001, 0);
  for (int i = 1; i <= 200000; i++){
    dp[i] = dp[i % __builtin_popcount(i)] + 1;
  }
  int pcnt = 0;
  for (int i = 0; i < N; i++){
    pcnt += X[i] - '0';
  }
  vector<int> rem_neg(N, 0);
  if (pcnt >= 2){
    rem_neg[N - 1] = 1;
    for (int i = N - 2; i >= 0; i--){
      rem_neg[i] = rem_neg[i + 1] * 2 % (pcnt - 1);
    }
  }
  vector<int> rem_pos(N, 0);
  rem_pos[N - 1] = 1;
  for (int i = N - 2; i >= 0; i--){
    rem_pos[i] = rem_pos[i + 1] * 2 % (pcnt + 1);
  }
  int X_neg = 0;
  if (pcnt >= 2){
    for (int i = 0; i < N; i++){
      if (X[i] == '1'){
        X_neg += rem_neg[i];
        X_neg %= (pcnt - 1);
      }
    }
  }
  int X_pos = 0;
  for (int i = 0; i < N; i++){
    if (X[i] == '1'){
      X_pos += rem_pos[i];
      X_pos %= (pcnt + 1);
    }
  }
  for (int i = 0; i < N; i++){
    if (X[i] == '1'){
      if (pcnt == 1){
        cout << 0 << endl;
      } else {
        int r = X_neg - rem_neg[i];
        r += pcnt - 1;
        r %= pcnt - 1;
        cout << dp[r] + 1 << endl;
      }
    } else {
      int r = X_pos + rem_pos[i];
      r %= pcnt + 1;
      cout << dp[r] + 1 << endl;
    }
  }
    return 0;
}


Measured memory_bytes: 6008