#include<bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i = 0; i < n; i++)
#define Rep(i,n) for(int i = 1; i <= n; i++)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define fin(a) { cout << a << endl; return 0; }
#define debug(a) { cerr << #a << ": " << a << endl; }
#define endl '\n'
#define fi first
#define se second
using lint = long long;
using ld = long double;
using P = pair<int,int>;
using Pl = pair<lint,lint>;
template<class T> using V = vector<T>;
template<class T> using priq     = priority_queue<T>;
template<class T> using priq_inv = priority_queue<T, vector<T>, greater<T>>;
const int dx[] = {0,1,0,-1,1,1,-1,-1};
const int dy[] = {1,0,-1,0,1,-1,-1,1};
template<class T> T ceil(const T &a, const T &b) { return ((a)+(b)-1)/b; }
template<class T> bool chmin(T &a, T b) { if(a > b) { a = b; return 1; } return 0; }
template<class T> bool chmax(T &a, T b) { if(a < b) { a = b; return 1; } return 0; }
template<class T> void YesorNo(T x) { printf(x ? "Yes\n" : "No\n"); }
struct INF { template<class T> operator T() { return numeric_limits<T>::max() / 2; } } INF;

template<class T, class U> istream& operator>>(istream &in, pair<T,U> &p) {
    return in >> p.first >> p.second;
}
template<class T, class U> ostream& operator<<(ostream &out, const pair<T,U> &p) {
    return out << '{' << p.first << ',' << p.second << '}';
}
template<class T> istream& operator>>(istream &in, vector<T> &v) {
    for(auto &&e : v) in >> e;
    return in;
}
template<class T> ostream& operator<<(ostream &out, const vector<T> &v) {
    for(const auto &e : v) out << e << ' ';
    return out;
}

/*----------------------------------------------------------------------------------------------------*/


int main(){
    int n;
    cin >> n;
    int idx = 1;
    int now = 1;
    V<int> ans(n); ans[0] = 1;
    for(int i = 2; i <= n; i++) {
        if(i % idx == 0) {
            idx = i;
            now++;
        }
        ans[i-1] = now;
    }
    cout << ans << endl;
}
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
#include <ext/pb_ds/detail/standard_policies.hpp>

// Picasso didn't learn to paint by watching lectures




/* 
*    coder :: ATUL_PANDEY_2608
*        >>> INDIA <<<
*/

 
using namespace std;
using namespace __gnu_pbds;

// #define  part ..
#define ook order_of_key
#define fbo find_by_order 
#define pb(a) push_back(a)
#define all(a) a.begin(),a.end() 
#define mod 1000000007
#define tot_time cerr << "Runtime is: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
//#define maxx 200006
#define fixed cout<<fixed<<setprecision(14);
#define ll long long 
#define quick    ios_base::sync_with_stdio(NULL),cin.tie(0);
#define listll vector< long long > 
#define listi vector< int> 
#define pii   pair<int , int> 
#define pll pair<long long , long long > 
#define minheap priority_queue<long long , vector< long long >, greater<long long > >
#define rep(i,a,b) for(int i=a;i<b;i++)
#define memo(a,x ) memset( a, x ,sizeof ( a) )
#define randoms mt19937 rng(26);

template  < class  T >
vector< T > readvector  ( T  n ) {  vector < T > arr(n ) ;
	    for( int  i =0; i < n ; i ++ ) cin>>arr[i] ;
		return arr; }


ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

ll power( ll a, ll n, ll m= 1000000007){
  ll ans = 1;
  while(n){
  if(n&1)
  {
  ans *= a;
  ans%=m;
  }
  a*=a;
  a%=m;
  n/=2;
  }
  return ans ;
} 


vector< int > prm ;
vector < bool > vsp ;

void prime ( int nn = 100000 ) {
	vsp = vector < bool > ( nn+1, 0 );
	int size_prime = nn;
	for( ll i =2; i*i < size_prime ; i++){
		
		if( vsp[i] == 1)
		continue;
		for(ll j = i*i; j < size_prime ;j+=i){
			
			vsp[j] =1;
			
		}
		
		
	}
	
	for( int i= 2; i < size_prime ; i++)
	if (vsp[i] == 0)
	prm.pb(i);
	
	
}


//auto comparator = [] ( array < ll ,2 >  &a  , array < ll , 2  > &b ) {  return ( a[0] < b[0 ] || (a[ 0] == b[ 0] && a[1]  > b[1] ) ) ; } ; 

//priority_queue< array <  ll  , 2> , vector< array< ll ,2 > > , decltype( comparator )  > pq ( comparator);







template < class T > using oset = tree< T , null_type, less  < T  > , rb_tree_tag , tree_order_statistics_node_update > ;
// oset< int > tree ; 
// tree.ook ( val  )  return index of element ;
// tree.fbo ( idx )   return pointer at the element .




// end of #define 

// define globals ...
const int maxx = 2e5+26;

//write function from here ...
// never forget  to recheck your predefined function in template .. 
// already defined ::  prime , power , gcd : ( ll ).. 







int Main(int t ){


 int n ;
 cin>>n;
 
 vector< int > arr( n , 0 ) ;

 ll tw = 1 ;
 arr[ 0  ]=1 ; 
 ll tt = 1 ;
 while( true ) {
	 int pre = tw +1  ;
	 tt*=2 ;
	 tw += tt;
	 if ( pre > n )
	 break;
	 int temp = pre ;
	 while ( temp <= tw && temp <= n ) {
		 arr[ temp-1] = arr[ pre-2] +1;
		 temp +=1;
	 }
	 
	 
	 
 }
 
 for( int a : arr){
	 cout<<a<<" ";
 }
    
    
    
	
  
return 0;

}






int main(){
 quick;

  //#ifndef ONLINE_JUDGE
  //freopen ("input.txt", "r", stdin);
  //freopen ("outt.txt", "w", stdout);
//#endif

int t =1; 
//cin>>t;
while(t-- )
 Main(t);

 return 0;
}


  


