#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>

using namespace std;

#define m_p make_pair
typedef long long LL;
typedef pair <int,int> II;
const int maxn = 1e5+10;
const int maxint = 0x3f3f3f3f;
const LL mod = 1e9+9;

struct mmp{
	LL x , y;
}a[maxn];
LL n , ans , f[maxn] , c[maxn];
priority_queue <LL> qa;
priority_queue <LL,vector<LL>,greater<LL> > qi;
map <pair<LL,LL>,LL> mp;

bool check(LL i)
{
	if (a[i].y == 0) return true;
	LL p;
	p = mp[m_p(a[i].x-1,a[i].y-1)];
	if (p && f[p] == 0) return true;
	p = mp[m_p(a[i].x,a[i].y-1)];
	if (p && f[p] == 0) return true;
	p = mp[m_p(a[i].x+1,a[i].y-1)];
	if (p && f[p] == 0) return true;
	return false;
}

bool check2(LL i)
{
	bool ret=true;
	LL p , pp;
	pp = mp[m_p(a[i].x,a[i].y)];
	mp[m_p(a[i].x,a[i].y)] = 0;
	p = mp[m_p(a[i].x-1,a[i].y+1)];
	if (p && f[p] == 0 && !check(p)) ret = false;
	p = mp[m_p(a[i].x,a[i].y+1)];
	if (p && f[p] == 0 && !check(p)) ret = false;
	p = mp[m_p(a[i].x+1,a[i].y+1)];
	if (p && f[p] == 0 && !check(p)) ret = false;
	mp[m_p(a[i].x,a[i].y)] = pp;
	return ret;
}

void put(LL p)
{
	c[p] == 0;
	qa.push(p);
	qi.push(p);
}

void putin(LL i)
{
	if (a[i].y >= 1)
	{
		LL p;
		p = mp[m_p(a[i].x-1,a[i].y-1)];
		if (p && c[p] == 1 && check2(p)) put(p);
		p = mp[m_p(a[i].x,a[i].y-1)];
		if (p && c[p] == 1 && check2(p)) put(p);
		p = mp[m_p(a[i].x+1,a[i].y-1)];
		if (p && c[p] == 1 && check2(p)) put(p);
	}
	return;
}

void jsma()
{
	while (1)
	{
		while (f[qa.top()] == 1) qa.pop();
		LL i = qa.top();
		qa.pop();
		mp[m_p(a[i].x,a[i].y)] = 0;
		if (check2(i))
		{
			f[i] = 1;
			mp[m_p(a[i].x,a[i].y)] = 0;
			ans = (ans*n+i-1)%mod;
			putin(i);
			mp[m_p(a[i].x,a[i].y)] = i;
			return;
		}
		else c[i] = 1;
		mp[m_p(a[i].x,a[i].y)] = i;
	}
	return;
}

void jsmi()
{
	while (1)
	{
		while (f[qi.top()] == 1) qi.pop();
		LL i = qi.top();
		qi.pop();
		mp[m_p(a[i].x,a[i].y)] = 0;
		if (check2(i))
		{
			f[i] = 1;
			mp[m_p(a[i].x,a[i].y)] = 0;
			ans = (ans*n+i-1)%mod;
			putin(i);
			mp[m_p(a[i].x,a[i].y)] = i;
			return;
		}
		else c[i] = 1;
		mp[m_p(a[i].x,a[i].y)] = i;
	}
	return;
}

int main()
{
	LL i , j , p;
	cin >> n;
	for (i = 1 ; i <= n ; i++)
	{
		scanf("%I64d%I64d",&a[i].x,&a[i].y);
		a[i].x+1;
		a[i].y+1;
		mp[m_p(a[i].x,a[i].y)] = i;
	}
	for (i = 1 ; i <= n ; i++)
	{
		mp[m_p(a[i].x,a[i].y)] = 0;
		if (check2(i))
		{
			qa.push(i);
			qi.push(i);
		}
		else c[i] = 1;
		mp[m_p(a[i].x,a[i].y)] = i;
	}
	for (i = 1 ; i <= n ; i++)
	{
		if (i%2) jsma();
		else jsmi();
	}
	cout << ans << "\n";
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct point{
    int x,y;
    bool operator<(const point p0)const{
        if(y==p0.y)
        return x<p0.x;
        return y<p0.y;
    }
}p;
struct rr{
    int i,k;
}r;
int n;
point a[100005];
const long long mod=1e9+9;
vector<long long> res;
map<int,int> q;
map<point,rr> m;// 位置对应jb
bool vis[100005];
bool ok(point pt){
    // 如果拿走它不会让其他的不稳定 就ok
    // 即上方三个格子下方的数字都不为1则ok
    map<point,rr>::iterator ip;
    point pt2;
    pt2.y=pt.y+1;
    pt2.x=pt.x;
    ip=m.find(pt2);
    if(ip!=m.end()&&ip->second.k==1)return 0;
    pt2.x=pt.x-1;
    ip=m.find(pt2);
    if(ip!=m.end()&&ip->second.k==1)return 0;
    pt2.x=pt.x+1;
    ip=m.find(pt2);
    if(ip!=m.end()&&ip->second.k==1)return 0;
    return 1;
}
void calc(point pt){
    // 吧这个点上面的三个点k--
    map<point,rr>::iterator ip;
    point pt2;
    pt2.y=pt.y+1;
    pt2.x=pt.x;
    ip=m.find(pt2);
    if(ip!=m.end())ip->second.k--;
    pt2.x=pt.x-1;
    ip=m.find(pt2);
    if(ip!=m.end())ip->second.k--;
    pt2.x=pt.x+1;
    ip=m.find(pt2);
    if(ip!=m.end())ip->second.k--;
}
//deque<int> q;
void solve(){
    map<point,rr>::iterator ip;
    point p0;
    for(map<point,rr>::iterator i=m.begin();i!=m.end();i++){
        p=i->first;
        if(p.y==0)i->second.k=999;
        p0.y=p.y-1;
        p0.x=p.x;
        if(m.find(p0)!=m.end())
            i->second.k++;
        p0.x=p.x-1;
        if(m.find(p0)!=m.end())
            i->second.k++;
        p0.x=p.x+1;
        if(m.find(p0)!=m.end())
            i->second.k++;
    }
    for(map<point,rr>::iterator i=m.begin();i!=m.end();i++){
        r=i->second;
        p=i->first;
        if(ok(p))q[r.i]=1,vis[r.i]=1;
    }
    // 选大、选小
    int jb=0;
    // 拿走后 上面三个记得干掉k
    while(1){
        if(q.size()==0)break;
        jb=(--q.end())->first;
        res.push_back(jb);
        q.erase(--q.end());
        m.erase(m.find(a[jb]));
        p=a[jb];
        calc(a[jb]);
        p0.y=p.y-1;
        p0.x=p.x;
        ip=m.find(p0);
        if(ip!=m.end()){
            if(!vis[ip->second.i]&&ok(ip->first))
                q[ip->second.i]=1,vis[ip->second.i]=1;
        }
        p0.x=p.x-1;
        ip=m.find(p0);
        if(ip!=m.end()){
            if(!vis[ip->second.i]&&ok(ip->first))q[ip->second.i]=1,vis[ip->second.i]=1;
        }
        p0.x=p.x+1;
        ip=m.find(p0);
        if(ip!=m.end()){
            if(!vis[ip->second.i]&&ok(ip->first))q[ip->second.i]=1,vis[ip->second.i]=1;
        }

        if(q.size()==0)break;
        jb=(q.begin())->first;
        res.push_back(jb);
        m.erase(m.find(a[jb]));
        q.erase(q.begin());
        p=a[jb];
        calc(a[jb]);
        p0.y=p.y-1;
        p0.x=p.x;
        ip=m.find(p0);
        if(ip!=m.end()){
            if(!vis[ip->second.i]&&ok(ip->first))q[ip->second.i]=1,vis[ip->second.i]=1;
        }
        p0.x=p.x-1;
        ip=m.find(p0);
        if(ip!=m.end()){
            if(!vis[ip->second.i]&&ok(ip->first))q[ip->second.i]=1,vis[ip->second.i]=1;
        }
        p0.x=p.x+1;
        ip=m.find(p0);
        if(ip!=m.end()){
            if(!vis[ip->second.i]&&ok(ip->first))q[ip->second.i]=1,vis[ip->second.i]=1;
        }
    }
    long long ans=0;
    for(int i=0;i<res.size();i++){
        ans*=n;
        ans+=res[i];
        ans%=mod;
    }
    cout<<ans<<endl;
//    for(map<int,int>::iterator i=q.begin();i!=q.end();i++){
//        cout<<i->first<<endl;
//    }

}
int main(){
    ios::sync_with_stdio(false);
 //   freopen("a.txt","r",stdin);
    // M进制
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>p.x>>p.y;
        a[i].x=p.x;
        a[i].y=p.y;
        r.i=i;
        r.k=0;
        m[p]=r;
    }
    solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

struct point{
    int x,y;
    bool operator<(const point p0)const{
        if(y==p0.y)
        return x<p0.x;
        return y<p0.y;
    }
}p;
struct rr{
    int i,k;
}r;
int n;
point a[100005];
//deque<int> q;
const long long mod=1e9+9;
vector<long long> res;
map<int,int> q;
map<point,rr> m;// 位置对应jb
void solve(){
    point p0;
    for(map<point,rr>::iterator i=m.begin();i!=m.end();i++){
        p=i->first;
        p0.y=p.y+1;
        p0.x=p.x;
        if(m.find(p0)!=m.end()){
            i->second.k++;
        }
        p0.x=p.x-1;
        if(m.find(p0)!=m.end()){
            i->second.k++;
        }
        p0.x=p.x+1;
        if(m.find(p0)!=m.end()){
            i->second.k++;
        }
    }
    for(map<point,rr>::iterator i=m.begin();i!=m.end();i++){
        r=i->second;
        if(r.k==0){
            p=i->first;
            q[r.i]=1;
//            m.erase(i);
//            i--;
        }
    }
    // 选大、选小
    int jb=0;
    map<point,rr>::iterator ip;
    while(1){
        if(q.size()==0)break;
        jb=(--q.end())->first;
        res.push_back(jb);
        q.erase(--q.end());
        m.erase(m.find(a[jb]));
        p=a[jb];
        p0.y=p.y-1;
        p0.x=p.x;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
//            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
            if(ip->second.k==0)q[ip->second.i]=1;
        }
        p0.x=p.x-1;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
//            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
            if(ip->second.k==0)q[ip->second.i]=1;
        }
        p0.x=p.x+1;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
//            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
            if(ip->second.k==0)q[ip->second.i]=1;
       }

        if(q.size()==0)break;
        jb=(q.begin())->first;
        res.push_back(jb);
        m.erase(m.find(a[jb]));
        q.erase(q.begin());
        p=a[jb];
        p0.y=p.y-1;
        p0.x=p.x;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
//            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
            if(ip->second.k==0)q[ip->second.i]=1;
        }
        p0.x=p.x-1;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
//            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
            if(ip->second.k==0)q[ip->second.i]=1;
        }
        p0.x=p.x+1;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
//            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
            if(ip->second.k==0)q[ip->second.i]=1;
        }
    }
    long long ans=0;
    for(int i=0;i<res.size();i++){
        ans*=n;
        ans+=res[i];
        ans%=mod;
    }
    cout<<ans<<endl;
//    for(map<int,int>::iterator i=q.begin();i!=q.end();i++){
//        cout<<i->first<<endl;
//    }

}
int main(){
    ios::sync_with_stdio(false);
 //   freopen("a.txt","r",stdin);
    // M进制
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>p.x>>p.y;
        a[i].x=p.x;
        a[i].y=p.y;
        r.i=i;
        r.k=0;
        m[p]=r;
    }
    solve();
    return 0;
}
/*
struct point{
    int x,y;
    bool operator<(const point p0)const{
        if(y==p0.y)
        return x<p0.x;
        return y<p0.y;
    }
}p;
int n;
point a[100005];
//deque<int> q;
vector<int> res;
map<int,int> q;
map<point,int> m;
void solve(){
    point p0;
    for(map<point,int>::iterator i=m.begin();i!=m.end();i++){
        p=i->first;
        p0.y=p.y+1;
        p0.x=p.x;
        if(m.find(p0)!=m.end())continue;
        p0.x=p.x-1;
        if(m.find(p0)!=m.end())continue;
        p0.x=p.x+1;
        if(m.find(p0)!=m.end())continue;
        q[i->second]=1;
    }
    // 选大、选小
    int jb=0;
    while(1){
        if(q.size()==0)break;
        jb=(--q.end())->first;
        res.push_back(jb-1);
        p=a[jb];
        q.erase(--q.end());
        if(q.size()==0)break;
        res.push_back((q.begin())->first-1);
        q.erase(q.begin());
    }
//    for(map<int,int>::iterator i=q.begin();i!=q.end();i++){
//        cout<<i->first<<endl;
//    }

}
int main(){
    ios::sync_with_stdio(false);
    freopen("a.txt","r",stdin);
    // M进制
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>p.x>>p.y;
        a[i].x=p.x;
        a[i].y=p.y;
        m[p]=i;
    }
    solve();
    return 0;
}
*/
/*
string s,t;
int main(){
  //  freopen("a.txt","r",stdin);
    cin>>s>>t;
    int j=0;
    int l=-1,r=-1;
    for(int i=0;i<t.length();i++){
        if(t[i]==s[j])j++;
        if(j==s.length()){
            l=i;break;
        }
    }
    j=s.length()-1;
    for(int i=t.length()-1;i>=0;i--){
        if(t[i]==s[j])j--;
        if(j==-1){
            r=i;break;
        }
    }
    if(l==-1||r==-1||l>=r)cout<<0<<endl;
    else cout<<r-l<<endl;
    return 0;
}
*/
/*
string s[205];
char s2[205][205];
int main(){
   // freopen("a.txt","r",stdin);
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)cin>>s[i];
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            s2[i][j]=s[j][i];
        }s2[i][m]='\0';
//        cout<<s2[i]<<endl;
    }
    for(int i=0;i<2*n;i++){
        for(int j=0;j<2*m;j++){
            cout<<s2[i/2][j/2];
        }cout<<"\n";
    }
    // i,j ->
    return 0;
}
*/
/*
struct point{
    int v,i;
}a[200005];
int w[200005],h[200005];
bool cmp(point p1,point p2){
    return p1.v<p2.v;
}
int main(){
 //   freopen("a.txt","r",stdin);
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int s=0;
    for(int i=0;i<n;i++){
        cin>>w[i]>>h[i];
        a[i].v=h[i];
        s+=w[i];
        a[i].i=i;
    }
    sort(a,a+n,cmp);
    for(int i=0;i<n;i++){
        if(h[i]==a[n-1].v){
            printf("%d ",a[n-2].v*(s-w[i]));
        }else{
            printf("%d ",a[n-1].v*(s-w[i]));
        }
    }
    return 0;
}
*/


#include <bits/stdc++.h>
using namespace std;

struct point{
    int x,y;
    bool operator<(const point p0)const{
        if(y==p0.y)
        return x<p0.x;
        return y<p0.y;
    }
}p;
struct rr{
    int i,k;
}r;
int n;
point a[100005];
//deque<int> q;
const long long mod=1e9+9;
vector<long long> res;
map<int,int> q;
map<point,rr> m;// 位置对应jb
void solve(){
    point p0;
    for(map<point,rr>::iterator i=m.begin();i!=m.end();i++){
        p=i->first;
        p0.y=p.y+1;
        p0.x=p.x;
        if(m.find(p0)!=m.end()){
            i->second.k++;
        }
        p0.x=p.x-1;
        if(m.find(p0)!=m.end()){
            i->second.k++;
        }
        p0.x=p.x+1;
        if(m.find(p0)!=m.end()){
            i->second.k++;
        }
    }
    for(map<point,rr>::iterator i=m.begin();i!=m.end();i++){
        r=i->second;
        if(r.k==0){
            q[r.i]=1;
            m.erase(i);
            i--;
        }
    }
    // 选大、选小
    int jb=0;
    map<point,rr>::iterator ip;
    while(1){
        if(q.size()==0)break;
        jb=(--q.end())->first;
        res.push_back(jb);
        q.erase(--q.end());
        p=a[jb];
        p0.y=p.y-1;
        p0.x=p.x;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
        }
        p0.x=p.x-1;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
        }
        p0.x=p.x+1;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
        }

        if(q.size()==0)break;
        jb=(q.begin())->first;
        res.push_back(jb);
        q.erase(q.begin());
        p=a[jb];
        p0.y=p.y-1;
        p0.x=p.x;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
        }
        p0.x=p.x-1;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
        }
        p0.x=p.x+1;
        ip=m.find(p0);
        if(ip!=m.end()){
            ip->second.k--;
            if(ip->second.k==0)q[ip->second.i]=1,m.erase(ip);
        }
    }
    long long ans=0;
    for(int i=0;i<res.size();i++){
        ans*=n;
        ans+=res[i];
        ans%=mod;
    }
    cout<<ans<<endl;
//    for(map<int,int>::iterator i=q.begin();i!=q.end();i++){
//        cout<<i->first<<endl;
//    }

}
int main(){
    ios::sync_with_stdio(false);
  //  freopen("a.txt","r",stdin);
    // M进制
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>p.x>>p.y;
        a[i].x=p.x;
        a[i].y=p.y;
        r.i=i;
        r.k=0;
        m[p]=r;
    }
    solve();
    return 0;
}
/*
struct point{
    int x,y;
    bool operator<(const point p0)const{
        if(y==p0.y)
        return x<p0.x;
        return y<p0.y;
    }
}p;
int n;
point a[100005];
//deque<int> q;
vector<int> res;
map<int,int> q;
map<point,int> m;
void solve(){
    point p0;
    for(map<point,int>::iterator i=m.begin();i!=m.end();i++){
        p=i->first;
        p0.y=p.y+1;
        p0.x=p.x;
        if(m.find(p0)!=m.end())continue;
        p0.x=p.x-1;
        if(m.find(p0)!=m.end())continue;
        p0.x=p.x+1;
        if(m.find(p0)!=m.end())continue;
        q[i->second]=1;
    }
    // 选大、选小
    int jb=0;
    while(1){
        if(q.size()==0)break;
        jb=(--q.end())->first;
        res.push_back(jb-1);
        p=a[jb];
        q.erase(--q.end());
        if(q.size()==0)break;
        res.push_back((q.begin())->first-1);
        q.erase(q.begin());
    }
//    for(map<int,int>::iterator i=q.begin();i!=q.end();i++){
//        cout<<i->first<<endl;
//    }

}
int main(){
    ios::sync_with_stdio(false);
    freopen("a.txt","r",stdin);
    // M进制
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>p.x>>p.y;
        a[i].x=p.x;
        a[i].y=p.y;
        m[p]=i;
    }
    solve();
    return 0;
}
*/
/*
string s,t;
int main(){
  //  freopen("a.txt","r",stdin);
    cin>>s>>t;
    int j=0;
    int l=-1,r=-1;
    for(int i=0;i<t.length();i++){
        if(t[i]==s[j])j++;
        if(j==s.length()){
            l=i;break;
        }
    }
    j=s.length()-1;
    for(int i=t.length()-1;i>=0;i--){
        if(t[i]==s[j])j--;
        if(j==-1){
            r=i;break;
        }
    }
    if(l==-1||r==-1||l>=r)cout<<0<<endl;
    else cout<<r-l<<endl;
    return 0;
}
*/
/*
string s[205];
char s2[205][205];
int main(){
   // freopen("a.txt","r",stdin);
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)cin>>s[i];
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            s2[i][j]=s[j][i];
        }s2[i][m]='\0';
//        cout<<s2[i]<<endl;
    }
    for(int i=0;i<2*n;i++){
        for(int j=0;j<2*m;j++){
            cout<<s2[i/2][j/2];
        }cout<<"\n";
    }
    // i,j ->
    return 0;
}
*/
/*
struct point{
    int v,i;
}a[200005];
int w[200005],h[200005];
bool cmp(point p1,point p2){
    return p1.v<p2.v;
}
int main(){
 //   freopen("a.txt","r",stdin);
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int s=0;
    for(int i=0;i<n;i++){
        cin>>w[i]>>h[i];
        a[i].v=h[i];
        s+=w[i];
        a[i].i=i;
    }
    sort(a,a+n,cmp);
    for(int i=0;i<n;i++){
        if(h[i]==a[n-1].v){
            printf("%d ",a[n-2].v*(s-w[i]));
        }else{
            printf("%d ",a[n-1].v*(s-w[i]));
        }
    }
    return 0;
}
*/


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
#define N 100010
const int mod=1e9+9;
ll pown[N];
struct node
{
    int x,y,id;
    node(int x,int y,int id):x(x),y(y),id(id){}
    bool operator<(const node&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{             //����ȳ�
    bool operator()(const node&a,const node&b){
        return a.id<b.id;
    }
};
struct cmp2{
    bool operator()(const node&a,const node&b){
        return a.id>b.id;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node& t){
    if(s.count(t)==0)
        return 1;
    return s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
}
inline bool canmove(const node& t){
    if(!s.erase(t)){
        return 0;
    }
    int tmp=stable(node(t.x-1,t.y+1,0))&&
    stable(node(t.x,t.y+1,0))&&
    stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return tmp;
}
int main(){
    //freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);

        pown[0]=1;
        rep(i,1,n)
            pown[i]=pown[i-1]*n%mod;
        s.clear();
        rep(i,0,n){
            int x,y;
            scanf("%d%d",&x,&y);
            s.insert(node(x,y,i));
        }
        while(!big.empty()){
            big.pop();
        }
        while(!small.empty()){
            small.pop();
        }
        for(IT it=s.begin();it!=s.end();++it){
            node tmp=*it;
            if(canmove(tmp)){
                big.push(tmp);
                small.push(tmp);
            }
        }
        ll ans=0;
        node u=node(0,0,0);
        node v=node(0,0,0);
        per(i,0,n){
            if(i&1){    //������С�ĳ�
                while(!small.empty()){
                    u=small.top();
                    small.pop();
                    if(canmove(u))
                        break;
                }
            }
            else{
                while(!big.empty()){
                    u=big.top();
                    big.pop();
                    if(canmove(u))
                        break;
                }
            }
            ans=(ans+pown[i]*u.id%mod)%mod;
            //printf("u.id=%d\n",u.id);
            s.erase(u);
            IT it=s.find(node(u.x-1,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
            it=s.find(node(u.x,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
            it=s.find(node(u.x+1,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
        }
        cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
#define N 100010
const int mod=1e9+9;
ll f[N];
struct node
{
    int x,y,t;
    node(int x,int y,int t):x(x),y(y),t(t){}
    bool operator<(const node&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{
    bool operator()(const node&a,const node&b){
        return a.t<b.t;
    }
};
struct cmp2{
    bool operator()(const node&a,const node&b){
        return a.t>b.t;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node&t){
    if(!s.count(t)){
        return 1;
    }
    int flag=s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
    return flag;
}
inline bool canmove(const node&t){
    if(!s.erase(t)){
        return 0;
    }
    bool flag=stable(node(t.x-1,t.y+1,0))
    &&stable(node(t.x,t.y+1,0))
    &&stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return flag;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);
    f[0]=1;
    rep(i,1,n) f[i]=f[i-1]*n%mod;
    rep(i,0,n){
        int x,y;
        scanf("%d%d",&x,&y);
        s.insert(node(x,y,i));
    }
    for(IT it=s.begin();it!=s.end();){
        IT jt=it;
        ++jt;
        node tmp=*it;
        if(canmove(tmp)){
            big.push(tmp);
            small.push(tmp);
        }
        it=jt;
    }
    ll ans=0;
    per(i,0,n){
        node u=node(0,0,0);
        node v=node(0,0,0);
        if((n-i)&1){
            while(!big.empty()){
                u=big.top();
                big.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        else{
            while(!small.empty()){
                u=small.top();
                small.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        s.erase(u);
        ans=(ans+u.t*f[i]%mod)%mod;
        IT it=s.find(node(u.x-1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x+1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
#define N 100010
const int mod=1e9+9;
ll pown[N];
struct node
{
    int x,y,id;
    node(int x,int y,int id):x(x),y(y),id(id){}
    bool operator<(const node&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{             //����ȳ�
    bool operator()(const node&a,const node&b){
        return a.id<b.id;
    }
};
struct cmp2{
    bool operator()(const node&a,const node&b){
        return a.id>b.id;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node& t){
    if(s.count(t)==0)
        return 1;
    return s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
}
inline bool canmove(const node& t){
    if(!s.erase(t)){
        return 0;
    }
    int tmp=stable(node(t.x-1,t.y+1,0))&&
    stable(node(t.x,t.y+1,0))&&
    stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return tmp;
}
int main(){
    freopen("in.txt","r",stdin);
    int i,n;
    while(~scanf("%d",&n)){
        pown[0]=1;
        rep(i,1,n)
            pown[i]=pown[i-1]*n%mod;
        s.clear();
        rep(i,0,n){
            int x,y;
            scanf("%d%d",&x,&y);
            s.insert(node(x,y,i));
        }
        while(!big.empty()){
            big.pop();
        }
        while(!small.empty()){
            small.pop();
        }
        for(IT it=s.begin();it!=s.end();++it){
            node tmp=*it;
            if(canmove(tmp)){
                big.push(tmp);
                small.push(tmp);
            }
        }
        ll ans=0;
        node u=node(0,0,0);
        node v=node(0,0,0);
        per(i,0,n){
            if(i&1){    //������С�ĳ�
                while(!small.empty()){
                    u=small.top();
                    small.pop();
                    if(canmove(u))
                        break;
                }
            }
            else{
                while(!big.empty()){
                    u=big.top();
                    big.pop();
                    if(canmove(u))
                        break;
                }
            }
            ans=(ans+pown[i]*u.id%mod)%mod;
            //printf("u.id=%d\n",u.id);
            s.erase(u);
            IT it=s.find(node(u.x-1,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
            it=s.find(node(u.x,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
            it=s.find(node(u.x+1,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
#define N 100010
const int mod=1e9+9;
ll pown[N];
struct node{
    int x,y,t;
    node (int x,int y,int t):x(x),y(y),t(t){}
    bool operator<(const node &a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{
    bool operator()(node &a,node&b){
        return a.t<b.t;
    }
};
struct cmp2{
    bool operator()(node &a,node &b){
        return a.t>b.t;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node&t){
    if(!s.count(t)){
        return 1;
    }
    bool f=s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
    return f;
}
inline bool canmove(const node &t){
    if(!s.erase(t)){
        return 0;
    }
    bool f=stable(node(t.x-1,t.y+1,0))&&
    stable(node(t.x,t.y+1,0))&&
    stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return f;
}
int main(){
   // freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);
    pown[0]=1;
    rep(i,1,n){
        pown[i]=pown[i-1]*n%mod;
    }
    int x,y;
    rep(i,0,n){
        scanf("%d%d",&x,&y);
        s.insert(node(x,y,i));
    }
    node u=node(0,0,0);
    for(IT it=s.begin();it!=s.end();++it){
        u=*it;
        //printf("u.t=%d ",u.t);
        if(canmove(u)){
            big.push(u);
            small.push(u);
           // printf("first in u.id=%d\n",u.t);
        }
    }
    node v=node(0,0,0);
    ll ans=0;
    per(i,0,n){
        if(i&1){
            while(!big.empty()){
                u=big.top();
                big.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        else{
            while(!small.empty()){
                u=small.top();
                small.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        ans=(ans+(u.t*pown[i])%mod)%mod;
        s.erase(u);
      //  printf("u.id=%d ",u.t);
        //printf("ans=%I64d\n",ans);
        IT it=s.find(node(u.x-1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x+1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        /*printf("i=%d :",i);
        for(IT it=s.begin();it!=s.end();++it){
            printf("u.t=%d ",(*it).t);
        }
        printf("\n");*/
    }
    printf("%I64d\n",ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
#define N 100010
const int mod=1e9+9;
ll pown[N];
struct node{
    int x,y,t;
    node (int x,int y,int t):x(x),y(y),t(t){}
    bool operator<(const node &a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{
    bool operator()(node &a,node&b){
        return a.t<b.t;
    }
};
struct cmp2{
    bool operator()(node &a,node &b){
        return a.t>b.t;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node&t){
    if(!s.count(t)){
        return 1;
    }
    bool f=s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
    return f;
}
inline bool canmove(const node &t){
    if(!s.erase(t)){
        return 0;
    }
    bool f=stable(node(t.x-1,t.y+1,0))&&
    stable(node(t.x,t.y+1,0))&&
    stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return f;
}
int main(){
   // freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);
    pown[0]=1;
    rep(i,1,n){
        pown[i]=pown[i-1]*n%mod;
    }
    int x,y;
    rep(i,0,n){
        scanf("%d%d",&x,&y);
        s.insert(node(x,y,i));
    }
    node u=node(0,0,0);
    for(IT it=s.begin();it!=s.end();++it){
        u=*it;
        //printf("u.t=%d ",u.t);
        if(canmove(u)){
            big.push(u);
            small.push(u);
           // printf("first in u.id=%d\n",u.t);
        }
    }
    node v=node(0,0,0);
    ll ans=0;
    per(i,0,n){
        if((n-i)&1){
            while(!big.empty()){
                u=big.top();
                big.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        else{
            while(!small.empty()){
                u=small.top();
                small.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        ans=(ans+(u.t*pown[i])%mod)%mod;
        s.erase(u);
      //  printf("u.id=%d ",u.t);
        //printf("ans=%I64d\n",ans);
        IT it=s.find(node(u.x-1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x+1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        /*printf("i=%d :",i);
        for(IT it=s.begin();it!=s.end();++it){
            printf("u.t=%d ",(*it).t);
        }
        printf("\n");*/
    }
    printf("%I64d\n",ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
#define N 100010
const int mod=1e9+9;
ll pown[N];
struct node
{
    int x,y,id;
    node(int x,int y,int id):x(x),y(y),id(id){}
    bool operator<(const node&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{             //����ȳ�
    bool operator()(const node&a,const node&b){
        return a.id<b.id;
    }
};
struct cmp2{
    bool operator()(const node&a,const node&b){
        return a.id>b.id;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node& t){
    if(s.count(t)==0)
        return 1;
    return s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
}
inline bool canmove(const node& t){
    if(!s.erase(t)){
        return 0;
    }
    int tmp=stable(node(t.x-1,t.y+1,0))&&
    stable(node(t.x,t.y+1,0))&&
    stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return tmp;
}
int main(){
    freopen("in.txt","r",stdin);
    int i,n;
    while(~scanf("%d",&n)){
        pown[0]=1;
        rep(i,1,n)
            pown[i]=pown[i-1]*n%mod;
        rep(i,0,n){
            int x,y;
            scanf("%d%d",&x,&y);
            s.insert(node(x,y,i));
        }
        set<node>::iterator it;
        for(it=s.begin();it!=s.end();++it){
            node tmp=*it;
            if(canmove(tmp)){
                big.push(tmp);
                small.push(tmp);
            }
        }
        ll ans=0;
        node u=node(0,0,0);
        node v=node(0,0,0);
        per(i,0,n){
            if(i&1){    //������С�ĳ�
                while(!small.empty()){
                    u=small.top();
                    small.pop();
                    if(canmove(u))
                        break;
                }
            }
            else{
                while(!big.empty()){
                    u=big.top();
                    big.pop();
                    if(canmove(u))
                        break;
                }
            }
            ans=(ans+pown[i]*u.id%mod)%mod;
            printf("u.id=%d\n",u.id);
            s.erase(u);
            IT it=s.find(node(u.x-1,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
            it=s.find(node(u.x,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
            it=s.find(node(u.x+1,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
#define N 110010
const int mod=1e9+9;
ll pown[N];
struct node{
    int x,y,t;
    node (int x,int y,int t):x(x),y(y),t(t){}
    bool operator<(const node &a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{
    bool operator()(node &a,node&b){
        return a.t<b.t;
    }
};
struct cmp2{
    bool operator()(node &a,node &b){
        return a.t>b.t;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node&t){
    if(!s.count(t)){
        return 1;
    }
    bool f=s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
    return f;
}
inline bool canmove(const node &t){
    if(!s.erase(t)){
        return 0;
    }
    bool f=stable(node(t.x-1,t.y+1,0))&&
    stable(node(t.x,t.y+1,0))&&
    stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return f;
}
int main(){
   // freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);
    pown[0]=1;
    rep(i,1,n){
        pown[i]=pown[i-1]*n%mod;
    }
    int x,y;
    rep(i,0,n){
        scanf("%d%d",&x,&y);
        s.insert(node(x,y,i));
    }
    for(IT it=s.begin();it!=s.end();){
        IT jt=it;
        ++jt;
        node u=*it;
        if(canmove(u)){
            big.push(u);
            small.push(u);
        }
        it=jt;
    }
    ll ans=0;
    per(i,0,n){
        node u=node(0,0,0);
        node v=node(0,0,0);
        if((n-i)&1){
            while(!big.empty()){
                u=big.top();
                big.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        else{
            while(!small.empty()){
                u=small.top();
                small.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        ans=(ans+(u.t*pown[i])%mod)%mod;
        s.erase(u);
      //  printf("u.id=%d ",u.t);
        //printf("ans=%I64d\n",ans);
        IT it=s.find(node(u.x-1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x+1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        /*printf("i=%d :",i);
        for(IT it=s.begin();it!=s.end();++it){
            printf("u.t=%d ",(*it).t);
        }
        printf("\n");*/
    }
    printf("%I64d\n",ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
#define N 100010
const int mod=1e9+9;
ll f[N];
struct node
{
    int x,y,t;
    node(int x,int y,int t):x(x),y(y),t(t){}
    bool operator<(const node&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{
    bool operator()(const node&a,const node&b){
        return a.t<b.t;
    }
};
struct cmp2{
    bool operator()(const node&a,const node&b){
        return a.t>b.t;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node&t){
    if(!s.count(t)){
        return 1;
    }
    int flag=s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
    return flag;
}
inline bool canmove(const node&t){
    if(!s.erase(t)){
        return 0;
    }
    bool flag=stable(node(t.x-1,t.y+1,0))
    &&stable(node(t.x,t.y+1,0))
    &&stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return flag;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);
    f[0]=1;
    rep(i,1,n) f[i]=f[i-1]*n%mod;
    rep(i,0,n){
        int x,y;
        scanf("%d%d",&x,&y);
        s.insert(node(x,y,i));
    }
    for(IT it=s.begin();it!=s.end();++it){
        //IT jt=it;
       // ++jt;
        node tmp=*it;
        if(canmove(tmp)){
            big.push(tmp);
            small.push(tmp);
        }
        //it=jt;
    }
    ll ans=0;
    node u=node(0,0,0);
    node v=node(0,0,0);
    per(i,0,n){
        if((n-i)&1){
            while(!big.empty()){
                u=big.top();
                big.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        else{
            while(!small.empty()){
                u=small.top();
                small.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        s.erase(u);
        ans=(ans+u.t*f[i]%mod)%mod;
        IT it=s.find(node(u.x-1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x+1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
#define N 100010
const int mod=1e9+9;
ll f[N];
struct node
{
    int x,y,t;
    node(int x,int y,int t):x(x),y(y),t(t){}
    bool operator<(const node&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{
    bool operator()(const node&a,const node&b){
        return a.t<b.t;
    }
};
struct cmp2{
    bool operator()(const node&a,const node&b){
        return a.t>b.t;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node&t){
    if(!s.count(t)){
        return 1;
    }
    int flag=s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
    return flag;
}
inline bool canmove(const node&t){
    if(!s.erase(t)){
        return 0;
    }
    bool flag=stable(node(t.x-1,t.y+1,0))
    &&stable(node(t.x,t.y+1,0))
    &&stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return flag;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);
    f[0]=1;
    rep(i,1,n) f[i]=f[i-1]*n%mod;
    rep(i,0,n){
        int x,y;
        scanf("%d%d",&x,&y);
        s.insert(node(x,y,i));
    }
    for(IT it=s.begin();it!=s.end();++it){
        IT jt=it;
        node tmp=*jt;
        if(canmove(tmp)){
            big.push(tmp);
            small.push(tmp);
        }
    }
    ll ans=0;
    node u=node(0,0,0);
    node v=node(0,0,0);
    per(i,0,n){
        if((n-i)&1){
            while(!big.empty()){
                u=big.top();
                big.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        else{
            while(!small.empty()){
                u=small.top();
                small.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        s.erase(u);
        ans=(ans+u.t*f[i]%mod)%mod;
        IT it=s.find(node(u.x-1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x+1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
#define N 100010
const int mod=1e9+9;
ll pown[N];
struct node
{
    int x,y,id;
    node(int x,int y,int id):x(x),y(y),id(id){}
    bool operator<(const node&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{             //����ȳ�
    bool operator()(const node&a,const node&b){
        return a.id<b.id;
    }
};
struct cmp2{
    bool operator()(const node&a,const node&b){
        return a.id>b.id;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node& t){
    if(s.count(t)==0)
        return 1;
    return s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
}
inline bool canmove(const node& t){
    if(!s.erase(t)){
        return 0;
    }
    int tmp=stable(node(t.x-1,t.y+1,0))&&
    stable(node(t.x,t.y+1,0))&&
    stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return tmp;
}
int main(){
    //freopen("in.txt","r",stdin);
    int i,n;
    while(~scanf("%d",&n)){
        pown[0]=1;
        rep(i,1,n)
            pown[i]=pown[i-1]*n%mod;
        s.clear();
        rep(i,0,n){
            int x,y;
            scanf("%d%d",&x,&y);
            s.insert(node(x,y,i));
        }
        while(!big.empty()){
            big.pop();
        }
        while(!small.empty()){
            small.pop();
        }
        for(IT it=s.begin();it!=s.end();++it){
            node tmp=*it;
            if(canmove(tmp)){
                big.push(tmp);
                small.push(tmp);
            }
        }
        ll ans=0;
        node u=node(0,0,0);
        node v=node(0,0,0);
        per(i,0,n){
            if(i&1){    //������С�ĳ�
                while(!small.empty()){
                    u=small.top();
                    small.pop();
                    if(canmove(u))
                        break;
                }
            }
            else{
                while(!big.empty()){
                    u=big.top();
                    big.pop();
                    if(canmove(u))
                        break;
                }
            }
            ans=(ans+pown[i]*u.id%mod)%mod;
            //printf("u.id=%d\n",u.id);
            s.erase(u);
            IT it=s.find(node(u.x-1,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
            it=s.find(node(u.x,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
            it=s.find(node(u.x+1,u.y-1,0));
            if(it!=s.end()&&canmove(v=*it)){
                big.push(v);
                small.push(v);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
#define N 100010
const int mod=1e9+9;
ll f[N];
struct node
{
    int x,y,t;
    node(int x,int y,int t):x(x),y(y),t(t){}
    bool operator<(const node&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
};
set<node>s;
typedef set<node>::iterator IT;
struct cmp1{
    bool operator()(const node&a,const node&b){
        return a.t<b.t;
    }
};
struct cmp2{
    bool operator()(const node&a,const node&b){
        return a.t>b.t;
    }
};
priority_queue<node,vector<node>,cmp1>big;
priority_queue<node,vector<node>,cmp2>small;
inline bool stable(const node&t){
    if(!s.count(t)){
        return 1;
    }
    int flag=s.count(node(t.x-1,t.y-1,0))
    ||s.count(node(t.x,t.y-1,0))
    ||s.count(node(t.x+1,t.y-1,0));
    return flag;
}
inline bool canmove(const node&t){
    if(!s.erase(t)){
        return 0;
    }
    bool flag=stable(node(t.x-1,t.y+1,0))
    &&stable(node(t.x,t.y+1,0))
    &&stable(node(t.x+1,t.y+1,0));
    s.insert(t);
    return flag;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);
    f[0]=1;
    rep(i,1,n) f[i]=f[i-1]*n%mod;
    rep(i,0,n){
        int x,y;
        scanf("%d%d",&x,&y);
        s.insert(node(x,y,i));
    }
    for(IT it=s.begin();it!=s.end();){
        IT jt=it;
        ++jt;
        node tmp=*it;
        if(canmove(tmp)){
            big.push(tmp);
            small.push(tmp);
        }
        it=jt;
    }
    ll ans=0;
    node u=node(0,0,0);
    node v=node(0,0,0);
    per(i,0,n){
        if((n-i)&1){
            while(!big.empty()){
                u=big.top();
                big.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        else{
            while(!small.empty()){
                u=small.top();
                small.pop();
                if(canmove(u)){
                    break;
                }
            }
        }
        s.erase(u);
        ans=(ans+u.t*f[i]%mod)%mod;
        IT it=s.find(node(u.x-1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
        it=s.find(node(u.x+1,u.y-1,0));
        if(it!=s.end()&&canmove(v=*it)){
            big.push(v);
            small.push(v);
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (i=a;i<n;i++)
#define per(i,a,n) for (i=n-1;i>=a;i--)
#define pb push_back
#define mp makepair
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
#define N 100010
PII a[N];
map<PII,int>p;
int dx[3]={-1,0,1};
int indeg[N];
int vis[N];
struct node1
{
    int x,y,id;
    bool friend operator<(node1 a,node1 b){
        return a.id<b.id;
    }
};
struct node2
{
    int x,y,id;
    bool friend operator<(node2 a,node2 b){
        return a.id>b.id;
    }
};
const int mod=1e9+9;
priority_queue<node1>q1;
priority_queue<node2>q2;
bool if_psh(PII t){   //��������Ƿ�������
    if(vis[p[t]])
        return false;
    int i,tmp;
    PII pa;
    pa.se=t.se+1;
    rep(i,0,3){
        pa.fi=t.fi+dx[i];
        tmp=p[pa];
        if(!tmp)
            continue;
        if(!vis[tmp]){
            return false;
        }
    }
    return true;
}

void psh1(PII t){  //���1
    node1 cur;
    cur.x=t.fi;
    cur.y=t.se;
    cur.id=p[t];
    //printf("q1 input x=%d y=%d id=%d\n",cur.x,cur.y,cur.id);
    q1.push(cur);
}

void psh2(PII t){  //���2
    node2 cur;
    cur.x=t.fi;
    cur.y=t.se;
    cur.id=p[t];
    //printf("q2 input x=%d y=%d id=%d\n",cur.x,cur.y,cur.id);
    q2.push(cur);
}

void if_add(PII t){  //�Ƴ��÷����Ƿ����µķ���������
    int i;
    PII pa;
    if(t.se==0)
        return ;
    pa.se=t.se-1;
    rep(i,0,3){  //��һ�㷽���Ƿ�������
        pa.fi=t.fi+dx[i];
        int tmp=p[pa];
        if(tmp==0)
            continue;
        if(if_psh(pa)){
            int ru=1;
            psh1(pa);
            psh2(pa);
        }
    }
}

void fun(int n){
    int i;
    PII pa;
    ll ans=0;
    node1 cur1;
    node2 cur2;
    while(!q1.empty()){
        q1.pop();
    }
    while(!q2.empty()){
        q2.pop();
    }
    rep(i,0,n){   //��ӣ��ҳ������Ƴ��ķ���
        if(if_psh(a[i])){
            psh1(a[i]);
            psh2(a[i]);
        }
    }
    mem(vis,0);
    while(1){
        int flag=0;
        while(!q1.empty()){
            cur1=q1.top();
            q1.pop();
            pa.fi=cur1.x;
            pa.se=cur1.y;
            int tmp=p[pa];
            if(vis[tmp]){
                continue;
            }
            flag=vis[tmp]=1;
            ans=ans*n+cur1.id-1;
            ans%=mod;
            //printf("yi  %d %d %d ans=%lld\n",cur1.x,cur1.y,cur1.id,ans);
            if_add(pa);     //�ж��Ƿ����µķ���������
            break;
        }
        if(flag==0)
            break;
        flag=0;
        while(!q2.empty()){
            cur2=q2.top();
            q2.pop();
            pa.fi=cur2.x;
            pa.se=cur2.y;
            int tmp=p[pa];
            if(vis[tmp]){
                continue;
            }
            flag=vis[tmp]=1;
            ans=ans*n+cur2.id-1;
            ans%=mod;
            //printf("yi  %d %d %d ans=%lld\n",cur2.x,cur2.y,cur2.id,ans);
            if_add(pa);
            break;
        }
        if(flag==0)
            break;
    }
    cout<<ans<<endl;
}
int main(){
    //freopen("in.txt","r",stdin);
    int i,j,n;
    PII pa;
    while(~scanf("%d",&n)){
        rep(i,0,n){
            scanf("%d%d",&a[i].fi,&a[i].se);
            p[a[i]]=i+1;        //ԭʼ�±�
        }
        mem(indeg,0);         //��ʾ���˹�ϵ
        rep(i,0,n){      //�������˹�ϵ
            pa.se=a[i].se+1;
            //printf("x=%d y=%d: \n",a[i].fi,a[i].se);
            rep(j,0,3){
                pa.fi=a[i].fi+dx[j];
                int tmp=p[pa];
                if(tmp==0){
                    continue;
                }
                ++indeg[tmp];
               // printf("x %d y %d tmp=%d indeg[tmp]=%d\n",pa.fi,pa.se,tmp,indeg[tmp]);
            }
        }
       // rep(i,0,n) printf("indeg[i]=%d \n",indeg[i]);
        fun(n);
    }
    return 0;
}


#include<iostream>
#include<map>
#include<set>
using namespace std;
#define ll long long int
#define pp pair<ll,ll>
#define Max 210005
map<pp,ll> a;
map<ll,bool> dl;
set<ll> inus;
pp in[Max];
ll n;
bool av(ll x,ll y)
{
		if(a.count(pp(x,y+1))&&(!dl.count(a[pp(x,y+1)])))
			if((!a.count(pp(x-1,y)))&&(!a.count(pp(x+1,y))))
				return false;
		if(a.count(pp(x-1,y+1))&&(!dl.count(a[pp(x-1,y+1)])))
			if((!a.count(pp(x-2,y)))&&(!a.count(pp(x-1,y))))
				return false;
		if(a.count(pp(x+1,y+1))&&(!dl.count(a[pp(x+1,y+1)])))
			if((!a.count(pp(x+1,y)))&&(!a.count(pp(x+2,y))))
				return false;
		return true;
}
bool ex(ll x,ll y)
{
	return (a.count(pp(x,y))&&!dl.count(a[pp(x,y)]));
}
void del(ll t)
{
	ll x=in[t].first;
	ll y=in[t].second;
	//making av
	if(y!=0)
	{
		if(ex(x,y-1))
		if( (!ex(x+1,y)) || ex(x+1,y-1) || ex(x+2,y-1) )
		{
			if( (!ex(x-1,y)) || ex(x-1,y-1) || ex(x-2,y-1) )
				inus.insert(a[pp(x,y-1)]);
		}

		if(ex(x+1,y-1))
		if( (!ex(x+1,y)) || ex(x,y-1) || ex(x+2,y-1) )
		{
			if( (!ex(x+2,y)) || ex(x+2,y-1) || ex(x+3,y-1) )
				inus.insert(a[pp(x+1,y-1)]);
		}

		if(ex(x-1,y-1))
		if( (!ex(x-1,y)) || ex(x,y-1) || ex(x-2,y-1) )
		{
			if( (!ex(x-2,y)) || ex(x-2,y-1) || ex(x-3,y-1) )
				inus.insert(a[pp(x-1,y-1)]);
		}
	}
	//making unav
	if(ex(x,y+1))
	{
		if(!ex(x-1,y))
		{
			inus.erase(a[pp(x+1,y)]);
		}
		if(!ex(x+1,y))
		{
			inus.erase(a[pp(x-1,y)]);
		}
	}
	if(ex(x+1,y+1))
	{
		if(!ex(x+1,y))
		{
			inus.erase(a[pp(x+2,y)]);
		}
		if(!ex(x+2,y))
		{
			inus.erase(a[pp(x+1,y)]);
		}
	}
	if(ex(x-1,y+1))
	{
		if(!ex(x-1,y))
		{
			inus.erase(a[pp(x-2,y)]);
		}
		if(!ex(x-2,y))
		{
			inus.erase(a[pp(x-1,y)]);
		}
	}
}

int main()
{
	ll x,y;
	ll i,j;
	cin>>n;
	for(i=0;i<n;++i)
	{
		cin>>x>>y;
		a[pp(x,y)]=i;
		in[i]=pp(x,y);
	}

	for(i=0;i<n;++i)
	{
		x=in[i].first;
		y=in[i].second;
		if(av(x,y))
		{
	//		cout<<a[pp(x,y)]<<" ";
			inus.insert(a[pp(x,y)]);
		}
	}
	//cout<<endl;
	set<ll>::iterator it;

	/*
	for(it=inus.begin();it!=inus.end();++it)
		cout<<*it<<" ";
	cout<<endl;
	system("pause");
	*/

	ll pl=0;
	ll now;
	ll sum=0;
	while(!inus.empty())
	{
		if(pl%2==0)
		{
			it=inus.end();
			it--;
		}
		else
			it=inus.begin();
		now=*it;
		pl++;
		//cout<<now<<endl;
		inus.erase(now);
		dl[now]=true;
		del(now);
		//cout<<now<<endl;
		sum*=n;
		sum+=now;
        sum%= 1000000009;
	}
	cout<<sum<<endl;
	return 0;
}


#include<iostream>
#include<map>
#include<set>
using namespace std;
#define ll long long int
#define pp pair<ll,ll>
#define Max 210005
map<pp,ll> a;
map<ll,bool> dl;
set<ll> inus;
pp in[Max];
ll n;
bool av(ll x,ll y)
{
        if(a.count(pp(x,y+1))&&(!dl.count(a[pp(x,y+1)])))
            if((!a.count(pp(x-1,y)))&&(!a.count(pp(x+1,y))))
                return false;
        if(a.count(pp(x-1,y+1))&&(!dl.count(a[pp(x-1,y+1)])))
            if((!a.count(pp(x-2,y)))&&(!a.count(pp(x-1,y))))
                return false;
        if(a.count(pp(x+1,y+1))&&(!dl.count(a[pp(x+1,y+1)])))
            if((!a.count(pp(x+1,y)))&&(!a.count(pp(x+2,y))))
                return false;
        return true;
}
void del(ll t)
{
    ll x=in[t].first;
    ll y=in[t].second;
    //making av
    if(y!=0)
    {
        if(a.count(pp(x,y-1)))
        if(!a.count(pp(x+1,y))||dl.count(a[pp(x+1,y)]))
        {
            if(!a.count(pp(x-1,y))||dl.count(a[pp(x-1,y)]))
                inus.insert(a[pp(x,y-1)]);
        }

        if(a.count(pp(x+1,y-1)))
        if(!a.count(pp(x+1,y))||dl.count(a[pp(x+1,y)]))
        {
            if(!a.count(pp(x+2,y))||dl.count(a[pp(x+2,y)]))
                inus.insert(a[pp(x+1,y-1)]);
        }

        if(a.count(pp(x-1,y-1)))
        if(!a.count(pp(x-1,y))||dl.count(a[pp(x-1,y)]))
        {
            if(!a.count(pp(x-2,y))||dl.count(a[pp(x-2,y)]))
                inus.insert(a[pp(x-1,y-1)]);
        }
    }
    //making unav
    if(a.count(pp(x,y+1))&&(!dl.count(a[pp(x,y+1)])))
    {
        if(!a.count(pp(x-1,y)))
        {
            inus.erase(a[pp(x+1,y)]);
        }
        if(!a.count(pp(x+1,y)))
        {
            inus.erase(a[pp(x-1,y)]);
        }
    }
    if(a.count(pp(x+1,y+1))&&(!dl.count(a[pp(x+1,y+1)])))
    {
        if(!a.count(pp(x+1,y)))
        {
            inus.erase(a[pp(x+2,y)]);
        }
        if(!a.count(pp(x+2,y)))
        {
            inus.erase(a[pp(x+1,y)]);
        }
    }
    if(a.count(pp(x-1,y+1))&&(!dl.count(a[pp(x-1,y+1)])))
    {
        if(!a.count(pp(x-1,y)))
        {
            inus.erase(a[pp(x-2,y)]);
        }
        if(!a.count(pp(x-2,y)))
        {
            inus.erase(a[pp(x-1,y)]);
        }
    }
}

int main()
{
    ll x,y;
    ll i,j;
    cin>>n;
    for(i=0;i<n;++i)
    {
        cin>>x>>y;
        a[pp(x,y)]=i;
        in[i]=pp(x,y);
    }

    for(i=0;i<n;++i)
    {
        x=in[i].first;
        y=in[i].second;
        if(av(x,y))
        {
        //  cout<<a[pp(x,y)]<<endl;
            inus.insert(a[pp(x,y)]);
        }
    }
    set<ll>::iterator it;

    /*
    for(it=inus.begin();it!=inus.end();++it)
        cout<<*it<<" ";
    cout<<endl;
    system("pause");
    */

    ll pl=0;
    ll now;
    ll sum=0;
    while(!inus.empty())
    {
        if(pl%2==0)
        {
            it=inus.end();
            it--;
        }
        else
            it=inus.begin();
        now=*it;
        pl++;
        //cout<<now<<endl;
        inus.erase(now);
        dl[now]=true;
        del(now);
        sum*=n;
        sum+=now;
        sum%= 1000000009;
    }
    cout<<sum<<endl;
    return 0;
}


#include<iostream>
#include<map>
#include<set>
using namespace std;
#define ll long long int
#define pp pair<ll,ll>
#define Max 210005
map<pp,ll> a;
map<ll,bool> dl;
set<ll> inus;
pp in[Max];
ll n;
bool av(ll x,ll y)
{
        if(a.count(pp(x,y+1))&&(!dl.count(a[pp(x,y+1)])))
            if((!a.count(pp(x-1,y)))&&(!a.count(pp(x+1,y))))
                return false;
        if(a.count(pp(x-1,y+1))&&(!dl.count(a[pp(x-1,y+1)])))
            if((!a.count(pp(x-2,y)))&&(!a.count(pp(x-1,y))))
                return false;
        if(a.count(pp(x+1,y+1))&&(!dl.count(a[pp(x+1,y+1)])))
            if((!a.count(pp(x+1,y)))&&(!a.count(pp(x+2,y))))
                return false;
        return true;
}
void del(ll t)
{
    ll x=in[t].first;
    ll y=in[t].second;
    //making av
    if(y!=0)
    {
        if(a.count(pp(x,y-1)))
        if(!a.count(pp(x+1,y))||dl.count(a[pp(x+1,y)]))
        {
            if(!a.count(pp(x-1,y))||dl.count(a[pp(x-1,y)]))
                inus.insert(a[pp(x,y-1)]);
        }

        if(a.count(pp(x+1,y-1)))
        if(!a.count(pp(x+1,y))||dl.count(a[pp(x+1,y)]))
        {
            if(!a.count(pp(x+2,y))||dl.count(a[pp(x+2,y)]))
                inus.insert(a[pp(x+1,y-1)]);
        }

        if(a.count(pp(x-1,y-1)))
        if(!a.count(pp(x-1,y))||dl.count(a[pp(x-1,y)]))
        {
            if(!a.count(pp(x-2,y))||dl.count(a[pp(x-2,y)]))
                inus.insert(a[pp(x-1,y-1)]);
        }
    }
    //making unav
    if(a.count(pp(x,y+1))&&(!dl.count(a[pp(x,y+1)])))
    {
        if(!a.count(pp(x-1,y)))
        {
            inus.erase(a[pp(x+1,y)]);
        }
        if(!a.count(pp(x+1,y)))
        {
            inus.erase(a[pp(x-1,y)]);
        }
    }
    if(a.count(pp(x+1,y+1))&&(!dl.count(a[pp(x+1,y+1)])))
    {
        if(!a.count(pp(x+1,y)))
        {
            inus.erase(a[pp(x+2,y)]);
        }
        if(!a.count(pp(x+2,y)))
        {
            inus.erase(a[pp(x+1,y)]);
        }
    }
    if(a.count(pp(x-1,y+1))&&(!dl.count(a[pp(x-1,y+1)])))
    {
        if(!a.count(pp(x-1,y)))
        {
            inus.erase(a[pp(x-2,y)]);
        }
        if(!a.count(pp(x-2,y)))
        {
            inus.erase(a[pp(x-1,y)]);
        }
    }
}

int main()
{
    ll x,y;
    ll i,j;
    cin>>n;
    for(i=0;i<n;++i)
    {
        cin>>x>>y;
        a[pp(x,y)]=i;
        in[i]=pp(x,y);
    }

    for(i=0;i<n;++i)
    {
        x=in[i].first;
        y=in[i].second;
        if(av(x,y))
        {
        //  cout<<a[pp(x,y)]<<endl;
            inus.insert(a[pp(x,y)]);
        }
    }
    set<ll>::iterator it;

    /*
    for(it=inus.begin();it!=inus.end();++it)
        cout<<*it<<" ";
    cout<<endl;
    system("pause");
    */

    ll pl=0;
    ll now;
    ll sum=0;
    while(!inus.empty())
    {
        if(pl%2==0)
        {
            it=inus.end();
            it--;
        }
        else
            it=inus.begin();
        now=*it;
        pl++;
        //cout<<now<<endl;
        inus.erase(now);
        dl[now]=true;
        del(now);
        sum*=n;
        sum+=now;
    }
    cout<<sum<<endl;
    return 0;
}


    #include<iostream>
#include<map>
#include<set>
using namespace std;
#define ll long long int
#define pp pair<ll,ll>
#define Max 210005
map<pp,ll> a;
map<ll,bool> dl;
set<ll> inus;
pp in[Max];
ll n;
bool av(ll x,ll y)
{
        if(a.count(pp(x,y+1))&&(!dl.count(a[pp(x,y+1)])))
            if((!a.count(pp(x-1,y)))&&(!a.count(pp(x+1,y))))
                return false;
        if(a.count(pp(x-1,y+1))&&(!dl.count(a[pp(x-1,y+1)])))
            if((!a.count(pp(x-2,y)))&&(!a.count(pp(x-1,y))))
                return false;
        if(a.count(pp(x+1,y+1))&&(!dl.count(a[pp(x+1,y+1)])))
            if((!a.count(pp(x+1,y)))&&(!a.count(pp(x+2,y))))
                return false;
        return true;
}
void del(ll t)
{
    ll x=in[t].first;
    ll y=in[t].second;
    //making av
    if(y!=0)
    {
        if(a.count(pp(x,y-1))&&!dl.count(a[pp(x,y-1)]))
        if(!a.count(pp(x+1,y))||dl.count(a[pp(x+1,y)]))
        {
            if(!a.count(pp(x-1,y))||dl.count(a[pp(x-1,y)]))
                inus.insert(a[pp(x,y-1)]);
        }

        if(a.count(pp(x+1,y-1))&&!dl.count(a[pp(x+1,y-1)]))
        if(!a.count(pp(x+1,y))||dl.count(a[pp(x+1,y)]))
        {
            if(!a.count(pp(x+2,y))||dl.count(a[pp(x+2,y)]))
                inus.insert(a[pp(x+1,y-1)]);
        }

        if(a.count(pp(x-1,y-1))&&!dl.count(a[pp(x-1,y-1)]))//
        if(!a.count(pp(x-1,y))||dl.count(a[pp(x-1,y)]))
        {
            if(!a.count(pp(x-2,y))||dl.count(a[pp(x-2,y)]))
                inus.insert(a[pp(x-1,y-1)]);
        }
    }
    //making unav
    if(a.count(pp(x,y+1))&&(!dl.count(a[pp(x,y+1)])))
    {
        if(!a.count(pp(x-1,y)))
        {
            inus.erase(a[pp(x+1,y)]);
        }
        if(!a.count(pp(x+1,y)))
        {
            inus.erase(a[pp(x-1,y)]);
        }
    }
    if(a.count(pp(x+1,y+1))&&(!dl.count(a[pp(x+1,y+1)])))
    {
        if(!a.count(pp(x+1,y)))
        {
            inus.erase(a[pp(x+2,y)]);
        }
        if(!a.count(pp(x+2,y)))
        {
            inus.erase(a[pp(x+1,y)]);
        }
    }
    if(a.count(pp(x-1,y+1))&&(!dl.count(a[pp(x-1,y+1)])))
    {
        if(!a.count(pp(x-1,y)))
        {
            inus.erase(a[pp(x-2,y)]);
        }
        if(!a.count(pp(x-2,y)))
        {
            inus.erase(a[pp(x-1,y)]);
        }
    }
}

int main()
{
    ll x,y;
    ll i,j;
    cin>>n;
    for(i=0;i<n;++i)
    {
        cin>>x>>y;
        a[pp(x,y)]=i;
        in[i]=pp(x,y);
    }

    for(i=0;i<n;++i)
    {
        x=in[i].first;
        y=in[i].second;
        if(av(x,y))
        {
        //  cout<<a[pp(x,y)]<<endl;
            inus.insert(a[pp(x,y)]);
        }
    }
    set<ll>::iterator it;

    /*
    for(it=inus.begin();it!=inus.end();++it)
        cout<<*it<<" ";
    cout<<endl;
    system("pause");
    */

    ll pl=0;
    ll now;
    ll sum=0;
    while(!inus.empty())
    {
        if(pl%2==0)
        {
            it=inus.end();
            it--;
        }
        else
            it=inus.begin();
        now=*it;
        pl++;
        //cout<<now<<endl;
        inus.erase(now);
        dl[now]=true;
        del(now);
        sum*=n;
        sum+=now;
        sum%= 1000000009;
    }
    cout<<sum<<endl;
    return 0;
}


#include <algorithm>
#include <bitset>
#include <limits>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <functional>
#include <map>
#include <queue>
#include <utility>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
const int MOD = 1000000009;
map< pair<int, int>, int> ex;
vector<int> ab[100000], be[100000];
pair<int, int> co[100000];
priority_queue<int> hq;
priority_queue<int, vector<int>, greater<int> > lq;
bitset<100000> rem;
map< pair<int, int>, int>::iterator it;
int N, power[100001], ans;
bool flag;

int main ()
{
	ios_base::sync_with_stdio (false);

#ifndef ONLINE_JUDGE
	freopen ("input0.txt", "r", stdin);
	freopen ("output.txt", "w", stdout);
#endif

	cin >> N;
	power[0] = 1;
	for (int a = 1;a <= N;a++)
		power[a] = (int)((ll)N * power[a - 1] % MOD);

	for (int a = 0;a < N;a++)
	{
		cin >> co[a].first >> co[a].second;
		ex.insert (make_pair (co[a], a));
	}

	for (int a = 0;a < N;a++)
	{
		for (int b = co[a].first - 1;b < co[a].first + 2;b++)
		{
			it = ex.find (make_pair (b, co[a].second + 1));
			if (it != ex.end ())
			{
				ab[a].push_back (it->second);
				be[it->second].push_back (a);
			}
		}
	}

	for (int a = 0;a < N;a++)
	{
		if (ab[a].empty ())
			lq.push (a),
			hq.push (a);
		else
		{
			flag = true;
			for (int b = 0;b < ab[a].size ();b++)
			{
				if (be[ab[a][b]].size () < 2)
				{
					flag = false;
					break;
				}
			}

			if (flag)
				lq.push (a),
				hq.push (a);
		}
	}

	rem.reset ();
	for (int a = N - 1, b;a >= 0;a--)
	{
		if (((N - 1 - a) & 1) == 0)
		{
			while (true)
			{
				flag = true;
				for (int c = 0;c < ab[hq.top ()].size ();c++)
				{
					if (be[ab[hq.top ()][c]].size () < 2)
					{
						flag = false;
						break;
					}
				}
				if (rem[hq.top ()] == false && flag)
					break;
				hq.pop ();
			}
			b = hq.top ();
			hq.pop ();
		}
		else
		{
			while (true)
			{
				flag = true;
				for (int c = 0;c < ab[lq.top ()].size ();c++)
				{
					if (be[ab[lq.top ()][c]].size () < 2)
					{
						flag = false;
						break;
					}
				}
				if (rem[lq.top ()] == false && flag)
					break;
				lq.pop ();
			}
			b = lq.top ();
			lq.pop ();
		}

		rem[b] = true;
		ans = ((ll)ans + (ll)power[a] * b) % MOD;

		for (int c = 0;c < be[b].size ();c++)
		{
			ab[be[b][c]].erase (find (ab[be[b][c]].begin (), ab[be[b][c]].end (), b));
			if (ab[be[b][c]].empty ())
				lq.push (be[b][c]),
				hq.push (be[b][c]);
		}
	}

	cout << ans;

	return 0;
}


#include <algorithm>
#include <bitset>
#include <limits>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <functional>
#include <map>
#include <queue>
#include <utility>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
const int MOD = 1e9+9;
map< pair<int, int>, int> ex;
vector<int> ab[100000], be[100000];
pair<int, int> co[100000];
priority_queue<int> hq;
priority_queue<int, vector<int>, greater<int> > lq;
bitset<100000> rem;
map< pair<int, int>, int>::iterator it;
int N, ans;
bool flag;

int main ()
{
	ios_base::sync_with_stdio (false);

#ifndef ONLINE_JUDGE
	freopen ("input0.txt", "r", stdin);
	freopen ("output.txt", "w", stdout);
#endif

	cin >> N;

	for (int a = 0;a < N;a++)
	{
		cin >> co[a].first >> co[a].second;
		ex.insert (make_pair (co[a], a));
	}

	for (int a = 0;a < N;a++)
	{
		for (int b = co[a].first - 1;b <= co[a].first + 1;b++)
		{
			it = ex.find (make_pair (b, co[a].second + 1));
			if (it != ex.end ())
			{
				ab[a].push_back (it->second);
				be[it->second].push_back (a);
			}
		}
	}

	for (int a = 0;a < N;a++)
	{
		if (ab[a].empty ())
			lq.push (a),
			hq.push (a);
		else
		{
			flag = true;
			for (int b = 0;b < ab[a].size ();b++)
			{
				if (be[ab[a][b]].size () < 2)
				{
					flag = false;
					break;
				}
			}

			if (flag)
				lq.push (a),
				hq.push (a);
		}
	}

	rem.reset ();
	for (int a = N - 1, b;a >= 0;a--)
	{
		if (((N - 1 - a) & 1) == 0)
		{
			while (true)
			{
				if (rem[hq.top ()] == true)
				{
					hq.pop ();
					continue;
				}
				flag = true;
				for (int c = 0;c < ab[hq.top ()].size ();c++)
				{
					if (be[ab[hq.top ()][c]].size () < 2)
					{
						flag = false;
						break;
					}
				}
				if (flag)
					break;
				hq.pop ();
			}
			b = hq.top ();
			hq.pop ();
		}
		else
		{
			while (true)
			{
				if (rem[lq.top ()] == true)
				{
					lq.pop ();
					continue;
				}
				flag = true;
				for (int c = 0;c < ab[lq.top ()].size ();c++)
				{
					if (be[ab[lq.top ()][c]].size () < 2)
					{
						flag = false;
						break;
					}
				}
				if (flag)
					break;
				lq.pop ();
			}
			b = lq.top ();
			lq.pop ();
		}

		rem[b] = true;
		ans = ((ll)ans * N + b) % MOD;

		for (int c = 0;c < be[b].size ();c++)
		{
			ab[be[b][c]].erase (find (ab[be[b][c]].begin (), ab[be[b][c]].end (), b));
			if (ab[be[b][c]].empty ())
				lq.push (be[b][c]),
				hq.push (be[b][c]);
		}
	}

	cout << ans;

	return 0;
}


#include <algorithm>
#include <bitset>
#include <limits>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <functional>
#include <map>
#include <queue>
#include <utility>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
const int MOD = 1e9+9;
map< pair<int, int>, int> ex;
vector<int> ab[100000], be[100000];
pair<int, int> co[100000];
priority_queue<int> hq;
priority_queue<int, vector<int>, greater<int> > lq;
bitset<100000> rem;
map< pair<int, int>, int>::iterator it;
int N, ans;
bool flag;

int main ()
{
	ios_base::sync_with_stdio (false);

#ifndef ONLINE_JUDGE
	freopen ("input0.txt", "r", stdin);
	freopen ("output.txt", "w", stdout);
#endif

	cin >> N;

	for (int a = 0;a < N;a++)
	{
		cin >> co[a].first >> co[a].second;
		ex.insert (make_pair (co[a], a));
	}

	for (int a = 0;a < N;a++)
	{
		for (int b = co[a].first - 1;b <= co[a].first + 1;b++)
		{
			it = ex.find (make_pair (b, co[a].second + 1));
			if (it != ex.end ())
			{
				ab[a].push_back (it->second);
				be[it->second].push_back (a);
			}
		}
	}

	for (int a = 0;a < N;a++)
	{
		flag = true;
		for (int b = 0;b < ab[a].size ();b++)
		{
			if (be[ab[a][b]].size () < 2)
			{
				flag = false;
				break;
			}
		}

		if (flag)
			lq.push (a),
			hq.push (a);
	}

	rem.reset ();
	for (int a = N - 1, b;a >= 0;a--)
	{
		if (((N - 1 - a) & 1) == 0)
		{
			while (true)
			{
				if (rem[hq.top ()] == true)
				{
					hq.pop ();
					continue;
				}
				flag = true;
				for (int c = 0;c < ab[hq.top ()].size ();c++)
				{
					if (be[ab[hq.top ()][c]].size () < 2)
					{
						flag = false;
						break;
					}
				}
				if (flag)
					break;
				hq.pop ();
			}
			b = hq.top ();
			hq.pop ();
		}
		else
		{
			while (true)
			{
				if (rem[lq.top ()] == true)
				{
					lq.pop ();
					continue;
				}
				flag = true;
				for (int c = 0;c < ab[lq.top ()].size ();c++)
				{
					if (be[ab[lq.top ()][c]].size () < 2)
					{
						flag = false;
						break;
					}
				}
				if (flag)
					break;
				lq.pop ();
			}
			b = lq.top ();
			lq.pop ();
		}

		rem[b] = true;
		ans = ((ll)ans * N + b) % MOD;

		for (int c = 0;c < be[b].size ();c++)
		{
			ab[be[b][c]].erase (find (ab[be[b][c]].begin (), ab[be[b][c]].end (), b));
			flag = true;
			for (int d = 0;d < ab[be[b][c]].size ();d++)
			{
				if (be[ab[be[b][c]][d]].size () < 2)
				{
					flag = false;
					break;
				}
			}

			if (flag)
				lq.push (be[b][c]),
				hq.push (be[b][c]);
		}
		for (int c = 0;c < ab[b].size ();c++)
			be[ab[b][c]].erase (find (be[ab[b][c]].begin (), be[ab[b][c]].end (), b));
	}

	cout << ans;

	return 0;
}


#include <algorithm>
#include <bitset>
#include <limits>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <functional>
#include <map>
#include <queue>
#include <utility>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
const int MOD = 1e9+9;
map< pair<int, int>, int> ex;
vector<int> ab[100000], be[100000];
pair<int, int> co[100000];
priority_queue<int> hq;
priority_queue<int, vector<int>, greater<int> > lq;
bitset<100000> rem;
map< pair<int, int>, int>::iterator it;
int N, ans;
bool flag;

int main ()
{
	ios_base::sync_with_stdio (false);

#ifndef ONLINE_JUDGE
	freopen ("input0.txt", "r", stdin);
	freopen ("output.txt", "w", stdout);
#endif

	cin >> N;

	for (int a = 0;a < N;a++)
	{
		cin >> co[a].first >> co[a].second;
		ex.insert (make_pair (co[a], a));
	}

	for (int a = 0;a < N;a++)
	{
		for (int b = co[a].first - 1;b <= co[a].first + 1;b++)
		{
			it = ex.find (make_pair (b, co[a].second + 1));
			if (it != ex.end ())
			{
				ab[a].push_back (it->second);
				be[it->second].push_back (a);
			}
		}
	}

	for (int a = 0;a < N;a++)
	{
		if (ab[a].empty ())
			lq.push (a),
			hq.push (a);
		else
		{
			flag = true;
			for (int b = 0;b < ab[a].size ();b++)
			{
				if (be[ab[a][b]].size () < 2)
				{
					flag = false;
					break;
				}
			}

			if (flag)
				lq.push (a),
				hq.push (a);
		}
	}

	rem.reset ();
	for (int a = N - 1, b;a >= 0;a--)
	{
		if (((N - 1 - a) & 1) == 0)
		{
			while (true)
			{
				if (rem[hq.top ()] == true)
				{
					hq.pop ();
					continue;
				}
				flag = true;
				for (int c = 0;c < ab[hq.top ()].size ();c++)
				{
					if (be[ab[hq.top ()][c]].size () < 2)
					{
						flag = false;
						break;
					}
				}
				if (flag)
					break;
				hq.pop ();
			}
			b = hq.top ();
			hq.pop ();
		}
		else
		{
			while (true)
			{
				if (rem[lq.top ()] == true)
				{
					lq.pop ();
					continue;
				}
				flag = true;
				for (int c = 0;c < ab[lq.top ()].size ();c++)
				{
					if (be[ab[lq.top ()][c]].size () < 2)
					{
						flag = false;
						break;
					}
				}
				if (flag)
					break;
				lq.pop ();
			}
			b = lq.top ();
			lq.pop ();
		}

		rem[b] = true;
		ans = ((ll)ans * N + b) % MOD;

		for (int c = 0;c < be[b].size ();c++)
		{
			ab[be[b][c]].erase (find (ab[be[b][c]].begin (), ab[be[b][c]].end (), b));
			if (ab[be[b][c]].empty ())
				lq.push (be[b][c]),
				hq.push (be[b][c]);
		}
		for (int c = 0;c < ab[b].size ();c++)
			be[ab[b][c]].erase (find (be[ab[b][c]].begin (), be[ab[b][c]].end (), b));
	}

	cout << ans;

	return 0;
}


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#define mp make_pair
using namespace std;

struct aa {
    int x, y;
} a[110000];
set <int> Set;
map <pair<int, int>, int> used;
int ans, n;

int ss(int x, int y) {
    int ans = 0;
    for (int i = -1; i <= 1; i++)
        if (used[mp(x + i, y - 1)]) ans++;
    return ans;
}

void test(int x, int y) {
    bool oo = true;
    for (int i = -1; i <= 1; i++)
        if (used[mp(x + i, y + 1)] && ss(x + i, y + 1) == 1) {
            oo = false;
        }
    if (!oo) {
        if (Set.find(used[mp(x, y)])) Set.erase(used[mp(x, y)]);
    }else {
        if (!Set.find(used[mp(x, y)])) Set.insert(used[mp(x, y)]);
    }
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &a[i].x, &a[i].y);
        used[mp(a[i].x, a[i].y)] = i;
    }
    for (int i = 1; i <= n; i++)
        test(a[i].x, a[i].y);
    for (int i = 1; i <= n; i++) {
        int t;
        if (i % 2 == 1) {
            t = *Set.rbegin();
            Set.erase(t);
            ans = (1LL * ans * n + t - 1) % 1000000009;
        }else {
            t = *Set.begin();
            Set.erase(t);
            ans = (1LL * ans * n + t - 1) % 1000000009;
        }
        used[mp(a[t].x, a[t].y)] = 0;
        for (int i = -2; i <= 2; i++)
            for (int j = -2; j <= 2; j++)
                if (used[mp(a[t].x + i, a[t].y + j)]) test(a[t].x + i, a[t].y + j);
    }
    printf("%d\n", ans);
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <map>

#define M 101011
#define MOD 1000000009

using namespace std;

int n;
int dx[4]={0,-1,0,1};
int num=0;
int flag[M],flag1[M];

struct node1
{
    int x;
    int y;
};

struct node
{
    int x;
    int y;
    int w;
    node1 no[7];
}str1[M];

bool operator > (node a,node b)
{
    return a.w>b.w;
}

bool operator < (node a,node b)
{
    return a.w<b.w;
}

priority_queue<node,vector<node>,greater<node> > minx;

priority_queue<node,vector<node>,less<node> > maxx;

pair<int,int> dis;
map<pair<int,int>,int> ans;

void init()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        str1[i].x=x;
        str1[i].y=y;
        str1[i].w=i;
        for(int j=1;j<=3;j++)
        {
            int fx=x+dx[j];
            int fy=y+1;
            str1[i].no[j].x=fx;
            str1[i].no[j].y=fy;
        }
        for(int j=1;j<=3;j++)
        {
            int fx=x+dx[j];
            int fy=y-1;
            str1[i].no[j+3].x=fx;
            str1[i].no[j+3].y=fy;
        }
    }
}

int com(int x)
{
    for(int j=1;j<=3;j++)
    {
        int fx=str1[x].no[j].x;
        int fy=str1[x].no[j].y;
        dis=make_pair(fx,fy);
        if(ans[dis]!=0&&flag1[ans[dis]]==0)
            return 0;
    }
    return 1;
}

void prework()
{
    for(int i=1;i<=n;i++)
    {
        dis=make_pair(str1[i].x,str1[i].y);
        if(ans[dis]==0)
        {
            num++;
            ans[dis]=num;
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(com(i))
        {
            minx.push(str1[i]);
            maxx.push(str1[i]);
        }
    }
}

int path[M];

void start()
{
    for(int i=1;i<=n;i++)
    {
        if(i%2==1)
        {
            int flag2=1;
            while(flag2==1)
            {
                node str3=maxx.top();
                maxx.pop();
                if(flag1[str3.w]==0)
                {
                    flag1[str3.w]=1;
                    flag2=0;
                    path[i]=str3.w-1;
                    for(int j=4;j<=6;j++)
                    {
                        int fx=str3.no[j].x;
                        int fy=str3.no[j].y;
                        dis=make_pair(fx,fy);
                        if(ans[dis]!=0)
                        {
                            int fp=ans[dis];
                            if(com(fp))
                            {
                                node str4;
                                str4=str1[fp];
                                maxx.push(str4);
                                minx.push(str4);
                            }
                        }

                    }
                }
            }
        }

        if(i%2==0)
        {
            int flag2=1;
            while(flag2==1)
            {
                node str3=minx.top();
                minx.pop();
                if(flag1[str3.w]==0)
                {
                    flag1[str3.w]=1;
                    flag2=0;
                    path[i]=str3.w-1;
                    for(int j=4;j<=6;j++)
                    {
                        int fx=str3.no[j].x;
                        int fy=str3.no[j].y;
                        dis=make_pair(fx,fy);
                        if(ans[dis]!=0)
                        {
                            int fp=ans[dis];
                            if(com(fp))
                            {
                                node str4;
                                str4=str1[fp];
                                minx.push(str4);
                                maxx.push(str4);
                            }
                        }

                    }
                }
            }
        }
    }
}

long long fans[M];
long long tw[M];
long long out=0;

int main()
{
    init();
    prework();
    start();
    fans[0]=1;
    fans[1]=n;
    for(int i=2;i<=n;i++)
        fans[i]=fans[i-1]*n%MOD;
    for(int i=1;i<=n;i++)
        tw[i]=path[n-i+1];
    for(int i=1;i<=n;i++)
    {
        out=(out+tw[i]*fans[i-1])%MOD;
    }
    cout<<out<<endl;

    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>

#define M 101011
#define MOD 1000000009
#define mp make_pair

using namespace std;

int n;

struct node
{
    int x;
    int y;
}str1[M];

pair<int,int> dis;
map<pair<int,int>,int> used;
set<int> Set;
long long ans=0;

void init()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        str1[i].x=x;
        str1[i].y=y;
        used[mp(x,y)]=i;
    }
}

int num(int x,int y)
{
    int ans=0;
    for(int i=-1;i<=1;i++)
        if(used[mp(x+i,y-1)])
            ans++;
    return ans;
}

void com(int x,int y)
{
    bool flag=true;;
    for(int i=-1;i<=1;i++)
    {
        if(used[mp(x+i,y+1)]&&num(x+i,y+1)==1)
            flag=false;
    }
    if(!flag)
    {
        if(Set.count(used[mp(x,y)]))
            Set.erase(used[mp(x,y)]);
    }
    else
    {
        if(!Set.count(used[mp(x,y)]))
            Set.insert(used[mp(x,y)]);
    }
}

void start()
{
    for(int i=1;i<=n;i++)
        com(str1[i].x,str1[i].y);
    for(int i=1;i<=n;i++)
    {
        int t;
        if(i%2==1)
        {
            t=*Set.rbegin();
            Set.erase(t);
            ans=(ans*n+t-1)%MOD;
        }
        else
        {
            t=*Set.begin();
            Set.erase(t);
            ans=(ans*n+t-1)%MOD;
        }
        used[mp(str1[t].x,str1[t].y)]=0;
        for(int j=-2;j<=2;j++)
        for(int k=-2;k<=2;k++)
            if(used[mp(str1[t].x+j,str1[t].y+k)])
                com(str1[t].x+j,str1[t].y+k);
    }
    cout<<ans<<endl;
}

int main()
{
    init();
    start();

    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <map>

#define M 101011
#define MOD 1000000007

using namespace std;

int n;
int dx[4]={0,-1,0,1};
int num=0;
int flag[M],flag1[M];

struct node1
{
    int x;
    int y;
};

struct node
{
    int x;
    int y;
    int w;
    node1 no[7];
}str1[M];

bool operator > (node a,node b)
{
    return a.w>b.w;
}

bool operator < (node a,node b)
{
    return a.w<b.w;
}

priority_queue<node,vector<node>,greater<node> > minx;

priority_queue<node,vector<node>,less<node> > maxx;

pair<int,int> dis;
map<pair<int,int>,int> ans;

void init()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        str1[i].x=x;
        str1[i].y=y;
        str1[i].w=i;
        for(int j=1;j<=3;j++)
        {
            int fx=x+dx[j];
            int fy=y+1;
            str1[i].no[j].x=fx;
            str1[i].no[j].y=fy;
        }
        for(int j=1;j<=3;j++)
        {
            int fx=x+dx[j];
            int fy=y-1;
            str1[i].no[j+3].x=fx;
            str1[i].no[j+3].y=fy;
        }
    }
}

int com(int x)
{
    for(int j=1;j<=3;j++)
    {
        int fx=str1[x].no[j].x;
        int fy=str1[x].no[j].y;
        dis=make_pair(fx,fy);
        if(ans[dis]!=0&&flag1[ans[dis]]==0)
            return 0;
    }
    return 1;
}

void prework()
{
    for(int i=1;i<=n;i++)
    {
        dis=make_pair(str1[i].x,str1[i].y);
        if(ans[dis]==0)
        {
            num++;
            ans[dis]=num;
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(com(i))
        {
            minx.push(str1[i]);
            maxx.push(str1[i]);
        }
    }
}

int path[M];

void start()
{
    for(int i=1;i<=n;i++)
    {
        if(i%2==1)
        {
            int flag2=1;
            while(flag2==1)
            {
                node str3=maxx.top();
                maxx.pop();
                if(flag1[str3.w]==0)
                {
                    flag1[str3.w]=1;
                    flag2=0;
                    path[i]=str3.w-1;
                    for(int j=4;j<=6;j++)
                    {
                        int fx=str3.no[j].x;
                        int fy=str3.no[j].y;
                        dis=make_pair(fx,fy);
                        if(ans[dis]!=0)
                        {
                            int fp=ans[dis];
                            if(com(fp))
                            {
                                node str4;
                                str4=str1[fp];
                                maxx.push(str4);
                                minx.push(str4);
                            }
                        }

                    }
                }
            }
        }

        if(i%2==0)
        {
            int flag2=1;
            while(flag2==1)
            {
                node str3=minx.top();
                minx.pop();
                if(flag1[str3.w]==0)
                {
                    flag1[str3.w]=1;
                    flag2=0;
                    path[i]=str3.w-1;
                    for(int j=4;j<=6;j++)
                    {
                        int fx=str3.no[j].x;
                        int fy=str3.no[j].y;
                        dis=make_pair(fx,fy);
                        if(ans[dis]!=0)
                        {
                            int fp=ans[dis];
                            if(com(fp))
                            {
                                node str4;
                                str4=str1[fp];
                                minx.push(str4);
                                maxx.push(str4);
                            }
                        }

                    }
                }
            }
        }
    }
}

long long fans[M];
long long tw[M];
long long out=0;

int main()
{
    init();
    prework();
    start();
    fans[0]=1;
    fans[1]=n;
    for(int i=2;i<=n;i++)
        fans[i]=fans[i-1]*n%MOD;
    for(int i=1;i<=n;i++)
        tw[i]=path[n-i+1];
    for(int i=1;i<=n;i++)
    {
        out=(out+tw[i]*fans[i-1])%MOD;
    }
    cout<<out<<endl;

    return 0;
}


//IN THE NAME OF ALLAH
#include<bits/stdc++.h>
using namespace std;

#define X first
#define Y second
#define Pos second
#define Id first
#define LL long long

typedef pair<LL,LL>pii;
typedef pair<int,pii >pipii;

const LL maxn=100000+100,modulo=1000000000+9;
int m,nxt[maxn];
set<int,greater<int> >possible_moves;
vector<int>upper[maxn],lower[maxn],ans;
vector<pipii>sl;
pipii p[maxn];
bool mark[maxn];

inline bool comp(const pipii &a,const pipii &b)
{
	if(a.Pos.X!=b.Pos.X) return a.Pos.X<b.Pos.X;
	return a.Pos.Y<b.Pos.Y;
}

inline int BS(const pii&a,int st,int fi)
{
	int mid;
	while(st<=fi){
		mid=(st+fi)/2;
		if(p[mid].Pos==a) return mid;
		else if(p[mid].Pos.X>a.X) fi=mid-1;
		else if(p[mid].Pos.X<a.X) st=mid+1;
		else if(p[mid].Pos.Y>a.Y) fi=mid-1;
		else st=mid+1;
	}
	return -1;
}

inline bool is_possible(int x)
{
	for(int i=0;i<upper[x].size();i++) if(!mark[upper[x][i]] && lower[upper[x][i]].size()<=1) return false;
	return true;
}

inline void sweap_line()
{
	for(int i=0,j=nxt[0];i<m;i=nxt[i]+1,j=nxt[i]){
		for(int k=i;k<=j-1;k++)
			if(p[k].Pos.Y==p[k+1].Pos.Y-1){
				upper[k].push_back(k+1);
				lower[k+1].push_back(k);
			}
		for(int k=i;k<=j;k++){
			pii temp=p[k].Pos;
			temp.X++;
			temp.Y--;
			int search_result=BS(temp,j+1,min(nxt[j+1],m-1));
			if(search_result!=-1){
				upper[p[search_result].Id].push_back(p[k].Id);
				lower[p[k].Id].push_back(p[search_result].Id);
			}
		}
		for(int k=j+1;k<=min(nxt[j+1],m-1);k++){
			pii temp=p[k].Pos;
			temp.X--;
			temp.Y--;
			int search_result=BS(temp,i,j);
			if(search_result!=-1){
				upper[p[search_result].Id].push_back(p[k].Id);
				lower[p[k].Id].push_back(p[search_result].Id);
			}
		}
	}
}

inline void update(int x)
{
	for(int i=0;i<upper[x].size();i++){
		int T=upper[x][i];
		if(mark[T]) continue;
		for(int j=0;j<lower[T].size();j++)
			if(lower[T][j]==x){
				lower[T].erase(lower[T].begin()+j);
				break;
			}
		for(int j=0;j<lower[T].size();j++){
			set<int>::iterator it=possible_moves.find(lower[T][j]);
			if(it!=possible_moves.end() && !is_possible(*it))
				possible_moves.erase(it);
		}
	}
	for(int i=0;i<lower[x].size();i++)
		if(!mark[lower[x][i]] && is_possible(lower[x][i])) possible_moves.insert(lower[x][i]);
}

inline LL m_to_ten_system()
{
	LL ret=0;
	LL t=1;
	for(int i=ans.size()-1;i>=0;i--){
		ret+=t*ans[i];
		ret%=modulo;
		t*=m;
		t%=modulo;
	}
	return ret;
}

inline void solve()
{
	for(int i=0;i<m;i++) if(is_possible(i)) possible_moves.insert(i);
	while(!possible_moves.empty()){
		ans.push_back(*possible_moves.begin());
		int temp=*possible_moves.begin();
		possible_moves.erase(possible_moves.begin());
		mark[temp]=true;
		update(temp);
		if(!possible_moves.empty()){
			set<int>::iterator it=possible_moves.end();
			it--;
			ans.push_back(*it);
			temp=*it;
			mark[temp]=true;
			possible_moves.erase(it);
			update(temp);
		}
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin>>m;
	LL x,y;
	for(int i=0;i<m;i++){
		cin>>p[i].Pos.X>>p[i].Pos.Y;
		p[i].Id=i;
	}
	sort(p,p+m,comp);
	for(int i=m-1,j;i>=0;i=j) for(j=i;p[j].Pos.X==p[i].Pos.X && j>=0;j--) nxt[j]=i;
	sweap_line();
	solve();
	cout<<m_to_ten_system()<<endl;
}


//IN THE NAME OF ALLAH
#include<bits/stdc++.h>
#include<conio.h>
using namespace std;

#define X first
#define Y second
#define Pos second
#define Id first
#define LL long long

typedef pair<LL,LL>pii;
typedef pair<int,pii >pipii;

const LL maxn=100000+100,modulo=1000000000+9;
int m,nxt[maxn];
set<int,greater<int> >possible_moves;
vector<int>upper[maxn],lower[maxn],ans;
vector<pipii>sl;
pipii p[maxn];
bool mark[maxn];

inline bool comp(const pipii &a,const pipii &b)
{
	if(a.Pos.X!=b.Pos.X) return a.Pos.X<b.Pos.X;
	return a.Pos.Y<b.Pos.Y;
}

inline int BS(const pii&a,int st,int fi)
{
	int mid;
	while(st<=fi){
		mid=(st+fi)/2;
		if(p[mid].Pos==a) return mid;
		else if(p[mid].Pos.X>a.X) fi=mid-1;
		else if(p[mid].Pos.X<a.X) st=mid+1;
		else if(p[mid].Pos.Y>a.Y) fi=mid-1;
		else st=mid+1;
	}
	return -1;
}

inline bool is_possible(int x)
{
	for(int i=0;i<upper[x].size();i++) if(!mark[upper[x][i]] && lower[upper[x][i]].size()<=1) return false;
	return true;
}

inline void sweap_line()
{
	for(int i=0,j=nxt[0];i<m;i=nxt[i]+1,j=nxt[i]+1){
		for(int k=i;k<=j-1;k++)
			if(p[k].Pos.Y==p[k+1].Pos.Y-1){
				upper[k].push_back(k+1);
				lower[k+1].push_back(k);
			}
		for(int k=i;k<=j;k++){
			pii temp=p[k].Pos;
			temp.X++;
			temp.Y--;
			int search_result=BS(temp,j+1,min(nxt[j+1],m-1));
			if(search_result!=-1){
				upper[search_result].push_back(k);
				lower[k].push_back(search_result);
			}
		}
		for(int k=j+1;k<=min(nxt[j+1],m-1);k++){
			pii temp=p[k].Pos;
			temp.X++;
			temp.Y--;
			int search_result=BS(temp,i,j);
			if(search_result!=-1){
				upper[search_result].push_back(k);
				lower[k].push_back(search_result);
			}
		}
	}
}

inline void update(int x)
{
	for(int i=0;i<upper[x].size();i++){
		int T=upper[x][i];
		if(mark[T]) continue;
		for(int j=0;j<lower[T].size();j++)
			if(lower[T][j]==x){
				lower[T].erase(lower[T].begin()+j);
				break;
			}
		for(int j=0;j<lower[T].size();j++){
			set<int>::iterator it=possible_moves.find(lower[T][j]);
			if(it!=possible_moves.end() && !is_possible(*it))
				possible_moves.erase(it);
		}
	}
	for(int i=0;i<lower[x].size();i++)
		if(!mark[lower[x][i]] && is_possible(lower[x][i])) possible_moves.insert(lower[x][i]);
}

inline LL m_to_ten_system()
{
	LL ret=0;
	LL t=1;
	for(int i=ans.size()-1;i>=0;i--){
		ret+=t*ans[i];
		ret%=modulo;
		t*=m;
		t%=modulo;
	}
	return ret;
}

inline void solve()
{
	for(int i=0;i<m;i++) if(is_possible(i)) possible_moves.insert(i);
	while(!possible_moves.empty()){
		ans.push_back(*possible_moves.begin());
		int temp=*possible_moves.begin();
		possible_moves.erase(possible_moves.begin());
		mark[temp]=true;
		update(temp);
		if(!possible_moves.empty()){
			set<int>::iterator it=possible_moves.end();
			it--;
			ans.push_back(*it);
			temp=*it;
			mark[temp]=true;
			possible_moves.erase(it);
			update(temp);
		}
	}
}

int main()
{
	//ios_base::sync_with_stdio(false);
	cin>>m;
	LL x,y;
	for(int i=0;i<m;i++){
		cin>>p[i].Pos.X>>p[i].Pos.Y;
		p[i].Id=i;
	}
	sort(p,p+m,comp);
	for(int i=m-1,j;i>=0;i=j) for(j=i;p[j].Pos.X==p[i].Pos.X && j>=0;j--) nxt[j]=i;
	sweap_line();
	solve();
	cout<<m_to_ten_system()<<endl;
}


//IN THE NAME OF ALLAH
#include<bits/stdc++.h>
#include<conio.h>
using namespace std;

#define X first
#define Y second
#define Pos second
#define Id first
#define LL long long

typedef pair<LL,LL>pii;
typedef pair<int,pii >pipii;

const LL maxn=100000+100,modulo=1000000000+9;
int m;
set<int,greater<int> >possible_moves;
vector<int>upper[maxn],lower[maxn];
vector<pipii>sl;
string ans="";
pipii p[maxn];
bool mark[maxn];

inline bool comp(const pipii &a,const pipii &b)
{
	if(a.Pos.X!=b.Pos.X) return a.Pos.X<b.Pos.X;
	return a.Pos.Y<b.Pos.Y;
}

inline int BS(const pii&a)
{
	int st=0,fi=sl.size()-1,mid;
	while(st<=fi){
		mid=(st+fi)/2;
		if(sl[mid].Pos==a) return mid;
		else if(sl[mid].Pos.X>a.X) fi=mid-1;
		else if(sl[mid].Pos.X<a.X) st=mid+1;
		else if(sl[mid].Pos.Y>a.Y) fi=mid-1;
		else st=mid+1;
	}
	return -1;
}

inline bool is_possible(int x)
{
	for(int i=0;i<upper[x].size();i++) if(!mark[upper[x][i]] && lower[upper[x][i]].size()<=1) return false;
	return true;
}

inline void print_2()
{
	cout<<"sl:\n";
	for(int i=0;i<sl.size();i++)
		cout<<sl[i].Pos.X<<' '<<sl[i].Pos.Y<<endl;
	cout<<"*************************\n";
	getch();
}

inline void sweap_line()
{
	for(int i=0;i<m;){
		if(sl.empty()) sl.push_back(p[i++]);
		while(i<m && p[i].Pos.X-sl.front().Pos.X<=1){
			sl.push_back(p[i]);
			i++;
		}
		for(int i=0;i<sl.size();i++){
			pii temp=sl[i].Pos;
			temp.Y--;
			int k=BS(temp);
			//cout<<"seraching"<<temp.X<<' '<<temp.Y<<endl;
			//cout<<"result is:"<<k<<endl;getch();
			if(k!=-1){
				lower[sl[i].Id].push_back(sl[k].Id);
				upper[sl[k].Id].push_back(sl[i].Id);
			}
			temp.X++;
			k=BS(temp);
			//cout<<"seraching"<<temp.X<<' '<<temp.Y<<endl;
			//cout<<"result is:"<<k<<endl;getch();
			if(k!=-1){
				lower[sl[i].Id].push_back(sl[k].Id);
				upper[sl[k].Id].push_back(sl[i].Id);
			}
			temp.X-=2;
			k=BS(temp);
			//cout<<"seraching"<<temp.X<<' '<<temp.Y<<endl;
			//cout<<"result is:"<<k<<endl;getch();
			if(k!=-1){
				lower[sl[i].Id].push_back(sl[k].Id);
				upper[sl[k].Id].push_back(sl[i].Id);
			}
			//cout<<"************************\n";getch();
		}
		int z=sl[0].Pos.X;
		for(int i=0;i<sl.size();){
			if(sl[i].Pos.X==z) sl.erase(sl.begin()+i);
			else break;
		}
	}
}

inline void update(int x)
{
	for(int i=0;i<upper[x].size();i++){
		int T=upper[x][i];
		if(mark[T]) continue;
		for(int j=0;j<lower[T].size();j++)
			if(lower[T][j]==x){
				lower[T].erase(lower[T].begin()+j);
				break;
			}
		for(int j=0;j<lower[T].size();j++){
			set<int>::iterator it=possible_moves.find(lower[T][j]);
			if(it!=possible_moves.end() && !is_possible(*it))
				possible_moves.erase(it);
		}
	}
	for(int i=0;i<lower[x].size();i++)
		if(!mark[lower[x][i]] && is_possible(lower[x][i])) possible_moves.insert(lower[x][i]);
}

inline string num_to_str(int x)
{
	if(x==0)
		return "0";
	string ret="";
	while(x>0){
		ret=char(x%10+'0')+ret;
		x/=10;
	}
	return ret;
}

inline LL m_to_ten_system()
{
	LL ret=0;
	LL t=1;
	for(int i=ans.size()-1;i>=0;i--){
		ret+=t*(ans[i]-'0');
		ret%=modulo;
		t*=m;
		t%=modulo;
	}
	return ret;
}

inline void print()
{
	cout<<"possible_moves :\n";
	for(set<int>::iterator it=possible_moves.begin();it!=possible_moves.end();it++)cout<<(*it)<<' ';
	cout<<endl;getch();
}

inline void solve()
{
	for(int i=0;i<m;i++) if(is_possible(i)) possible_moves.insert(i);
	//print();
	while(!possible_moves.empty()){
		ans+=num_to_str(*possible_moves.begin());
		int temp=*possible_moves.begin();
		possible_moves.erase(possible_moves.begin());
		mark[temp]=true;
		update(temp);
		//print();
		if(!possible_moves.empty()){
			set<int>::iterator it=possible_moves.end();
			it--;
			ans+=num_to_str(*it);
			temp=*it;
			mark[temp]=true;
			possible_moves.erase(it);
			update(temp);
			//print();
		}
	}
	//cout<<"hi\n";
}

int main()
{
	//cout<<num_to_str(2387);
	//ios_base::sync_with_stdio(false);
	cin>>m;
	LL x,y;
	for(int i=0;i<m;i++){
		cin>>p[i].Pos.X>>p[i].Pos.Y;
		p[i].Id=i;
	}
	sort(p,p+m,comp);
	sweap_line();
	/*for(int i=0;i<m;i++){
		cout<<i<<" :\n";
		cout<<"lowers:\n";
		for(int j=0;j<lower[i].size();j++)
			cout<<lower[i][j]<<' ';
		cout<<endl;
		cout<<"uppers:\n";
		for(int j=0;j<upper[i].size();j++)
			cout<<upper[i][j]<<' ';
		cout<<"\n***************************\n";
	}*/
	solve();
	//cout<<ans<<endl;
	cout<<m_to_ten_system()<<endl;
}