#include <bits/stdc++.h>
using namespace std;
const int mx = 1e5 + 5;
long long mod = 1e9 + 9;
struct EqualFunc {
  bool operator()(const pair<long long, long long> &lhs,
                  const pair<long long, long long> &rhs) const {
    return lhs.first == rhs.first && lhs.second == rhs.second;
  }
};
struct HashFunc {
  std::size_t operator()(const pair<long long, long long> &key) const {
    return (hash<long long>()(key.first) ^
            (hash<long long>()(key.second) << 1)) >>
           1;
  }
};
unordered_map<pair<long long, long long>, int, HashFunc, EqualFunc> mp;
vector<int> c[mx];
vector<int> p[mx];
pair<long long, long long> v[mx];
char vis[mx];
bool findup(int x) {
  for (int i : p[x]) {
    if (c[i].size() == 1) {
      return false;
    }
  }
  return true;
}
int main() {
  int m;
  scanf("%d", &m);
  long long a, b;
  for (int i = 1; i <= m; ++i) {
    scanf("%lld%lld", &a, &b);
    mp[{a, b}] = i;
    v[i] = {a, b};
  }
  int now;
  for (auto &i : mp) {
    a = i.first.first;
    b = i.first.second;
    if (mp.count({a - 1, b - 1}) > 0) {
      now = mp[{a - 1, b - 1}];
      p[now].push_back(i.second);
      c[i.second].push_back(now);
    }
    if (mp.count({a, b - 1}) > 0) {
      now = mp[{a, b - 1}];
      p[now].push_back(i.second);
      c[i.second].push_back(now);
    }
    if (mp.count({a + 1, b - 1}) > 0) {
      now = mp[{a + 1, b - 1}];
      p[now].push_back(i.second);
      c[i.second].push_back(now);
    }
  }
  long long res = 0;
  vector<int> q;
  for (int i = 1; i <= m; ++i) {
    if (findup(i)) {
      vis[i] = 1;
      q.push_back(i);
    }
  }
  int bf = 0;
  for (int i = 1; i <= m; ++i) {
    if (i & 1) {
      now = q.back();
      q.pop_back();
    } else {
      now = q[bf];
      bf++;
    }
    res = res * m + now - 1;
    res %= mod;
    vis[now] = 2;
    auto tmp = p[now];
    for (int j : p[now]) {
      c[j].erase(find(c[j].begin(), c[j].end(), now));
      tmp.insert(tmp.end(), c[j].begin(), c[j].end());
    }
    tmp.insert(tmp.end(), c[now].begin(), c[now].end());
    for (int j : c[now]) {
      p[j].erase(find(p[j].begin(), p[j].end(), now));
      tmp.insert(tmp.end(), p[j].begin(), p[j].end());
    }
    c[now].clear();
    a = v[now].first;
    b = v[now].second;
    for (int j : tmp) {
      if (!vis[j] && findup(j)) {
        vis[j] = true;
        q.insert(lower_bound(q.begin() + bf, q.end(), j), j);
      } else if (vis[j] == 1 && !findup(j)) {
        q.erase(lower_bound(q.begin() + bf, q.end(), j));
        vis[j] = false;
      }
    }
  }
  printf("%lld", res);
}
