#include <bits/stdc++.h>   using namespace std;   struct Data {     int64_t value;     int64_t supports;     int64_t supportedBy;   };   bool isTop(map<pair<int64_t, int64_t>, Data> const& cubes,              pair<int64_t, int64_t> const& pos) {     bool top = true;     for (int64_t i = -1; i <= 1; ++i) {       map<pair<int64_t, int64_t>, Data>::const_iterator f =           cubes.find(pair<int64_t, int64_t>{pos.first + i, pos.second + 1});       if (f != cubes.end()) {         if (f->second.supportedBy <= 1) {           top = false;           break;         }       }     }     return top;   }   int main(int, char**) {     ios_base::sync_with_stdio(false);     cin.tie(NULL);     int64_t n;     cin >> n;     map<pair<int64_t, int64_t>, Data> cubes;     for (int64_t i = 0; i < n; ++i) {       int64_t x, y;       cin >> x >> y;       cubes.insert(make_pair(pair<int64_t, int64_t>{x, y}, Data{i, 0, 0}));     }     for (auto& p : cubes) {       Data& data = p.second;       pair<int64_t, int64_t> const& pos = p.first;       if (cubes.find(pair<int64_t, int64_t>{pos.first - 1, pos.second - 1}) !=           cubes.end())         data.supportedBy += 1;       if (cubes.find(pair<int64_t, int64_t>{pos.first, pos.second - 1}) !=           cubes.end())         data.supportedBy += 1;       if (cubes.find(pair<int64_t, int64_t>{pos.first + 1, pos.second - 1}) !=           cubes.end())         data.supportedBy += 1;       if (cubes.find(pair<int64_t, int64_t>{pos.first - 1, pos.second + 1}) !=           cubes.end())         data.supports += 1;       if (cubes.find(pair<int64_t, int64_t>{pos.first, pos.second + 1}) !=           cubes.end())         data.supports += 1;       if (cubes.find(pair<int64_t, int64_t>{pos.first + 1, pos.second + 1}) !=           cubes.end())         data.supports += 1;     }     set<pair<int64_t, pair<int64_t, int64_t> > > tops;     for (auto const& p : cubes) {       int64_t value = p.second.value;       pair<int64_t, int64_t> const& pos = p.first;       if (isTop(cubes, pos))         tops.insert(pair<int64_t, pair<int64_t, int64_t> >{value, pos});     }     int64_t result = 0;     bool smallest = false;     while (!tops.empty()) {       set<pair<int64_t, pair<int64_t, int64_t> > >::iterator used;       if (smallest)         used = tops.begin();       else         used = --tops.end();       smallest = !smallest;       result *= n;       result += used->first;       result %= 1000000009l;       pair<int64_t, int64_t> pos = used->second;       cubes.erase(pos);       tops.erase(used);       set<pair<int64_t, pair<int64_t, int64_t> > > update;       for (int64_t i = -1; i <= 1; ++i) {         {           pair<int64_t, int64_t> pm1{pos.first + i, pos.second - 1};           map<pair<int64_t, int64_t>, Data>::iterator fm1 = cubes.find(pm1);           if (fm1 != cubes.end()) {             fm1->second.supports -= 1;             update.insert(                 pair<int64_t, pair<int64_t, int64_t> >{fm1->second.value, pm1});           }         }         {           pair<int64_t, int64_t> pp1{pos.first + i, pos.second + 1};           map<pair<int64_t, int64_t>, Data>::iterator fp1 = cubes.find(pp1);           if (fp1 != cubes.end()) {             fp1->second.supportedBy -= 1;             update.insert(                 pair<int64_t, pair<int64_t, int64_t> >{fp1->second.value, pp1});             if (fp1->second.supportedBy <= 1) {               for (int64_t j = -1; j <= 1; ++j) {                 pair<int64_t, int64_t> sibP{pp1.first + j, pos.second};                 map<pair<int64_t, int64_t>, Data>::iterator sibI =                     cubes.find(sibP);                 if (sibI != cubes.end()) {                   tops.erase(pair<int64_t, pair<int64_t, int64_t> >{                       sibI->second.value, sibP});                 }               }             }           }         }       }       for (auto const& updatePos : update) {         if (isTop(cubes, updatePos.second)) tops.insert(updatePos);       }     }     cout << result << endl;     return 0;   }