#include <bits/stdc++.h>
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")
using namespace std;
inline bool EQ(double a, double b) { return fabs(a - b) < 1e-9; }
inline int msbp(int x) { return 31 - __builtin_clz(x); }
inline int msb(int x) { return 1 << msbp(x); }
const int INF = 0x3f3f3f3f;
const int N = 5e5 + 10;
int n;
pair<int, int> v[N];
int partner(int id) { return ((id - 1) ^ 1) + 1; }
int get_neck(int id) { return ((id - 1) / 2) + 1; }
int get_id(pair<int, int> cur) { return 2 * cur.first - 1 + cur.second; }
pair<int, int> get_pii(int id) {
  pair<int, int> res{get_neck(id), 0};
  if (partner(id) < id) res.second = 1;
  return res;
}
int parent[N], sz[N];
int find(int x) { return parent[x] = (x == parent[x] ? x : find(parent[x])); }
bool disjoint(int x, int y) { return find(x) != find(y); }
void join(int x, int y) {
  if (!disjoint(x, y)) return;
  int newPar = find(x), newChild = find(y);
  sz[newPar] += sz[newChild];
  parent[newChild] = newPar;
}
int dsuSize(int x) { return sz[find(x)]; }
vector<int> get_cycle(int start, vector<int>& l, vector<int>& r) {
  vector<int> res(1, start);
  res.push_back(partner(start));
  int id = start;
  if (id > partner(id))
    id = l[get_neck(id)];
  else
    id = r[get_neck(id)];
  while (id != start) {
    res.push_back(id);
    res.push_back(partner(id));
    if (id > partner(id))
      id = l[get_neck(id)];
    else
      id = r[get_neck(id)];
  }
  return res;
}
bool check(int beauty, bool answer) {
  int hi = 1 << (beauty);
  vector<int> l(n + 1), r(n + 1), all(1);
  vector<vector<pair<int, int>>> rm(hi);
  for (int i = (1); i <= (n); ++i) {
    int a = v[i].first % hi, b = v[i].second % hi;
    rm[a].push_back({i, 0});
    rm[b].push_back({i, 1});
    all.push_back(a);
    all.push_back(b);
  }
  for (int i = 0; i < (hi); ++i) {
    auto& cm = rm[i];
    if (cm.size() & 1) return false;
    for (int j = 0; j < cm.size(); j += 2) {
      auto cur = cm[j];
      auto nxt = cm[j + 1];
      if (cur.second == 0)
        l[cur.first] = get_id(nxt);
      else
        r[cur.first] = get_id(nxt);
      if (nxt.second == 0)
        l[nxt.first] = get_id(cur);
      else
        r[nxt.first] = get_id(cur);
    }
  }
  int cycles = 0;
  vector<unordered_map<int, vector<int>>> ms;
  vector<int> cycle_map(2 * n + 1, -1);
  for (int i = (1); i <= (2 * n); ++i) {
    if (cycle_map[i] != -1) continue;
    unordered_map<int, vector<int>> m;
    auto v = move(get_cycle(i, l, r));
    for (int j = 0; j < (v.size()); ++j) {
      int id = v[j];
      cycle_map[id] = cycles;
      if (j & 1) {
        auto& rv = m[all[id]];
        if (rv.size() == 0) {
          rv.push_back(v[j]);
          rv.push_back(v[(j + 1) % v.size()]);
        }
      }
    }
    ms.emplace_back(m);
    ++cycles;
  }
  std::iota(parent, parent + N, 0), std::fill(sz, sz + N, 1);
  for (int i = 0; i < (hi); ++i) {
    auto& cm = rm[i];
    if (cm.size() == 0) continue;
    auto cur = cm[0];
    for (int j = (1); j <= (cm.size() - 1); ++j) {
      auto nxt = cm[j];
      int cur_id = get_id(cur), nxt_id = get_id(nxt);
      int cur_cycle = cycle_map[cur_id], nxt_cycle = cycle_map[nxt_id];
      if (disjoint(cur_cycle, nxt_cycle)) {
        join(cur_cycle, nxt_cycle);
        pair<int, int> cur_neighbor;
        if (cur.second == 0)
          cur_neighbor = get_pii(l[cur.first]);
        else
          cur_neighbor = get_pii(r[cur.first]);
        pair<int, int> nxt_neighbor;
        if (nxt.second == 0)
          nxt_neighbor = get_pii(l[nxt.first]);
        else
          nxt_neighbor = get_pii(r[nxt.first]);
        if (cur_neighbor.second == 0 && nxt.second == 0)
          l[cur_neighbor.first] = l[nxt.first];
        if (cur_neighbor.second == 0 && nxt.second == 1)
          l[cur_neighbor.first] = r[nxt.first];
        if (cur_neighbor.second == 1 && nxt.second == 0)
          r[cur_neighbor.first] = l[nxt.first];
        if (cur_neighbor.second == 1 && nxt.second == 1)
          r[cur_neighbor.first] = r[nxt.first];
        if (nxt_neighbor.second == 0 && cur.second == 0)
          l[nxt_neighbor.first] = l[cur.first];
        if (nxt_neighbor.second == 0 && cur.second == 1)
          l[nxt_neighbor.first] = r[cur.first];
        if (nxt_neighbor.second == 1 && cur.second == 0)
          r[nxt_neighbor.first] = l[cur.first];
        if (nxt_neighbor.second == 1 && cur.second == 1)
          r[nxt_neighbor.first] = r[cur.first];
        if (cur.second == 0)
          l[cur.first] = get_id(nxt);
        else
          r[cur.first] = get_id(nxt);
        if (nxt.second == 0)
          l[nxt.first] = get_id(cur);
        else
          r[nxt.first] = get_id(cur);
      }
    }
  }
  if (answer) {
    cout << beauty << endl;
    auto v = move(get_cycle(1, l, r));
    for (int x : v) cout << x << ' ';
    cout << endl;
    exit(0);
  } else {
    return dsuSize(0) == cycles;
  }
}
signed main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for (int i = (1); i <= (n); ++i) cin >> v[i].first >> v[i].second;
  int l = 0, r = 20;
  while (l < r) {
    int mid = (l + r + 1) / 2;
    if (check(mid, false))
      l = mid;
    else
      r = mid - 1;
  }
  if (l == 0) {
    cout << 0 << endl;
    for (int i = (1); i <= (2 * n); ++i) cout << i << ' ';
    cout << endl;
  } else {
    check(l, true);
  }
  return 0;
}
