#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
  return x * f;
}
const int MAXN = 1800010;
const int INF = 2147483600;
int N;
int Next[MAXN + 1], Root[MAXN + 1], tim;
vector<int> vec[MAXN + 1];
int a[MAXN + 1];
int col[MAXN + 1];
int id;
bool vis[MAXN + 1];
inline int D(int x) { return ((x - 1) ^ 1) + 1; }
int Node[MAXN << 1], Nexte[MAXN << 1], Roote[MAXN + 1], cnt, Cost[MAXN << 1];
inline void insert(int u, int v, int x) {
  Node[++cnt] = v;
  Nexte[cnt] = Roote[u];
  Roote[u] = cnt;
  Cost[cnt] = x;
}
inline bool dfs(int j, int bg) {
  col[j] = 1;
  if (a[j] == a[bg]) {
    Next[D(j)] = bg;
    return 1;
  }
  while (vec[a[j]].size() && col[*vec[a[j]].rbegin()]) vec[a[j]].pop_back();
  if (!vec[a[j]].size()) return false;
  int x = *vec[a[j]].rbegin();
  vec[a[j]].pop_back();
  Next[D(j)] = x;
  col[x] = 1;
  return dfs(D(x), bg);
}
int val[MAXN + 1];
pair<int, int> sta[MAXN + 1];
int In[MAXN + 1];
int main() {
  N = read();
  for (int i = 1; i <= N; i++) {
    val[2 * i - 1] = read();
    val[2 * i] = read();
  }
  for (int i = 20; i >= 0; i--) {
    for (int j = 1; j <= 2 * N; j++) {
      a[j] = (val[j] & ((1 << i) - 1)) + 1;
      vec[a[j]].clear();
      Next[j] = 0;
    }
    for (int j = 1; j <= 2 * N; j++) {
      vec[a[j]].push_back(j);
      In[a[j]] = 0;
      col[j] = 0;
    }
    bool flag = 1;
    tim = 0;
    for (int j = 1; j <= 2 * N; j++) {
      if (!col[j] && !col[D(j)])
        ++tim, Root[tim] = j, col[j] = 1, flag &= dfs(D(j), j);
    }
    if (!flag) continue;
    for (int j = 1; j <= tim + (1 << i); j++) Roote[j] = 0, vis[j] = 0;
    cnt = 0;
    for (int j = 1; j <= tim; j++) {
      bool Ad = 0;
      int top = 0;
      for (int d = Root[j]; d;) {
        sta[++top] = make_pair(a[Next[d]], d);
        insert(j, a[Next[d]] + tim, d);
        insert(a[Next[d]] + tim, j, d);
        d = Next[d];
        if (d == Root[j]) break;
      }
    }
    queue<int> que;
    que.push(1);
    vis[1] = 1;
    int sm = 0;
    while (!que.empty()) {
      int k = que.front();
      que.pop();
      if (k > tim) {
        for (int xt = Roote[k]; xt; xt = Nexte[xt]) {
          int v = Node[xt];
          if (vis[v]) continue;
          int d = Cost[xt];
          int x = In[k - tim];
          int y = Next[x];
          Next[x] = Next[d];
          Next[d] = y;
          que.push(v);
          vis[v] = 1;
        }
      } else {
        ++sm;
        for (int x = Roote[k]; x; x = Nexte[x]) {
          int v = Node[x];
          if (vis[v]) continue;
          In[v - tim] = Cost[x];
          que.push(v);
          vis[v] = 1;
        }
      }
    }
    if (tim == sm) {
      printf("%d\n", i);
      int x = Root[1];
      for (int k = 1; k <= N; k++) printf("%d %d ", x, D(x)), x = Next[x];
      break;
    }
  }
  return 0;
}
