#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
int par[1 << 20], sz[1 << 20];
void init(int n) {
  for (int i = 0; i < n; i++) par[i] = i, sz[i] = 1;
}
int find(int x) {
  if (par[x] == x) return x;
  return par[x] = find(par[x]);
}
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y) return;
  if (sz[x] > sz[y]) swap(x, y);
  par[x] = y;
  sz[y] += sz[x];
}
bool same(int x, int y) { return find(x) == find(y); }
vector<pair<int, int>> G[1 << 20];
bool f[500010];
vector<int> e, ans;
int a[500010], b[500010];
void euler_cycle(int s) {
  while (G[s].size()) {
    if (!f[G[s].back().second]) {
      G[s].pop_back();
    } else {
      int ver = G[s].back().first, id = G[s].back().second;
      f[id] = false;
      euler_cycle(ver);
    }
  }
  e.push_back(s);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int i, j, n;
  cin >> n;
  for (i = 0; i < n; i++) cin >> a[i] >> b[i];
  for (j = 20; j >= 0; j--) {
    for (i = 0; i < (1 << 20); i++) G[i].clear();
    init(1 << 20);
    for (i = 0; i < n; i++) {
      int x = a[i] % (1 << j), y = b[i] % (1 << j);
      unite(x, y);
      G[x].push_back({y, i});
      G[y].push_back({x, i});
    }
    bool flag = true;
    int cnt = 0;
    for (i = 0; i < (1 << 20); i++) {
      if (G[i].size() & 1) flag = false;
      if (G[i].size() && par[i] == i) cnt++;
    }
    if (!flag || cnt > 1) continue;
    int st = -1;
    for (i = 0; i < (1 << 20); i++) {
      if (G[i].size()) st = i;
    }
    for (i = 0; i < n; i++) f[i] = true;
    euler_cycle(st);
    map<pair<int, int>, vector<int>> mp;
    for (i = 0; i < n; i++) {
      mp[{a[i] % (1 << j), b[i] % (1 << j)}].push_back(i);
      f[i] = true;
    }
    for (i = 0; i < n; i++) {
      int x = e[i], y = e[i + 1];
      while (mp[{x, y}].size() && !f[mp[{x, y}].back()]) mp[{x, y}].pop_back();
      while (mp[{y, x}].size() && !f[mp[{y, x}].back()]) mp[{y, x}].pop_back();
      int z;
      if (mp[{x, y}].size())
        z = mp[{x, y}].back(), f[z] = false;
      else
        z = mp[{y, x}].back(), f[z] = false;
      if (a[z] % (1 << j) == x)
        ans.push_back(2 * z + 1), ans.push_back(2 * z + 2);
      else
        ans.push_back(2 * z + 2), ans.push_back(2 * z + 1);
    }
    cout << j << endl;
    for (i = 0; i < 2 * n; i++) cout << ans[i] << " ";
    cout << endl;
    return 0;
  }
}
