#include <bits/stdc++.h>
using std::map, std::vector, std::set;
using u32 = std::uint32_t;
struct Edge {
  size_t idx;
  size_t start;
  size_t end;
  bool side;
};
using graph = std::vector<vector<Edge>>;
using EdgeIter = vector<Edge>::const_iterator;
struct EulerFinder {
 private:
  const graph *g;
  u32 start;
  std::vector<EdgeIter> currEdges;
  std::vector<bool> visited;

 public:
  std::vector<Edge> cycle;
  bool success;
  EulerFinder(const graph &g_) : g(&g_) {
    if (g->empty()) {
      success = true;
      return;
    }
    currEdges.resize(g->size());
    size_t total_edges = 0;
    for (size_t v = 0; v < g->size(); v++) {
      currEdges[v] = (*g)[v].cbegin();
      total_edges += (*g)[v].size();
    }
    total_edges /= 2;
    visited = std::vector<bool>(total_edges, false);
    start = 0;
    success = pullCycle(start);
    for (bool isVisited : visited) {
      success &= isVisited;
    }
    if (!success) {
      cycle.clear();
    } else {
      std::reverse(cycle.begin(), cycle.end());
    }
  }
  bool pullCycle(u32 v) {
    auto end = (*g)[v].cend();
    while (currEdges[v] != end) {
      Edge e = *(currEdges[v]++);
      if (visited[e.idx]) continue;
      visited[e.idx] = true;
      if (!pullCycle(e.end)) return false;
      cycle.push_back(e);
    }
    if (cycle.empty()) {
      return v == start;
    } else {
      return cycle.back().start == v;
    }
  }
};
struct Segment {
  u32 start, end;
};
graph condense(const vector<Segment> &segments, u32 mask) {
  std::map<u32, size_t> labels;
  auto makeLabel = [&labels](u32 v) {
    if (labels.find(v) == labels.end()) {
      labels.insert({v, labels.size()});
    }
  };
  for (auto seg : segments) {
    u32 start = seg.start & mask;
    u32 end = seg.end & mask;
    makeLabel(start);
    makeLabel(end);
  }
  graph g(labels.size());
  for (size_t i = 0; i < segments.size(); i++) {
    Segment seg = segments[i];
    size_t start = labels[seg.start & mask];
    size_t end = labels[seg.end & mask];
    g[start].push_back(Edge{i, start, end, false});
    g[end].push_back(Edge{i, end, start, true});
  }
  return g;
}
template <typename TPred>
int binSearch(int min, int max, TPred pred) {
  while (max - min > 1) {
    int mid = (max + min) / 2;
    if (pred(mid))
      min = mid;
    else
      max = mid;
  }
  return min;
}
int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int n;
  std::cin >> n;
  vector<Segment> segments(n);
  for (int i = 0; i < n; i++) {
    std::cin >> segments[i].start >> segments[i].end;
  }
  int bGood = 0;
  int bBad = 21;
  EulerFinder finderSuccess({});
  while (bBad - bGood > 1) {
    int bMid = (bBad + bGood) / 2;
    auto finder = EulerFinder(condense(segments, (1u << bMid) - 1));
    if (finder.success) {
      bGood = bMid;
      finderSuccess = std::move(finder);
    } else {
      bBad = bMid;
    }
  }
  if (bGood == 0) {
    std::cout << "0\n";
    for (int i = 0; i < 2 * n; i++) std::cout << 1 + i << " ";
    std::cout << "\n";
    return 0;
  }
  std::cout << bGood << "\n";
  for (Edge e : finderSuccess.cycle) {
    std::cout << 1 + ((e.idx * 2) ^ e.side) << " "
              << 1 + ((e.idx * 2) ^ (!e.side)) << " ";
  }
  std::cout << "\n";
}
