#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int MX = 2e5 + 5;
template <class T>
bool ckmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
template <typename T>
constexpr auto hasBegin(int) -> decltype(std::begin(std::declval<T>()), true) {
  return true;
}
constexpr bool hasBegin(...) { return false; }
template <typename T>
using IsContainer = std::integral_constant<bool, hasBegin<T>(0)>;
template <typename T>
std::istream &operator>>(std::istream &is, std::vector<T> &vec) {
  for (T &element : vec) {
    is >> element;
  }
  return is;
}
template <typename T, typename U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
  is >> p.first;
  is >> p.second;
  return is;
}
template <class X, class Y>
std::ostream &operator<<(std::ostream &os, std::pair<X, Y> const &p) {
  return os << p.first << " " << p.second;
}
template <class Ch, class Tr, class Container>
std::basic_ostream<Ch, Tr> &operator<<(std::basic_ostream<Ch, Tr> &os,
                                       Container const &x) {
  bool first = true;
  for (auto &y : x) {
    if (first) {
      first = false;
    } else {
      os << " ";
    }
    os << y;
  }
  return os;
}
template <int SZ, bool directed>
struct Euler {
  int N, M = 0;
  vector<pair<int, int>> adj[SZ];
  vector<pair<int, int>>::iterator its[SZ];
  vector<bool> used;
  void addEdge(int a, int b) {
    if (directed)
      adj[a].push_back({b, M});
    else
      adj[a].push_back({b, M}), adj[b].push_back({a, M});
    used.push_back(0);
    M++;
  }
  vector<pair<int, int>> solve(int _N, int src = 0) {
    N = _N;
    for (int i = (0); i < (N); ++i) its[i] = begin(adj[i]);
    vector<pair<pair<int, int>, int>> ret, second = {{{src, -1}, -1}};
    while ((int)second.size()) {
      int x = second.back().first.first;
      auto &it = its[x], end = adj[x].end();
      while (it != end && used[it->second]) it++;
      if (it == end) {
        if ((int)ret.size() &&
            ret.back().first.second != second.back().first.first)
          return {};
        ret.push_back(second.back()), second.pop_back();
      } else {
        second.push_back({{it->first, x}, it->second});
        used[it->second] = 1;
      }
    }
    if ((int)ret.size() != M + 1) return {};
    vector<pair<int, int>> ans;
    for (auto &t : ret) ans.push_back({t.first.first, t.second});
    reverse(begin(ans), end(ans));
    return ans;
  }
  void clear(int _N) {
    N = _N;
    M = 0;
    for (int i = (0); i < (N); ++i) {
      adj[i].clear();
    }
    used.clear();
  }
};
using namespace std;
const int N = 1 << 20;
int counter[N];
Euler<N, false> euler;
class CJohnnyAndMegansNecklace {
  bool first(const vector<int> &A, const vector<int> &B, int lg) {
    int mask = (1 << lg) - 1, n = (int)A.size();
    for (int i = (0); i < (n); ++i) {
      counter[A[i] & mask]++;
      counter[B[i] & mask]++;
    }
    bool res = true;
    for (int i = (0); i < (n); ++i) {
      if (counter[A[i] & mask] % 2) {
        res = false;
      }
      if (counter[B[i] & mask] % 2) {
        res = false;
      }
    }
    for (int i = (0); i < (n); ++i) {
      counter[A[i] & mask]--;
      counter[B[i] & mask]--;
    }
    return res;
  }

 public:
  void solve(std::istream &in, std::ostream &out) {
    int n;
    in >> n;
    vector<int> A(n), B(n);
    for (int i = (0); i < (n); ++i) {
      in >> A[i] >> B[i];
    }
    int res = -1;
    vector<pair<int, int>> path;
    while (res < 20) {
      res++;
      for (int i = (0); i < (n); ++i) {
        int a = A[i] & ((1 << res) - 1), b = B[i] & ((1 << res) - 1);
        euler.addEdge(a, b);
      }
      vector<pair<int, int>> aux =
          euler.solve(1 << res, A[0] & ((1 << res) - 1));
      euler.clear(1 << res);
      if (aux.empty() or not first(A, B, res)) {
        res--;
        break;
      }
      path = aux;
    }
    out << res << '\n';
    for (int i = (1); i < (n + 1); ++i) {
      int ed = path[i].second, u = 2 * ed + 1, v = 2 * ed + 2;
      if ((A[ed] & ((1 << res) - 1)) == path[i].first) {
        swap(u, v);
      }
      out << u << ' ' << v << ' ';
    }
    out << '\n';
  }
  void setup() {}
};
int main() {
  std::ios_base::sync_with_stdio(false);
  CJohnnyAndMegansNecklace solver;
  solver.setup();
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  in.tie(nullptr);
  out << std::fixed;
  out.precision(20);
  solver.solve(in, out);
  return 0;
}
