#include <bits/stdc++.h>

using namespace std;

typedef long long i64;
typedef unsigned long long ui64;
typedef vector<i64> vi;
typedef vector<vi> vvi;
typedef pair<i64, i64> pi;

#define pb push_back
#define sz(a) i64((a).size())
#define all(c) (c).begin(), (c).end()
#define REP(s, e, i) for(i=(s); i < (e); ++i)
inline void RI(i64 &i) {scanf("%lld", &(i));}
inline void RVI(vi &v) { for(i64 i=0;i<sz(v);++i) { RI(v[i]); } }
inline void RVVI(vvi &vv) { for(i64 i=0;i<sz(vv);++i) { RVI(vv[i]); } }
inline void WI(const i64 &i) {printf("%lld\n", i);}
inline void WVI(const vi &v, char sep=' ') { for(i64 i=0;i<sz(v);++i) { if(i != 0){ printf("%c", sep); } printf("%lld", v[i]);} printf("\n"); }
inline void WS(const string &s) { printf("%s\n", s.c_str()); }
inline void WB(bool b, const string &yes, const string &no) { if(b){ WS(yes);} else { WS(no);} }
inline void YESNO(bool b) { WB(b, "YES", "NO"); }
#define BUF_LENGTH 1000000
inline void RS(string &s) {static char buf[BUF_LENGTH]; scanf("%s", buf); s = buf;}
template<typename T> inline bool IN(T &S, const typename T::key_type &key) {
  return S.find(key) != S.end();
}


template<typename T>
vector<T> sieve(T max) {
  if(max < 2) {
    return {};
  }
  using flag_type = unsigned char;
  vector<flag_type> is_prime(max+1, 1);
  
  // 2
  vector<T> primes = {2};
  int q = 4;
  while(q <= max) {
    is_prime[q] = 0;
    q += 2;
  }
  
  // 3 or more
  for(int p=3;p<=max;p+=2) {
    if(is_prime[p]) {
      primes.push_back(p);
      int q = p * 3;
      while(q <= max) {
        is_prime[q] = 0;
        q += p * 2;
      }
    }
  }
  
  return primes;
}

int main(int argc, char *argv[]) {
  i64 i, j, k;  
  i64 N; cin >> N;
  vi primes = sieve(N + 1);

  vi ans(N+1, 0);
  ans[1] = 1;
  REP(1, N+1, i) {
    for(auto &p: primes) {      
      if(i*p > N) {
        break;
      }
      i64 n = ans[i] + 1;
      if(ans[i*p] == 0) {
        ans[i*p] = n;
      }
      else {
        assert(ans[i*p] >= n);
      }
    }
  }

  REP(1, N+1, i) {
    if(i != 1) {
      printf(" ");
    }
    printf("%lld", ans[i]);
  }
  printf("\n");

  return 0;
}


//a.9
#include<bits/stdc++.h>
#define ll long long
#define all(x) x.begin(),x.end()
#define CASE(t) cout<<"Case #"<<(t)<<": ";
#define endll endl
#define endl '\n'
#define mod 1000000007
#define INF 1e18
#define maxN 500005
#define ios ios_base::sync_with_stdio(false); cin.tie(NULL)
using namespace std;
ll ceill(ll a,ll b){return a/b+bool(a%b);}
ll gcd(ll a,ll b){if(b==0)return a;return gcd(b, a % b);}
ll lcm(ll a,ll b){return (a*b)/gcd(a,b);}
ll power(ll x,ll y){ll res=1;while(y>0){if(y&1)res=(res*x)%mod;x=(x*x)%mod;y>>=1;}return res;}
bool isPrime(ll n)
{
    if(n<=1)return false;if(n<=3)return true;if(n%2==0 || n%3==0)return false;
    for(ll i=5;i*i<=n;i=i+6)if(n%i==0 || n%(i+2)==0) return false; return true;
}
void primeFactors(ll n, vector<ll> &vec)
{
    while(n%2==0)vec.push_back(2),n/=2;
    for(ll i=3;i<=sqrt(n);i+=2)while(n%i==0)vec.push_back(i),n/=i;
    if(n>2)vec.push_back(n);
}
//vector<ll>fact(maxN);
//void factpre(){fact[0]=1;for(ll i=1;i<maxN;i++)fact[i]=(fact[i-1]*1LL*i);}
//ll mul(ll a,ll b){return (a*1LL*b)%mod;}
//ll nCr(ll n,ll k){return mul(fact[n],power(mul(fact[k],fact[n-k]),mod-2));}
bool chk(ll n)
{
    return n&&(!(n&(n-1)));
}
void solve()
{
    ll n;cin>>n;
    ll tmp=0;
    for(ll i=1;i<=n;i++)
    {
        if(i==1 || chk(i))cout<<(++tmp)<<" ";
        else cout<<tmp<<" ";
    }
    cout<<endl;
}
signed main()
{
    ios;
    ll tc=1; //cin>>tc;
    for(ll TTT=1;TTT<=tc;TTT++)
    {
        //CASE(TTT);
        solve();
    }
}
