#include <bits/stdc++.h>
using namespace std;
const int N = (1 << 21) + 5;
int a[N], b[N];
bool used[N], used2[N];
vector<int> gr[N];
void dfs(int node) {
  used[node] = true;
  for (const int &x : gr[node]) {
    if (!used[b[x ^ 1]]) {
      dfs(b[x ^ 1]);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n;
  cin >> n;
  for (int i = 0; i < 2 * n; i++) {
    cin >> a[i];
  }
  for (int i = 20; i >= 0; i--) {
    for (int j = 0; j < 2 * n; j++) {
      b[j] = (a[j] & ((1 << i) - 1));
      gr[b[j]].push_back(j);
    }
    bool fir = false, ok = true;
    int start_ver;
    for (int j = 0; j < (1 << i); j++) {
      if (!gr[j].empty()) {
        start_ver = j;
        if (!used[j]) {
          if (fir) {
            ok = false;
            break;
          }
          fir = true;
          dfs(j);
        }
      }
      if (gr[j].size() & 1) {
        ok = false;
        break;
      }
    }
    if (ok) {
      vector<int> stk = {start_ver};
      vector<pair<int, int>> stk2, ans;
      while (!stk.empty()) {
        int node = stk.back();
        while (!gr[node].empty() && used2[gr[node].back()]) gr[node].pop_back();
        if (gr[node].empty()) {
          stk.pop_back();
          if (!stk2.empty()) {
            ans.push_back(stk2.back());
            stk2.pop_back();
          }
        } else {
          int x = gr[node].back();
          used2[x] = true;
          used2[x ^ 1] = true;
          gr[node].pop_back();
          stk.push_back(b[x ^ 1]);
          stk2.push_back({x ^ 1, x});
        }
      }
      cout << i << "\n";
      for (const auto &p : ans) {
        cout << p.first + 1 << " " << p.second + 1 << " ";
      }
      return 0;
    }
    fill(used2, used2 + n + n, false);
    for (int j = 0; j < (1 << i); j++) {
      used[j] = false;
      gr[j].clear();
    }
  }
  return 0;
}
