#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000009;
vector<int> G[110000];
vector<int> rG[110000];
int M;
bool used[110000];
set<int> que;
struct node {
  int x, y, n;
  node() {}
  node(int x, int y, int n) : x(x), y(y), n(n) {}
  bool operator<(const node &p) const {
    if (x == p.x) {
      if (y == p.y) return n < p.n;
      return y < p.y;
    }
    return x < p.x;
  }
} B[110000];
bool cmp(const node &a, const node &b) { return a.n < b.n; }
int main() {
  while (cin >> M) {
    long long ans = 0;
    for (int i = 0; i < M; i++) {
      cin >> B[i].x >> B[i].y;
      B[i].n = i;
    }
    sort(B, B + M);
    memset(used, 0, sizeof used);
    memset(G, 0, sizeof G);
    memset(rG, 0, sizeof rG);
    for (int i = 0; i < M; i++) {
      if (!B[i].y) continue;
      for (int j = -1; j <= 1; j++) {
        int pos = upper_bound(B, B + M, node(B[i].x + j, B[i].y - 1, -1)) - B;
        if (pos < M && B[pos].x == B[i].x + j && B[pos].y == B[i].y - 1) {
          G[B[i].n].push_back(B[pos].n);
          rG[B[pos].n].push_back(B[i].n);
        }
      }
    }
    sort(B, B + M, cmp);
    for (int i = 0; i < M; i++) {
      for (int j = 0; j < rG[i].size(); j++) {
        if (G[rG[i][j]].size() == 1) goto fail1;
      }
      que.insert(i);
    fail1:;
    }
    for (int k = 1; k <= M; k++) {
      int v, nv;
      if (k & 1) {
        v = *que.rbegin();
      } else
        v = *que.begin();
      que.erase(v);
      used[v] = true;
      ans = (ans * M % mod + v) % mod;
      for (int i = 0; i < rG[v].size(); i++) {
        int u = rG[v][i], num = 0, nv;
        if (used[u]) continue;
        for (int j = 0; j < G[u].size(); j++) {
          if (G[u][j] == v) continue;
          if (!used[G[u][j]]) {
            nv = G[u][j];
            num++;
          }
        }
        if (num == 1 && que.count(nv)) {
          que.erase(nv);
        }
      }
      for (int i = 0; i < G[v].size(); i++) {
        int u = G[v][i];
        if (used[u] || que.count(u) != 0) continue;
        for (int j = 0; j < rG[u].size(); j++) {
          if (used[rG[u][j]]) continue;
          int nu = rG[u][j], num = 0;
          for (int h = 0; h < G[nu].size(); h++) {
            if (G[nu][h] == u) continue;
            if (!used[G[nu][h]]) num++;
          }
          if (!num) goto fail2;
        }
        que.insert(u);
      fail2:;
      }
    }
    cout << ans << endl;
  }
}
