Problem:
Score: 600 points

Problem Statement

AtCoder's head office consists of N rooms numbered 1 to N. For any two rooms, there is a direct passage connecting these rooms.

For security reasons, Takahashi the president asked you to set a level for every passage, which is a positive integer and must satisfy the following condition:

For each room i\ (1 \leq i \leq N), if we leave Room i, pass through some passages whose levels are all equal and get back to Room i, the number of times we pass through a passage is always even.

Your task is to set levels to the passages so that the highest level of a passage is minimized.

Constraints

N is an integer between 2 and 500 (inclusive).

Input

Input is given from Standard Input in the following format:

N

Output

Print one way to set levels to the passages so that the objective is achieved, as follows:

a_{1,2} a_{1,3} ... a_{1,N}
a_{2,3} ... a_{2,N}
.
.
.
a_{N-1,N}

Here a_{i,j} is the level of the passage connecting Room i and Room j.

If there are multiple solutions, any of them will be accepted.

Sample Input 1

3

Sample Output 1

1 2
1

The following image describes this output:

For example, if we leave Room 2, traverse the path 2 \to 3 \to 2 \to 3 \to 2 \to 1 \to 2 while only passing passages of level 1 and get back to Room 2, we pass through a passage six times.

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
#ifdef __LOCAL
#define debug(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl
#define debugArray(x, n)                                      \
  cerr << __LINE__ << ": " << #x << " = {";                   \
  for (long long hoge = 0; (hoge) < (long long)(n); ++(hoge)) \
    cerr << ((hoge) ? "," : "") << x[hoge];                   \
  cerr << "}" << endl
#else
#define debug(x) (void(0))
#define debugArray(x, n) (void(0))
#endif

struct UnionFind {
  vector<int> par;
  UnionFind(int size) : par(size, -1) {}
  bool unite(int u, int v) {
    if ((u = root(u)) == (v = root(v))) return false;
    if (par[u] > par[v]) swap(u, v);
    par[u] += par[v], par[v] = u;
    return true;
  }
  bool same(int u, int v) { return root(u) == root(v); }
  int root(int u) { return par[u] < 0 ? u : par[u] = root(par[u]); }
  int size(int u) { return -par[root(u)]; }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int N;
  cin >> N;
  int ans[510][510];
  int lmin = INT_MAX;
  auto step = [&]() {
    int level[510][510];
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++) level[i][j] = 0;
    int l = 1;
    random_device seed_gen;
    mt19937 engine(seed_gen());
    for (bool update = true; update; l++) {
      update = false;
      UnionFind uf(N * 2);
      vector<pair<int, int>> vec;
      for (int i = 0; i < N; i++)
        for (int j = i + 1; j < N; j++)
          if (level[i][j] == 0) vec.emplace_back(i, j);
      shuffle(vec.begin(), vec.end(), engine);
      for (auto p : vec) {
        int u, v;
        tie(u, v) = p;
        if (uf.same(u, v)) continue;
        level[u][v] = l;
        update = true;
        uf.unite(u, v + N);
        uf.unite(v, u + N);
      }
    }
    l--;
    if (l < lmin) {
      for (int i = 0; i < N; i++)
        for (int j = i + 1; j < N; j++) ans[i][j] = level[i][j];
    }
  };
  for (int i = 0; i < 100; i++) step();
  for (int i = 0; i < N; i++) {
    for (int j = i + 1; j < N; j++) {
      cout << ans[i][j] << (j == N - 1 ? '\n' : ' ');
    }
  }
  return 0;
}