#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 5 + 1e5;
struct Edge {
  int to, edgeInd;
  Edge() {}
  Edge(int to, int edgeInd, int nodeInd) {
    this->to = to;
    this->edgeInd = edgeInd;
  }
};
struct Encoder {
  int code = 0;
  map<pair<int, int>, int> num2code;
  int encode(pair<int, int> x) {
    auto it = num2code.find(x);
    if (it == num2code.end()) {
      num2code[x] = code;
      code++;
      return code - 1;
    }
    return it->second;
  }
};
int n;
pair<int, int> a[MAXN];
int adjInd[MAXN];
bool usedEdge[MAXN];
int deg[MAXN];
vector<Edge> graph[MAXN];
vector<int> answer;
int eulerianCircuit(int u, bool recover = false) {
  int len = 0;
  stack<int> st;
  st.push(u);
  while (st.empty() == false) {
    u = st.top();
    while (adjInd[u] != graph[u].size() &&
           usedEdge[graph[u][adjInd[u]].edgeInd] == true)
      adjInd[u]++;
    if (adjInd[u] == graph[u].size()) {
      if (recover == true)
        answer.push_back(u);
      else
        len++;
      st.pop();
    } else {
      st.push(graph[u][adjInd[u]].to);
      usedEdge[graph[u][adjInd[u]].edgeInd] = true;
      adjInd[u]++;
    }
  }
  return len;
}
Encoder E;
vector<int> edges[MAXN];
void InitBit(int bit, bool recover = false) {
  memset(deg, 0, sizeof(int) * ((1LL << bit)));
  memset(adjInd, 0, sizeof(int) * ((1LL << bit)));
  memset(usedEdge, false, sizeof(usedEdge));
  for (int x = 0; x < (1LL << bit); x++) graph[x].clear();
  answer.clear();
  for (int i = 1; i <= n; i++) {
    int x = a[i].first % (1LL << bit);
    int y = a[i].second % (1LL << bit);
    if (recover == true) edges[E.encode({x, y})].push_back(i);
    if (x != y) {
      graph[x].push_back(Edge(y, i, 2 * i));
      graph[y].push_back(Edge(x, i, 2 * i - 1));
      deg[x]++;
      deg[y]++;
    } else {
      graph[x].push_back(Edge(y, i, 2 * i));
    }
  }
}
bool checkBit(int bit) {
  InitBit(bit);
  for (int x = 0; x < (1LL << bit); x++) {
    if (deg[x] % 2 != 0) return false;
  }
  int len = eulerianCircuit(a[1].first % (1LL << bit));
  if (len - 1 != n) return false;
  return true;
}
void restoreBit(int bit) {
  cout << bit << '\n';
  InitBit(bit, true);
  eulerianCircuit(a[1].first % (1LL << bit), true);
  for (int i = 0; i < answer.size() - 1; i++) {
    int x = answer[i];
    int y = answer[i + 1];
    if (edges[E.encode({x, y})].empty() == false) {
      int ind = edges[E.encode({x, y})].back();
      edges[E.encode({x, y})].pop_back();
      cout << ind * 2 - 1 << " " << ind * 2 << " ";
    } else if (edges[E.encode({y, x})].empty() == false) {
      int ind = edges[E.encode({y, x})].back();
      edges[E.encode({y, x})].pop_back();
      cout << ind * 2 << " " << ind * 2 - 1 << " ";
    }
  }
  cout << '\n';
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i].first >> a[i].second;
  }
  int l = 0, r = 20, mid;
  while (l + 1 < r) {
    mid = (l + r) / 2;
    if (checkBit(mid) == true)
      l = mid;
    else
      r = mid - 1;
  }
  if (checkBit(r) == true)
    restoreBit(r);
  else
    restoreBit(l);
}
