#include <bits/stdc++.h>   using namespace std;   template <typename T>   void join(vector<T>& arr, string sep) {     bool first = true;     for (auto t : arr) {       if (first) {         first = false;         cout << t;       } else {         cout << sep << t;       }     }     cout <<   n ;   }   struct Euler {     vector<vector<pair<long long, long long>>> g;     long long n;     vector<long long> path;     long long edge_count;     Euler(long long n) : n(n) {       g.resize(n);       edge_count = 0;     }     void addEdge(long long u, long long v) {       long long w = edge_count++;       g[u].push_back({v, w});       g[v].push_back({u, w});     }     bool compute() {       int first = 0;       while (first < n && g[first].empty()) first++;       if (first == n) return true;       long long v1 = -1, v2 = -1;       for (long long u = 0; u < (long long)(n); ++u) {         if (g[u].size() & 1) {           return false;         }       }       if (v1 != -1) {         assert(v2 != -1);       }       vector<long long> visited(edge_count);       vector<long long> s = {first};       while (!s.empty()) {         long long u = s.back();         long long v;         while (true) {           if (g[u].empty()) {             v = -1;             path.push_back(u);             s.pop_back();             break;           }           long long v = g[u].back().first;           long long w = g[u].back().second;           g[u].pop_back();           if (visited[w]) {             continue;           }           visited[w] = true;           s.push_back(v);           break;         }       }       if (v1 != -1) {         for (long long i = 0; i < (long long)(path.size() - 1); ++i) {           if ((path[i] == v1 && path[i + 1] == v2) ||               (path[i] == v2 && path[i + 1] == v1)) {             vector<long long> res;             for (long long j = (long long)(i + 1); j < (long long)(path.size());                  ++j) {               res.push_back(path[j]);             }             for (long long j = (long long)(1); j < (long long)(i + 1); ++j) {               res.push_back(path[j]);             }             path = res;             break;           }         }       }       for (long long u = 0; u < (long long)(n); ++u) {         if (!g[u].empty()) {           return false;         }       }       return true;     }   };   long long getPref(long long c, long long i) { return ((1 << i) - 1) & c; }   struct PairHash {     int operator()(const pair<long long, long long>& pp) const {       const int p = 31;       const int m = 1e9 + 9;       long long l = pp.first;       long long r = (pp.second * p) % m;       return (l + r) % m;     }   };   void solve() {     long long n;     cin >> n;     vector<pair<long long, long long>> colors(n);     for (long long i = 0; i < (long long)(n); ++i) {       long long a, b;       cin >> a >> b;       colors[i] = {a, b};     }     vector<long long> res;     for (long long i = (long long)(1); i < (long long)(2 * n + 1); ++i) {       res.push_back(i);     }     long long lowest = 0;     long long l = 1;     long long r = 20;     while (l <= r) {       long long i = l + (r - l) / 2;       unordered_map<pair<long long, long long>,                     vector<pair<long long, long long>>, PairHash>           nodes2Idx;       Euler e(1 << i);       for (long long j = 0; j < (long long)(n); ++j) {         long long pref1 = getPref(colors[j].first, i);         long long pref2 = getPref(colors[j].second, i);         long long idx1 = 2 * j + 1;         long long idx2 = 2 * j + 2;         if (pref1 > pref2) {           swap(pref1, pref2);           swap(idx1, idx2);         }         nodes2Idx[{pref1, pref2}].push_back({idx1, idx2});         e.addEdge(pref1, pref2);       }       if (!e.compute()) {         r = i - 1;         continue;       }       l = i + 1;       lowest = i;       assert(e.path.size() == n + 1);       for (long long j = 0; j < (long long)(n); ++j) {         long long pref1 = e.path[j];         long long pref2 = e.path[j + 1];         bool swaped = false;         if (pref1 > pref2) {           swap(pref1, pref2);           swaped = true;         }         auto it = nodes2Idx.find({pref1, pref2});         pair<long long, long long> idxPair = it->second.back();         it->second.pop_back();         long long idx1 = idxPair.first;         long long idx2 = idxPair.second;         if (swaped) swap(idx1, idx2);         res[2 * j] = idx1;         res[2 * j + 1] = idx2;       }     }     cout << lowest <<   n ;     join(res,    );   }   int main() {     ios::sync_with_stdio(false);     cin.tie(0);     solve();     return 0;   }