#include <bits/stdc++.h>
using namespace std;
namespace Euler {
const int MAXN = 1 << 21;
vector<int> g[MAXN], vv[MAXN];
vector<bool> deleted;
vector<int> odds, evens, isolated;
int n;
void reset(int N) {
  n = N;
  deleted.clear();
  for (int i = 0; i < n; i++) g[i].clear(), vv[i].clear();
  odds.clear();
  evens.clear();
  isolated.clear();
}
void addEdge(int x, int y, bool oneBased = false) {
  if (oneBased) x--, y--;
  g[x].push_back(y);
  vv[x].push_back(deleted.size());
  g[y].push_back(x);
  vv[y].push_back(deleted.size());
  deleted.push_back(false);
}
bool isConnected() {
  vector<bool> vis(n, false);
  int src = -1;
  if (!odds.empty()) src = odds[0];
  if (!evens.empty()) src = evens[0];
  if (src == -1) return true;
  queue<int> q;
  q.push(src);
  vis[src] = true;
  int cnt = 0;
  while (!q.empty()) {
    cnt += 1;
    int node = q.front();
    q.pop();
    for (int x : g[node])
      if (!vis[x]) vis[x] = true, q.push(x);
  }
  return cnt == n - int(isolated.size());
}
void process(bool tolerateIsolation = false) {
  evens.clear();
  odds.clear();
  isolated.clear();
  for (int node = 0; node < n; node++)
    if (g[node].size() == 0) {
      if (tolerateIsolation)
        isolated.push_back(node);
      else
        assert(0);
    } else if (g[node].size() % 2 == 0)
      evens.push_back(node);
    else
      odds.push_back(node);
}
bool hasEulerCycle() {
  process(true);
  return odds.empty() && isConnected();
}
bool hasEulerPath() {
  process(true);
  return odds.size() == 2 && isConnected();
}
bool getEulerCycle(vector<int> &circuit, int startNode = -1) {
  circuit.clear();
  if (!hasEulerCycle()) return false;
  if (evens.empty()) return true;
  stack<int> st;
  int src = startNode != -1 ? startNode : evens[0];
  st.push(src);
  while (!st.empty()) {
    int node = st.top();
    while (!vv[node].empty() && deleted[vv[node].back()])
      vv[node].pop_back(), g[node].pop_back();
    if (g[node].empty()) {
      circuit.push_back(node);
      st.pop();
    } else {
      int child = g[node].back();
      deleted[vv[node].back()] = true;
      st.push(child);
    }
  }
  return true;
}
bool getEulerPath(vector<int> &path, int startNode = -1) {
  path.clear();
  if (!hasEulerPath()) return false;
  if (odds.empty()) return true;
  if (startNode != odds[0] && startNode != odds[1] && startNode != -1)
    return false;
  stack<int> st;
  int src = startNode != -1 ? startNode : odds[0];
  st.push(src);
  while (!st.empty()) {
    int node = st.top();
    while (!vv[node].empty() && deleted[vv[node].back()])
      vv[node].pop_back(), g[node].pop_back();
    if (g[node].empty()) {
      path.push_back(node);
      st.pop();
    } else {
      int child = g[node].back();
      deleted[vv[node].back()] = true;
      st.push(child);
    }
  }
  return true;
}
};  // namespace Euler
int n;
int A[500005], B[500005];
vector<pair<pair<int, int>, pair<int, int> > > edges;
vector<pair<pair<int, int>, int> > outputEdges;
pair<int, int> ans[500005];
bool taken[1000005];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) cin >> A[i] >> B[i];
  vector<int> circuit;
  int start = 0, end = 21;
  while (end - start > 1) {
    int mid = (end + start) >> 1;
    edges.clear();
    Euler::reset(1 << mid);
    for (int i = 0; i < n; i++) {
      int x = A[i] & ((1 << mid) - 1);
      int y = B[i] & ((1 << mid) - 1);
      Euler::addEdge(x, y);
    }
    if (!Euler::getEulerCycle(circuit))
      end = mid;
    else
      start = mid;
  }
  int b = start;
  edges.clear();
  Euler::reset(1 << b);
  cout << b << '\n';
  for (int i = 0; i < n; i++) {
    int x = A[i] & ((1 << b) - 1);
    int y = B[i] & ((1 << b) - 1);
    Euler::addEdge(x, y);
    edges.push_back(make_pair(make_pair(x, y), make_pair(i * 2, i * 2 + 1)));
    if (x != y)
      edges.push_back(make_pair(make_pair(y, x), make_pair(i * 2 + 1, i * 2)));
  }
  Euler::getEulerCycle(circuit);
  for (int i = 1; i < int(circuit.size()); i++) {
    int prv = circuit[i - 1], nxt = circuit[i];
    outputEdges.push_back(make_pair(make_pair(prv, nxt), i - 1));
  }
  sort(outputEdges.begin(), outputEdges.end());
  sort(edges.begin(), edges.end());
  int ind = 0;
  for (int i = 0; i < int(outputEdges.size()); i++) {
    while (outputEdges[i].first != edges[ind].first ||
           taken[edges[ind].second.first] || taken[edges[ind].second.second])
      ind++;
    taken[edges[ind].second.first] = true;
    taken[edges[ind].second.second] = true;
    ans[outputEdges[i].second] = edges[ind].second;
    ind++;
  }
  for (int i = 0; i < n; i++)
    cout << ans[i].first + 1 << " " << ans[i].second + 1 << " ";
  cout << '\n';
  return 0;
}
