#include <bits/stdc++.h>
using namespace std;
template <typename... Args>
void db(Args... args) {}
long long CHECK_EULER_TOUR(long long N,
                           vector<pair<long long, long long>> &edge,
                           bool undigraph, long long troot = -1) {
  N = 1049576;
  vector<vector<long long>> L(N);
  for (long long i = 0; i < edge.size(); i++) {
    assert(edge[i].first >= 0 && edge[i].first < N);
    assert(edge[i].second >= 0 && edge[i].second < N);
    if (undigraph) {
      L[edge[i].first].push_back(edge[i].second);
      L[edge[i].second].push_back(edge[i].first);
    } else {
      L[edge[i].first].push_back(edge[i].second);
    }
  }
  vector<long long> ingree(N);
  vector<long long> outgree(N);
  vector<bool> mark(N);
  long long total_edge = 0;
  for (long long i = 0; i < N; i++) {
    total_edge += L[i].size();
    for (auto v : L[i]) {
      outgree[i]++;
      ingree[v]++;
    }
  }
  long long init = -1;
  vector<pair<long long, long long>> odd;
  for (long long i = 0; i < N; i++) {
    if (init == -1 && outgree[i]) init = i;
    if (undigraph) {
      if (outgree[i] & 1) odd.push_back({i, 0});
    } else {
      if (outgree[i] != ingree[i]) odd.push_back({i, outgree[i] - ingree[i]});
    }
  }
  long long root = -1;
  if (odd.size()) {
    return -1;
    if (undigraph) {
      if (odd.size() != 2) return -1;
      if (odd[0].first > odd[1].first) swap(odd[0], odd[1]);
      if (troot != -1) {
        if (troot == odd[0].first)
          root = troot;
        else if (troot == odd[1].first)
          root = troot;
        else
          return -1;
      } else
        root = odd[0].first;
    } else {
      if (odd.size() != 2) return -1;
      if (odd[0].second < odd[1].second) swap(odd[0], odd[1]);
      if (odd[0].second == 1 && odd[1].second == -1) {
        if (troot != -1) {
          if (troot == odd[0].first)
            root = troot;
          else
            return -1;
        } else
          root = odd[0].first;
      } else
        return -1;
    }
  } else {
    if (troot != -1)
      root = troot;
    else
      root = init;
  }
  queue<long long> Q;
  mark[root] = true;
  Q.push(root);
  long long temp_edge = 0;
  while (!Q.empty()) {
    long long nodo = Q.front();
    Q.pop();
    temp_edge += L[nodo].size();
    for (auto v : L[nodo]) {
      if (!mark[v]) {
        mark[v] = true;
        Q.push(v);
      }
    }
  }
  if (total_edge != temp_edge) return -1;
  return root;
}
vector<long long> EULER_TOUR(long long N,
                             vector<pair<long long, long long>> &edge,
                             bool undigraph, long long troot = -1) {
  N = 1049576;
  vector<long long> res;
  long long root = CHECK_EULER_TOUR(N, edge, undigraph, troot);
  if (root == -1) {
    return res;
  }
  vector<vector<long long>> L(N);
  vector<vector<long long>> id(N);
  vector<vector<long long>> inv(N);
  for (long long i = 0; i < edge.size(); i++) {
    if (undigraph) {
      L[edge[i].first].push_back(edge[i].second);
      L[edge[i].second].push_back(edge[i].first);
      id[edge[i].first].push_back(i);
      id[edge[i].second].push_back(i + edge.size());
      if (edge[i].first == edge[i].second) {
        long long sz = inv[edge[i].first].size();
        inv[edge[i].first].push_back(sz + 1);
        inv[edge[i].second].push_back(sz);
      } else {
        long long sz2 = inv[edge[i].second].size();
        long long sz1 = inv[edge[i].first].size();
        inv[edge[i].first].push_back(sz2);
        inv[edge[i].second].push_back(sz1);
      }
    } else {
      L[edge[i].first].push_back(edge[i].second);
      id[edge[i].first].push_back(i);
    }
  }
  vector<vector<bool>> mark(N);
  vector<long long> ptr(N);
  for (long long i = 0; i < N; i++) {
    mark[i].resize(L[i].size());
  }
  stack<pair<long long, long long>> S;
  S.push({root, -1});
  while (!S.empty()) {
    long long nodo = S.top().first;
    while (ptr[nodo] < L[nodo].size() && mark[nodo][ptr[nodo]]) {
      ptr[nodo]++;
    }
    if (ptr[nodo] == L[nodo].size()) {
      res.push_back(S.top().second);
      S.pop();
    } else {
      mark[nodo][ptr[nodo]] = true;
      if (undigraph) mark[L[nodo][ptr[nodo]]][inv[nodo][ptr[nodo]]] = true;
      S.push({L[nodo][ptr[nodo]], id[nodo][ptr[nodo]]});
    }
  }
  reverse(res.begin(), res.end());
  return res;
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  long long N;
  cin >> N;
  vector<pair<long long, long long>> edge;
  for (long long i = 1; i <= N; i++) {
    long long a, b;
    cin >> a >> b;
    edge.push_back({a, b});
  }
  long long sol = 0;
  vector<pair<long long, long long>> temp;
  vector<long long> mp;
  for (long long i = 20; i >= 0; i--) {
    temp = edge;
    for (long long x = 0; x < temp.size(); x++) {
      temp[x].first = temp[x].first & ((1 << i) - 1);
      temp[x].second = temp[x].second & ((1 << i) - 1);
    }
    if (CHECK_EULER_TOUR(mp.size(), temp, 1) != -1) {
      sol = i;
      break;
    }
  }
  cout << sol << '\n';
  db(temp);
  vector<long long> res = EULER_TOUR(mp.size(), temp, 1);
  db(temp.size());
  db(res);
  for (long long i = 1; i < res.size(); i++) {
    if (res[i] >= temp.size()) {
      cout << (res[i] - temp.size() + 1) * 2 << " "
           << (res[i] - temp.size() + 1) * 2 - 1 << " ";
    } else {
      cout << (res[i] + 1) * 2 - 1 << " " << (res[i] + 1) * 2 << " ";
    }
  }
  return 0;
}
