//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;
set<int,greater<int> >possible_moves;
vector<int>upper[maxn],lower[maxn];
vector<pipii>sl;
vector<int>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 uniquef(vector<int>&v)
{
	sort(v.begin(),v.end());
	for(int i=0;i+1<v.size();){
		if(v[i]==v[i+1]) v.erase(v.begin()+i);
		else i++;
	}
}

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);
			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);
			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);
			if(k!=-1){
				lower[sl[i].Id].push_back(sl[k].Id);
				upper[sl[k].Id].push_back(sl[i].Id);
			}
		}
		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;
		}
	}
	for(int i=0;i<m;i++){
		uniquef(upper[i]);
		uniquef(lower[i]);
	}
}

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);
	sweap_line();
	solve();
	cout<<m_to_ten_system()<<endl;
}


//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[p[k].Id].push_back(p[k+1].Id);
				lower[p[k+1].Id].push_back(p[k].Id);
			}
		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;
set<int,greater<int> >possible_moves;
vector<int>upper[maxn],lower[maxn];
vector<pipii>sl;
vector<int>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 uniquef(vector<int>&v)
{
	sort(v.begin(),v.end());
	for(int i=0;i+1<v.size();){
		if(v[i]==v[i+1]) v.erase(v.begin()+i);
		else i++;
	}
}

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++){
			//cout<<"current is :"<<sl[i].Id<<' '<<sl[i].Pos.X<<' '<<sl[i].Pos.Y<<endl;
			pii temp=sl[i].Pos;
			temp.Y--;
			int k=BS(temp);
			//cout<<"seraching"<<temp.X<<' '<<temp.Y<<endl;
			//cout<<"result is:"<<sl[k].Id<<endl;
			if(k!=-1){
				//cout<<"adding-->"<<sl[i].Id<<" to :"<<sl[k].Id<<endl;
				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:"<<sl[k].Id<<endl;
			if(k!=-1){
				//cout<<"adding-->"<<sl[i].Id<<" to :"<<sl[k].Id<<endl;
				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:"<<sl[k].Id<<endl;
			if(k!=-1){
				//cout<<"adding-->"<<sl[i].Id<<" to :"<<sl[k].Id<<endl;
				lower[sl[i].Id].push_back(sl[k].Id);
				upper[sl[k].Id].push_back(sl[i].Id);
			}
			//cout<<"************************\n";
		}
		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;
		}
	}
	for(int i=0;i<m;i++){
		uniquef(upper[i]);
		uniquef(lower[i]);
	}
	/*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";
	}*/
}

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];
		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.push_back(*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.push_back(*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();
	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++){
		int T=upper[x][i];
		if(mark[T]) continue;
		if(lower[T].size()<=1) return false;
	}
	return true;
}

inline void sweap_line()
{
	sl.push_back(p[0]);
	for(int i=1;i<m;){
		while(i<m && p[i].Pos.X-sl.front().Pos.X<=1){
			sl.push_back(p[i]);
			i++;
		}
		/*cout<<sl.size()<<endl;getch();
		for(int i=0;i<sl.size();i++)
			cout<<sl[i].Pos.X<<' '<<sl[i].Pos.Y<<endl;
		getch();*/
		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 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)+1<<' ';
	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+1<<" :\n";
		for(int j=0;j<lower[i].size();j++)
			cout<<lower[i][j]+1<<' ';
		cout<<endl;
		for(int j=0;j<upper[i].size();j++)
			cout<<upper[i][j]+1<<' ';
		cout<<"\n***************************\n";
	}*/
	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 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)+1<<' ';
	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;
}


//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();
	for(int i=0;i<ans.size();i++)
		cout<<ans[i]<<' ';
	cout<<endl;
	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;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <map>
#define X first
#define Y second
using namespace std;
const int Mn = 100000 + 10;
const int Mod = 1e9 + 9;
set<int> s;
map<pair<int,int>,int> hash;
pair<int, int> a[Mn];
bool vis[Mn];
int n;
inline int pow(int x, int y, int M) {
    int res(1);
    while(y) {
        if(y & 1)
            res = (long long) res * x %  M;
        x = (long long) x * x % M;
        y >>= 1;
    }
    return res;
}
inline bool stable(int x) {
    return  x == 0
            || vis[x] == false
            || a[x].Y == 0
            || vis[hash[make_pair(a[x].X - 1, a[x].Y - 1)]]
            || vis[hash[make_pair(a[x].X, a[x].Y - 1)]]
            || vis[hash[make_pair(a[x].X + 1, a[x].Y - 1)]];
}
inline bool check(int x) {
    if(!vis[x])
        return false;
    vis[x] = false;
    if (stable(hash[make_pair(a[x].X - 1, a[x].Y + 1)]) &&
        stable(hash[make_pair(a[x].X, a[x].Y + 1)]) &&
        stable(hash[make_pair(a[x].X + 1, a[x].Y + 1)])) {
            vis[x] = true;
            return true;
        }
    vis[x] = true;
    return false;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d%d",&a[i].X,&a[i].Y);
        hash[a[i]] = i;
        vis[i] = true;
    }
    for(int i = 1; i <= n; ++i)
        if(check(i)) {
            s.insert(i);
            //cerr << i << endl;
        }
    int ans(0);
    for(int i = n-1, flag = 0; i >= 0; --i, flag ^= 1) {

        set<int> :: iterator it1 = s.begin();
        set<int> :: reverse_iterator it0 = s.rbegin();

        int k = flag ? *it1 : *it0;
        ans = (ans + (long long)(k - 1) * pow(n,i,Mod) % Mod) % Mod;
        //cerr << k  << " "<<ans <<endl;

        s.erase(k);
        vis[k] = false;
        for(int j = -1; j <= 1; ++j) {
            int num = hash[make_pair(a[k].X + j, a[k].Y - 1)];
            if(num && check(num))
                s.insert(num);
        }
        for(int j = -2; j <= 2; ++j) {
            int num = hash[make_pair(a[k].X + j, a[k].Y)];
            if(num && !check(num) && s.find(num) != s.end())
                s.erase(num);
        }
    }
    cout << ans << endl;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <map>
#define X first
#define Y second
using namespace std;
const int Mn = 100000 + 10;
const int Mod = 1e9 + 9;
set<int> s;
map<pair<int,int>,int> hash;
pair<int, int> a[Mn];
bool vis[Mn];
int n;
inline int pow(int x, int y, int M) {
    int res(1);
    while(y) {
        if(y & 1)
            res = (long long) res * x %  M;
        x = (long long) x * x % M;
        y >>= 1;
    }
    return res;
}
inline bool stable(int x) {
    return  x == 0
            || vis[x] == false
            || a[x].Y == 0
            || vis[hash[make_pair(a[x].X - 1, a[x].Y - 1)]]
            || vis[hash[make_pair(a[x].X, a[x].Y - 1)]]
            || vis[hash[make_pair(a[x].X, a[x].Y - 1)]];
}
inline bool check(int x) {
    if(!vis[x])
        return false;
    vis[x] = false;
    if (stable(hash[make_pair(a[x].X - 1, a[x].Y + 1)]) &&
        stable(hash[make_pair(a[x].X, a[x].Y + 1)]) &&
        stable(hash[make_pair(a[x].X + 1, a[x].Y + 1)])) {
            vis[x] = true;
            return true;
        }
    vis[x] = true;
    return false;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d%d",&a[i].X,&a[i].Y);
        hash[a[i]] = i;
        vis[i] = true;
    }
    for(int i = 1; i <= n; ++i)
        if(check(i)) {
            s.insert(i);
            //cerr << i << endl;
        }
    int ans(0);
    for(int i = n-1, flag = 0; i >= 0; --i, flag ^= 1) {
        set<int> :: iterator it1 = s.begin();
        set<int> :: reverse_iterator it0 = s.rbegin();
        int k = flag ? *it1 : *it0;
        ans = (ans + (long long)(k - 1) * pow(n,i,Mod) % Mod) % Mod;
        //cerr << k  << " "<<ans <<endl;

        s.erase(k);
        vis[k] = false;
        for(int j = -1; j <= 1; ++j) {
            int num = hash[make_pair(a[k].X + j, a[k].Y - 1)];
            if(num && check(num))
                s.insert(num);
        }
        for(int j = -2; j <= 2; ++j) {
            int num = hash[make_pair(a[k].X + j, a[k].Y)];
            if(num && !check(num) && s.find(num) != s.end())
                s.erase(num);
        }
    }
    cout << ans << endl;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <map>
#define X first
#define Y second
using namespace std;
const int Mn = 100000 + 10;
const int Mod = 1e9 + 9;
set<int> s;
map<pair<int,int>,int> hash;
pair<int, int> a[Mn];
bool vis[Mn];
int n;
inline int pow(int x, int y, int M) {
    int res(1);
    while(y) {
        if(y & 1)
            res = (long long) res * x %  M;
        x = (long long) x * x % M;
        y >>= 1;
    }
    return res;
}
inline bool stable(int x) {
    return  x == 0
            || vis[x] == false
            || a[x].Y == 0
            || vis[hash[make_pair(a[x].X - 1, a[x].Y - 1)]]
            || vis[hash[make_pair(a[x].X, a[x].Y - 1)]]
            || vis[hash[make_pair(a[x].X, a[x].Y - 1)]];
}
inline bool check(int x) {
    if(!vis[x])
        return false;
    vis[x] = false;
    if (stable(hash[make_pair(a[x].X - 1, a[x].Y + 1)]) &&
        stable(hash[make_pair(a[x].X, a[x].Y + 1)]) &&
        stable(hash[make_pair(a[x].X + 1, a[x].Y + 1)])) {
            vis[x] = true;
            return true;
        }
    vis[x] = true;
    return false;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d%d",&a[i].X,&a[i].Y);
        hash[a[i]] = i;
        vis[i] = true;
    }
    for(int i = 1; i <= n; ++i)
        if(check(i)) {
            s.insert(i);
            //cerr << i << endl;
        }
    int ans(0);
    for(int i = n-1; i >= 0; --i) {
        set<int> :: reverse_iterator it = s.rbegin();
        int k = *it;

        ans = (ans + (long long)(k - 1) * pow(n,i,Mod) % Mod) % Mod;
        //cerr << k -1 << " "<<ans <<endl;

        s.erase(k);
        vis[k] = false;
        for(int j = -1; j <= 1; ++j) {
            int num = hash[make_pair(a[k].X + j, a[k].Y - 1)];
            if(num && check(num))
                s.insert(num);
        }
        for(int j = -2; j <= 2; ++j) {
            int num = hash[make_pair(a[k].X + j, a[k].Y)];
            if(num && !check(num) && s.find(num) != s.end())
                s.erase(num);
        }
    }
    cout << ans << endl;
}


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

using namespace std;

const long long oo=1000000009;

struct node
{
    int val,pos;
    node():val(0),pos(0){};
    node(int x,int y):val(x),pos(y){};
};
priority_queue< int >maxpos;
priority_queue< int , vector<int> , greater<int> >minpos;
int son[100010][5],father[100010][5],n;
long long ans=0;
bool removable[100010],removed[100010];
vector<node>v[100010];
map<int,int>m;

bool cmp(node x,node y)
{
    return x.val<y.val;
}

void father_delete_son(int x)
{
    for(int i=1;i<=father[x][0];i++)
    {
        int cur_father=father[x][i];
        for(int j=1;j<=son[cur_father][0];j++)
            if(son[cur_father][j]==x)
            {
                swap(son[cur_father][j],son[cur_father][son[cur_father][0]--]);
                break;
            }
        if(son[cur_father][0]==1)
            removable[son[cur_father][1]]=0;
    }
}

void son_delete_father(int x)
{
    for(int i=1;i<=son[x][0];i++)
    {
        int cur_son=son[x][i];
        for(int j=1;j<=father[cur_son][0];j++)
            if(father[cur_son][j]==x)
            {
                swap(father[cur_son][j],father[cur_son][father[cur_son][0]--]);
                break;
            }
        bool flag=1;
        for(int j=1;j<=father[cur_son][0];j++)
            if(son[father[cur_son][j]][0]==1)
            {
                flag=0;
                break;
            }
        if(flag)
        {
            removable[cur_son]=1;
            maxpos.push(cur_son);
            minpos.push(cur_son);
        }
    }
}

bool check(int x)
{
    if(!removable[x]||removed[x])
        return 0;
    ans=(ans*n+x-1)%oo;
    removed[x]=1;
    father_delete_son(x);
    son_delete_father(x);
}

void get_removable()
{
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=v[i-1][j].pos;
        for(int j=0;j<v[i].size();j++)
        {
            node cur=v[i][j];
            for(int k=-1;k<2;k++)
                if(m[cur.val+k])
                {
                    int son_pos=m[cur.val+k];
                    son[cur.pos][++son[cur.pos][0]]=son_pos;
                    father[son_pos][++father[son_pos][0]]=cur.pos;
                }
            if(son[cur.pos][0]==1)
                removable[son[cur.pos][1]]=0;
            else
            {
                for(int k=1;k<=son[cur.pos][0];k++)
                    removable[son[cur.pos][k]]&=1;
            }
        }
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=0;
    }
}

void init()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        cin>>x>>y;
        v[y].push_back(node(x,i));
        removable[i]=1;
        removed[i]=0;
    }
    for(int i=0;i<n;i++)
        sort(v[i].begin(),v[i].end(),cmp);
    get_removable();
}

void work()
{
    for(int i=1;i<=n;i++)
        if(removable[i])
        {
            maxpos.push(i);
            minpos.push(i);
        }
    for(int i=1;i<=n/2;i++)
    {
        while(!check(maxpos.top()))
            maxpos.pop();
        while(!check(minpos.top()))
            minpos.pop();
    }
    if(n&1)
    {
        for(int i=1;i<=n;i++)
            if(!removed[i])
                ans=(ans*n+i-1)%oo;
    }
}

void print()
{
    cout<<ans<<endl;
}

int main()
{
    init();
    work();
    print();
    return 0;
}


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

using namespace std;

const long long oo=1000000009;

struct node
{
    int val,pos;
};
priority_queue< int >maxpos;
priority_queue< int , vector<int> , greater<int> >minpos;
int son[100010][5],father[100010][5],n;
long long ans=0;
bool removable[100010],removed[100010];
vector<node>v[100010];
map<int,int>m;

bool cmp(node x,node y)
{
    return x.val<y.val;
}

void father_delete_son(int x)
{
    for(int i=1;i<=father[x][0];i++)
    {
        int cur_father=father[x][i];
        for(int j=1;j<=son[cur_father][0];j++)
            if(son[cur_father][j]==x)
            {
                swap(son[cur_father][j],son[cur_father][son[cur_father][0]--]);
                break;
            }
        if(son[cur_father][0]==1)
            removable[son[cur_father][1]]=0;
    }
}

void son_delete_father(int x)
{
    for(int i=1;i<=son[x][0];i++)
    {
        int cur_son=son[x][i];
        for(int j=1;j<=father[cur_son][0];j++)
            if(father[cur_son][j]==x)
            {
                swap(father[cur_son][j],father[cur_son][father[cur_son][0]--]);
                break;
            }
        bool flag=1;
        for(int j=1;j<=father[cur_son][0];j++)
            if(son[father[cur_son][j]][0]==1)
            {
                flag=0;
                break;
            }
        if(flag)
        {
            removable[cur_son]=1;
            maxpos.push(cur_son);
            minpos.push(cur_son);
        }
    }
}

bool check(int x)
{
    if(!removable[x]||removed[x])
        return 0;
    ans=(ans*n+x-1)%oo;
    removed[x]=1;
    father_delete_son(x);
    son_delete_father(x);
}

void get_removable()
{
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=v[i-1][j].pos;
        for(int j=0;j<v[i].size();j++)
        {
            node cur=v[i][j];
            for(int k=-1;k<2;k++)
                if(m[cur.val+k])
                {
                    int son_pos=m[cur.val+k];
                    son[cur.pos][++son[cur.pos][0]]=son_pos;
                    father[son_pos][++father[son_pos][0]]=cur.pos;
                }
            if(son[cur.pos][0]==1)
                removable[son[cur.pos][1]]=0;
            else
            {
                for(int k=1;k<=son[cur.pos][0];k++)
                    removable[son[cur.pos][k]]&=1;
            }
        }
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=0;
    }
}

void init()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        cin>>x>>y;
        node temp;
        temp.val=x;
        temp.pos=i;
        v[y].push_back(temp);
        removable[i]=1;
        removed[i]=0;
    }
    for(int i=0;i<n;i++)
        sort(v[i].begin(),v[i].end(),cmp);
    get_removable();
}

void work()
{
    for(int i=1;i<=n;i++)
        if(removable[i])
        {
            maxpos.push(i);
            minpos.push(i);
        }
    for(int i=1;i<=n/2;i++)
    {
        while(!check(maxpos.top()))
            maxpos.pop();
        while(!check(minpos.top()))
            minpos.pop();
    }
    if(n&1)
    {
        for(int i=1;i<=n;i++)
            if(!removed[i])
                ans=(ans*n+i-1)%oo;
    }
    cout<<ans<<endl;
}

int main()
{
    init();
    work();
    return 0;
}


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

using namespace std;

const long long oo=1000000009;

struct node
{
    int val,pos;
    node():val(0),pos(0){};
    node(int x,int y):val(x),pos(y){};
};
priority_queue< int >maxpos;
priority_queue< int , vector<int> , greater<int> >minpos;
int son[100010][5],father[100010][5],n;
long long ans=0;
bool removable[100010],removed[100010];
vector<node>v[100010];
map<int,int>m;

bool cmp(node x,node y)
{
    return x.val<y.val;
}

void father_delete_son(int x)
{
    for(int i=1;i<=father[x][0];i++)
    {
        int cur_father=father[x][i];
        for(int j=1;j<=son[cur_father][0];j++)
            if(son[cur_father][j]==x)
            {
                swap(son[cur_father][j],son[cur_father][son[cur_father][0]--]);
                break;
            }
        if(son[cur_father][0]==1)
            removable[son[cur_father][1]]=0;
    }
}

void son_delete_father(int x)
{
    for(int i=1;i<=son[x][0];i++)
    {
        int cur_son=son[x][i];
        for(int j=1;j<=father[cur_son][0];j++)
            if(father[cur_son][j]==x)
            {
                swap(father[cur_son][j],father[cur_son][father[cur_son][0]--]);
                break;
            }
        bool flag=1;
        for(int j=1;j<=father[cur_son][0];j++)
            if(son[father[cur_son][j]][0]==1)
            {
                flag=0;
                break;
            }
        if(flag)
        {
            removable[cur_son]=1;
            maxpos.push(cur_son);
            minpos.push(cur_son);
        }
    }
}

bool check(int x)
{
    if(!removable[x]||removed[x])
        return 0;
    ans=(ans*n+x-1)%oo;
    removed[x]=1;
    father_delete_son(x);
    son_delete_father(x);
    return 1;
}

void get_removable()
{
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=v[i-1][j].pos;
        for(int j=0;j<v[i].size();j++)
        {
            node cur=v[i][j];
            for(int k=-1;k<2;k++)
                if(m[cur.val+k])
                {
                    int son_pos=m[cur.val+k];
                    son[cur.pos][++son[cur.pos][0]]=son_pos;
                    father[son_pos][++father[son_pos][0]]=cur.pos;
                }
            if(son[cur.pos][0]==1)
                removable[son[cur.pos][1]]=0;
            else
            {
                for(int k=1;k<=son[cur.pos][0];k++)
                    removable[son[cur.pos][k]]&=1;
            }
        }
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=0;
    }
}

void init()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        cin>>x>>y;
        v[y].push_back(node(x,i));
        removable[i]=1;
        removed[i]=0;
    }
    for(int i=0;i<n;i++)
        sort(v[i].begin(),v[i].end(),cmp);
    get_removable();
}

void work()
{
    for(int i=1;i<=n;i++)
        if(removable[i])
        {
            maxpos.push(i);
            minpos.push(i);
        }
    for(int i=1;i<=n/2;i++)
    {
        while(!check(maxpos.top()))
        	maxpos.pop();
        while(!check(minpos.top()))
        	minpos.pop();
    }
    if(n&1)
    {
        for(int i=1;i<=n;i++)
            if(!removed[i])
                ans=(ans*n+i-1)%oo;
    }
    cout<<ans<<endl;
}

int main()
{
    init();
    work();
    return 0;
}


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

using namespace std;

const long long oo=1000000009;

struct node
{
    int val,pos;
    node():val(0),pos(0){};
    node(int x,int y):val(x),pos(y){};
};
priority_queue< int >maxpos;
priority_queue< int , vector<int> , greater<int> >minpos;
int son[100010][5],father[100010][5],n;
long long ans=0;
bool removable[100010],removed[100010];
vector<node>v[100010];
map<int,int>m;

bool cmp(node x,node y)
{
    return x.val<y.val;
}

void father_delete_son(int x)
{
    for(int i=1;i<=father[x][0];i++)
    {
        int cur_father=father[x][i];
        for(int j=1;j<=son[cur_father][0];j++)
            if(son[cur_father][j]==x)
            {
                swap(son[cur_father][j],son[cur_father][son[cur_father][0]--]);
                break;
            }
        if(son[cur_father][0]==1)
            removable[son[cur_father][1]]=0;
    }
}

void son_delete_father(int x)
{
    for(int i=1;i<=son[x][0];i++)
    {
        int cur_son=son[x][i];
        for(int j=1;j<=father[cur_son][0];j++)
            if(father[cur_son][j]==x)
            {
                swap(father[cur_son][j],father[cur_son][father[cur_son][0]--]);
                break;
            }
        bool flag=1;
        for(int j=1;j<=father[cur_son][0];j++)
            if(son[father[cur_son][j]][0]==1)
            {
                flag=0;
                break;
            }
        if(flag)
        {
            removable[cur_son]=1;
            maxpos.push(cur_son);
            minpos.push(cur_son);
        }
    }
}

bool check(int x)
{
    if(!removable[x]||removed[x])
        return 0;
    ans=(ans*n+x-1)%oo;
    removed[x]=1;
    father_delete_son(x);
    son_delete_father(x);
}

void get_removable()
{
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=v[i-1][j].pos;
        for(int j=0;j<v[i].size();j++)
        {
            node cur=v[i][j];
            for(int k=-1;k<2;k++)
                if(m[cur.val+k])
                {
                    int son_pos=m[cur.val+k];
                    son[cur.pos][++son[cur.pos][0]]=son_pos;
                    father[son_pos][++father[son_pos][0]]=cur.pos;
                }
            if(son[cur.pos][0]==1)
                removable[son[cur.pos][1]]=0;
            else
            {
                for(int k=1;k<=son[cur.pos][0];k++)
                    removable[son[cur.pos][k]]&=1;
            }
        }
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=0;
    }
}

void init()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        cin>>x>>y;
        v[y].push_back(node(x,i));
        removable[i]=1;
        removed[i]=0;
    }
    for(int i=0;i<n;i++)
        sort(v[i].begin(),v[i].end(),cmp);
    get_removable();
}

void work()
{
    for(int i=1;i<=n;i++)
        if(removable[i])
        {
            maxpos.push(i);
            minpos.push(i);
        }
    for(int i=1;i<=n/2;i++)
    {
        while(!check(maxpos.top()))
            maxpos.pop();
        while(!check(minpos.top()))
            minpos.pop();
    }
    if(n&1)
    {
        for(int i=1;i<=n;i++)
            if(!removed[i])
                ans=(ans*n+i-1)%oo;
    }
    cout<<ans<<endl;
}

int main()
{
    init();
    work();
    return 0;
}


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

using namespace std;

const long long oo=1000000009;

struct node
{
    int val,pos;
    node():val(0),pos(0){};
    node(int x,int y):val(x),pos(y){};
};
priority_queue< int >maxpos;
priority_queue< int , vector<int> , greater<int> >minpos;
int son[100010][5],father[100010][5],n;
long long ans=0;
bool removable[100010],removed[100010];
vector<node>v[100010];
map<int,int>m;

bool cmp(node x,node y)
{
    return x.val<y.val;
}

void father_delete_son(int x)
{
    for(int i=1;i<=father[x][0];i++)
    {
        int cur_father=father[x][i];
        for(int j=1;j<=son[cur_father][0];j++)
            if(son[cur_father][j]==x)
            {
                swap(son[cur_father][j],son[cur_father][son[cur_father][0]--]);
                break;
            }
        if(son[cur_father][0]==1)
            removable[son[cur_father][1]]=0;
    }
}

void son_delete_father(int x)
{
    for(int i=1;i<=son[x][0];i++)
    {
        int cur_son=son[x][i];
        for(int j=1;j<=father[cur_son][0];j++)
            if(father[cur_son][j]==x)
            {
                swap(father[cur_son][j],father[cur_son][father[cur_son][0]--]);
                break;
            }
        bool flag=1;
        for(int j=1;j<=father[cur_son][0];j++)
            if(son[father[cur_son][j]][0]==1)
            {
                flag=0;
                break;
            }
        if(flag)
        {
            removable[cur_son]=1;
            maxpos.push(cur_son);
            minpos.push(cur_son);
        }
    }
}

bool check(int x)
{
    if(!removable[x]||removed[x])
        return 0;
    ans=(ans*n+x-1)%oo;
    removed[x]=1;
    father_delete_son(x);
    son_delete_father(x);
}

void get_removable()
{
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=v[i-1][j].pos;
        for(int j=0;j<v[i].size();j++)
        {
            node cur=v[i][j];
            for(int k=-1;k<2;k++)
                if(m[cur.val+k])
                {
                    int son_pos=m[cur.val+k];
                    son[cur.pos][++son[cur.pos][0]]=son_pos;
                    father[son_pos][++father[son_pos][0]]=cur.pos;
                }
            if(son[cur.pos][0]==1)
                removable[son[cur.pos][1]]=0;
            else
            {
                for(int k=1;k<=son[cur.pos][0];k++)
                    removable[son[cur.pos][k]]&=1;
            }
        }
        for(int j=0;j<v[i-1].size();j++)
            m[v[i-1][j].val]=0;
    }
}

void init()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        cin>>x>>y;
        v[y].push_back(node(x,i));
        removable[i]=1;
        removed[i]=0;
    }
    for(int i=0;i<n;i++)
        sort(v[i].begin(),v[i].end(),cmp);
    get_removable();
}

void work()
{
    for(int i=1;i<=n;i++)
        if(removable[i])
        {
            maxpos.push(i);
            minpos.push(i);
        }
    for(int i=1;i<=n/2;i++)
    {
        while(!check(maxpos.top()))
            maxpos.pop();
        while(!check(minpos.top()))
            minpos.pop();
    }
    if(n&1)
    {
        for(int i=1;i<=n;i++)
            if(!removed[i])
                ans=(ans*n+i-1)%oo;
    }
    cout<<ans<<endl;
}

int main()
{
    init();
    work();
    return 0;
}


#include <iostream>
#include <set>

using namespace std;

#define MODULO				1000000009LL

typedef struct cube_s
{
	int x;
	int y;
	int  val;
}cube_t;

typedef set <cube_t *, bool (*)(cube_t *, cube_t *)> set_cubes_t;

bool figure_comp(cube_t * a, cube_t * b)
{
	return ((a->y < b->y) || (a->y == b->y && a->x < b->x));
}

bool free_comp(cube_t * a, cube_t * b)
{
	return (a->val < b->val);
}

int idx = 0;
long long *vp;
set_cubes_t figure(figure_comp), free_cubes(free_comp);

int get_count(cube_t *cube)
{
	int count = 0;
	cube_t val, *found;

	val.y = cube->y-1;
	for (val.x = cube->x-1; val.x <= cube->x+1; val.x++)
	{
		found = *figure.find(&val);
		if (found != *figure.end())
		{
			count++;
		}
	}

	return count;
}

bool check_if_can_erase(cube_t *cube)
{
	cube_t val, *found;

	val.y = cube->y+1;
	for (val.x = cube->x-1; val.x <= cube->x+1; val.x++)
	{
		found = *figure.find(&val);
		if (found != *figure.end() && get_count(found) == 1)
		{
			return false;
		}
	}

	return true;
}

void remove_cube_from_figure(cube_t *cube)
{
	int count = 0;
	cube_t val, *found;

	figure.erase(cube);
	free_cubes.erase(cube);

	val.y = cube->y-1;
	for (val.x = cube->x-1; val.x <= cube->x+1; val.x++)
	{
		found = *figure.find(&val);
		if (found != *figure.end())
		{
			if (check_if_can_erase(found))
			{
				free_cubes.insert(found);
			}
			else
			{
				free_cubes.erase(found);
			}
		}
	}

	val.y = cube->y;
	for (val.x = cube->x-2; val.x <= cube->x+2; val.x++)
	{
		found = *figure.find(&val);
		if (found != *figure.end())
		{
			if (check_if_can_erase(found))
			{
				free_cubes.insert(found);
			}
			else
			{
				free_cubes.erase(found);
			}
		}
	}
}

int main()
{
	int m, i;
	long long resp, pow;
	cube_t *cubes, *vasya, *petya;
	set_cubes_t::iterator it;

	cin>>m;

	vp = new long long[m];
	cubes = new cube_t[m];

	for (i = 0; i < m; i++)
	{
		cin>>cubes[i].x>>cubes[i].y;
		cubes[i].val = i;

		figure.insert(&cubes[i]);
	}

	for (it = figure.begin(); it != figure.end(); it++)
	{
		if (check_if_can_erase(*it))
		{
			free_cubes.insert(*it);
			//cout<<"can erase = "<<(*it)->val<<endl;
		}
	}

	while (1)
	{
		if (free_cubes.size() == 0)
		{
			break;
		}
		vasya = *free_cubes.rbegin();
		if (vasya != *free_cubes.end())
		{
			remove_cube_from_figure(vasya);
			vp[idx++] = vasya->val;

			//cout<<"vasya "<<vasya->val<<endl;
		}
		else
		{
			break;
		}

		if (free_cubes.size() == 0)
		{
			break;
		}
		petya = *free_cubes.begin();
		if (petya != *free_cubes.end())
		{
			remove_cube_from_figure(petya);
			vp[idx++] = petya->val;

			//cout<<"petya "<<petya->val<<endl;
		}
		else
		{
			break;
		}
	}

	resp = 0LL; pow = 1LL;
	for (i = m-1; i >= 0; i--)
	{
		resp += ((vp[i] * pow) % MODULO);
		resp %= MODULO;

		pow *= (long long)m;
		pow %= MODULO;
	}

	cout<<resp<<endl;

	return 0;
}


#include <iostream>
#include <set>

using namespace std;

#define MODULO				1000000009LL

typedef struct cube_s
{
	int x;
	int y;
	int count;
	int  val;
}cube_t;

typedef set <cube_t *, bool (*)(cube_t *, cube_t *)> set_cubes_t;

bool figure_comp(cube_t * a, cube_t * b)
{
	return ((a->y < b->y) || (a->y == b->y && a->x < b->x));
}

bool free_comp(cube_t * a, cube_t * b)
{
	return (a->val < b->val);
}

int idx = 0;
long long *vp;
set_cubes_t figure(figure_comp), free_cubes(free_comp);

void remove_cube_from_figure(cube_t *cube)
{
	cube_t val, *found;

	figure.erase(cube);
	free_cubes.erase(cube);

	val.y = cube->y-1;
	for (val.x = cube->x-1; val.x <= cube->x+1; val.x++)
	{
		found = *figure.find(&val);
		if (found != *figure.end() && --found->count == 0)
		{
			free_cubes.insert(found);
		}
	}

	vp[idx++] = cube->val;
}

int main()
{
	int m, i;
	long long resp, pow;
	cube_t *cubes, *cube, *vasya, *petya,  val;
	set_cubes_t::iterator it;

	cin>>m;

	vp = new long long[m];
	cubes = new cube_t[m];

	for (i = 0; i < m; i++)
	{
		cin>>cubes[i].x>>cubes[i].y;
		cubes[i].count = 0;
		cubes[i].val = i;

		figure.insert(&cubes[i]);
	}

	for (it = figure.begin(); it != figure.end(); it++)
	{
		val.y = (*it)->y - 1;
		for (val.x = (*it)->x-1; val.x <= (*it)->x+1; val.x++)
		{
			cube = *figure.find(&val);

			if (cube != *figure.end())
			{
				cube->count++;
			}
		}
	}

	for (it = figure.begin(); it != figure.end(); it++)
	{
		if (!(*it)->count)
		{
			free_cubes.insert(*it);
		}
	}

	while (1)
	{
		if (free_cubes.size() == 0)
		{
			break;
		}
		vasya = *free_cubes.rbegin();
		if (vasya != *free_cubes.end())
			remove_cube_from_figure(vasya);
		else
			break;

		if (free_cubes.size() == 0)
		{
			break;
		}
		petya = *free_cubes.begin();
		if (petya != *free_cubes.end())
			remove_cube_from_figure(petya);
		else
			break;
	}

	resp = 0LL; pow = 1LL;
	for (i = m-1; i >= 0; i--)
	{
		resp += ((vp[i] * pow) % MODULO);
		resp %= MODULO;

		pow *= (long long)m;
		pow %= MODULO;
	}

	cout<<resp<<endl;

	return 0;
}


#include <iostream>
#include <set>

using namespace std;

#define MODULO				1000000009LL

typedef struct cube_s
{
	int x;
	int y;
	int count;
	int  val;
}cube_t;

typedef set <cube_t *, bool (*)(cube_t *, cube_t *)> set_cubes_t;

bool figure_comp(cube_t * a, cube_t * b)
{
	return ((a->y < b->y) || (a->y == b->y && a->x < b->x));
}

bool free_comp(cube_t * a, cube_t * b)
{
	return (a->val < b->val);
}

int idx = 0;
long long *vp;
set_cubes_t figure(figure_comp), free_cubes(free_comp);

void remove_cube_from_figure(cube_t *cube)
{
	cube_t val, *found;

	figure.erase(cube);
	free_cubes.erase(cube);

	val.y = cube->y-1;
	for (val.x = cube->x-1; val.x <= cube->x+1; val.x++)
	{
		found = *figure.find(&val);
		if (found != *figure.end() && --found->count == 0)
		{
			free_cubes.insert(found);
		}
	}

	vp[idx++] = cube->val;
}

int main()
{
	int m, i;
	long long resp, pow;
	cube_t *cubes, *cube, *vasya, *petya,  val;
	set_cubes_t::iterator it;

	cin>>m;

	vp = new long long[m];
	cubes = new cube_t[m];

	for (i = 0; i < m; i++)
	{
		cin>>cubes[i].x>>cubes[i].y;
		cubes[i].count = 0;
		cubes[i].val = i;

		figure.insert(&cubes[i]);
	}

	for (it = figure.begin(); it != figure.end(); it++)
	{
		val.y = (*it)->y - 1;
		for (val.x = (*it)->x-1; val.x <= (*it)->x+1; val.x++)
		{
			cube = *figure.find(&val);

			if (cube != *figure.end())
			{
				cube->count++;
			}
		}
	}

	for (it = figure.begin(); it != figure.end(); it++)
	{
		if (!(*it)->count)
		{
			free_cubes.insert(*it);
		}
	}

	while (1)
	{
		vasya = *free_cubes.rbegin();
		if (vasya != *free_cubes.end())
			remove_cube_from_figure(vasya);
		else
			break;

		petya = *free_cubes.begin();
		if (petya != *free_cubes.end())
			remove_cube_from_figure(petya);
		else
			break;
	}

	resp = 0LL; pow = 1LL;
	for (i = m-1; i >= 0; i--)
	{
		resp += ((vp[i] * pow) % MODULO);
		resp %= MODULO;

		pow *= (long long)m;
		pow %= MODULO;
	}

	cout<<resp<<endl;

	return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <set>

bool can_delete(std::map< std::pair<long, long>, long> const &cubes, long x, long y)
{
	if (cubes.find(std::make_pair(x - 1, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x - 2, y)) == cubes.end()
			&& cubes.find(std::make_pair(x - 1, y)) == cubes.end());
			return false;
	}

	if (cubes.find(std::make_pair(x, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x - 1, y)) == cubes.end()
			&& cubes.find(std::make_pair(x + 1, y)) == cubes.end());
			return false;
	}

	if (cubes.find(std::make_pair(x + 1, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x + 2, y)) == cubes.end()
			&& cubes.find(std::make_pair(x + 1, y)) == cubes.end());
			return false;
	}

	return true;
}

int main()
{
	unsigned long long m;
	std::cin >> m;

	std::vector<long> xs(m, 0);
	std::vector<long> ys(m, 0);
	std::map< std::pair<long, long>, long> cubes;

	for (long i = 0; i != m; ++i) {
		std::cin >> xs[i] >> ys[i];
		cubes.insert(std::make_pair(std::make_pair(xs[i], ys[i]), i));
	}

	std::set<long> numbers;
	for (long i = 0; i != m; ++i) {
		long const x = xs[i];
		long const y = ys[i];

		if (can_delete(cubes, x, y))
			numbers.insert(i);
	}

	unsigned long long result = 0;
	unsigned long long base = 1000000009;
	while (!numbers.empty()) {
		{
			std::set<long>::iterator it = --numbers.end();
			unsigned long long const max = *it;
			numbers.erase(it);

			result = (result * m + max) % base;
			long const x = xs[max];
			long const y = ys[max];

			cubes.erase(cubes.find(std::make_pair(x, y)));

			std::map< std::pair<long, long>, long>::iterator pit = cubes.find(std::make_pair(x - 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 2, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 2, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x - 1, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x + 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x + 1, y - 1))
				numbers.insert(pit->second);
		}
		if (!numbers.empty()) {
			std::set<long>::iterator it = numbers.begin();
			unsigned long long const min = *it;
			numbers.erase(it);

			result = (result * m + min) % base;
			long const x = xs[min];
			long const y = ys[min];

			cubes.erase(cubes.find(std::make_pair(x, y)));

			std::map< std::pair<long, long>, long>::iterator pit = cubes.find(std::make_pair(x - 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 2, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 2, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x - 1, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x + 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x + 1, y - 1))
				numbers.insert(pit->second);
		}
	}

	std::cout << result << std::endl;

	return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <set>

bool can_delete(std::map< std::pair<long, long>, long> const &cubes, long x, long y)
{
	if (cubes.find(std::make_pair(x - 1, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x - 2, y)) == cubes.end()
			&& cubes.find(std::make_pair(x - 1, y)) == cubes.end());
			return false;
	}

	if (cubes.find(std::make_pair(x, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x - 1, y)) == cubes.end()
			&& cubes.find(std::make_pair(x + 1, y)) == cubes.end());
			return false;
	}

	if (cubes.find(std::make_pair(x + 1, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x + 2, y)) == cubes.end()
			&& cubes.find(std::make_pair(x + 1, y)) == cubes.end());
			return false;
	}

	return true;
}

int main()
{
	unsigned long long m;
	std::cin >> m;

	std::vector<long> xs(m, 0);
	std::vector<long> ys(m, 0);
	std::map< std::pair<long, long>, long> cubes;

	for (long i = 0; i != m; ++i) {
		std::cin >> xs[i] >> ys[i];
		cubes.insert(std::make_pair(std::make_pair(xs[i], ys[i]), i));
	}

	std::set<long> numbers;
	for (long i = 0; i != m; ++i) {
		long const x = xs[i];
		long const y = ys[i];

		if (can_delete(cubes, x, y))
			numbers.insert(i);
	}

	unsigned long long result = 0;
	unsigned long long base = 1000000009;
	while (!numbers.empty()) {
		{
			std::set<long>::iterator it = --numbers.end();
			unsigned long long const max = *it;
			numbers.erase(it);

			result = (result * m + max) % base;
			long const x = xs[max];
			long const y = ys[max];

			cubes.erase(cubes.find(std::make_pair(x, y)));

			std::map< std::pair<long, long>, long>::iterator pit = cubes.find(std::make_pair(x - 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x - 1, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x + 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x + 1, y - 1))
				numbers.insert(pit->second);
		}
		if (!numbers.empty()) {
			std::set<long>::iterator it = numbers.begin();
			unsigned long long const min = *it;
			numbers.erase(it);

			result = (result * m + min) % base;
			long const x = xs[min];
			long const y = ys[min];

			cubes.erase(cubes.find(std::make_pair(x, y)));

			std::map< std::pair<long, long>, long>::iterator pit = cubes.find(std::make_pair(x - 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x - 1, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x + 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x + 1, y - 1))
				numbers.insert(pit->second);
		}
	}

	std::cout << result << std::endl;

	return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <set>

bool can_delete(std::map< std::pair<long, long>, long> const &cubes, long x, long y)
{
	if (cubes.find(std::make_pair(x - 1, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x - 2, y)) == cubes.end()
			&& cubes.find(std::make_pair(x - 1, y)) == cubes.end());
			return false;
	}

	if (cubes.find(std::make_pair(x, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x - 1, y)) == cubes.end()
			&& cubes.find(std::make_pair(x + 1, y)) == cubes.end());
			return false;
	}

	if (cubes.find(std::make_pair(x + 1, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x + 2, y)) == cubes.end()
			&& cubes.find(std::make_pair(x + 1, y)) == cubes.end());
			return false;
	}

	return true;
}

int main()
{
	long m;
	std::cin >> m;

	std::vector<long> xs(m, 0);
	std::vector<long> ys(m, 0);
	std::map< std::pair<long, long>, long> cubes;

	for (long i = 0; i != m; ++i) {
		std::cin >> xs[i] >> ys[i];
		cubes.insert(std::make_pair(std::make_pair(xs[i], ys[i]), i));
	}

	std::set<long> numbers;
	for (long i = 0; i != m; ++i) {
		long const x = xs[i];
		long const y = ys[i];

		if (can_delete(cubes, x, y))
			numbers.insert(i);
	}

	unsigned long result = 0;
	unsigned long base = 1000000009;
	while (!numbers.empty()) {
		{
			std::set<long>::iterator it = --numbers.end();
			long const max = *it;
			numbers.erase(it);

			result = (result * m + max) % base;
			long const x = xs[max];
			long const y = ys[max];

			cubes.erase(cubes.find(std::make_pair(x, y)));

			std::map< std::pair<long, long>, long>::iterator pit = cubes.find(std::make_pair(x - 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x - 1, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x + 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x + 1, y - 1))
				numbers.insert(pit->second);
		}
		if (!numbers.empty()) {
			std::set<long>::iterator it = numbers.begin();
			long const min = *it;
			numbers.erase(it);

			result = (result * m + min) % base;
			long const x = xs[min];
			long const y = ys[min];

			cubes.erase(cubes.find(std::make_pair(x, y)));

			std::map< std::pair<long, long>, long>::iterator pit = cubes.find(std::make_pair(x - 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x - 1, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x + 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x + 1, y - 1))
				numbers.insert(pit->second);
		}
	}

	std::cout << result << std::endl;

	return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <set>

bool can_delete(std::map< std::pair<long, long>, long> const &cubes, long x, long y)
{
	if (cubes.find(std::make_pair(x - 1, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x - 2, y)) == cubes.end()
			&& cubes.find(std::make_pair(x - 1, y)) == cubes.end())
			return false;
	}

	if (cubes.find(std::make_pair(x, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x - 1, y)) == cubes.end()
			&& cubes.find(std::make_pair(x + 1, y)) == cubes.end())
			return false;
	}

	if (cubes.find(std::make_pair(x + 1, y + 1)) != cubes.end()) {
		if (cubes.find(std::make_pair(x + 2, y)) == cubes.end()
			&& cubes.find(std::make_pair(x + 1, y)) == cubes.end())
			return false;
	}

	return true;
}

int main()
{
	unsigned long long m;
	std::cin >> m;

	std::vector<long> xs(m, 0);
	std::vector<long> ys(m, 0);
	std::map< std::pair<long, long>, long> cubes;

	for (long i = 0; i != m; ++i) {
		std::cin >> xs[i] >> ys[i];
		cubes.insert(std::make_pair(std::make_pair(xs[i], ys[i]), i));
	}

	std::set<long> numbers;
	for (long i = 0; i != m; ++i) {
		long const x = xs[i];
		long const y = ys[i];

		if (can_delete(cubes, x, y)) {
			numbers.insert(i);
		}
	}

	unsigned long long result = 0;
	unsigned long long base = 1000000009;
	while (!numbers.empty()) {
		{
			std::set<long>::iterator it = --numbers.end();
			unsigned long long const max = *it;
			numbers.erase(it);

			result = (result * m + max) % base;
			long const x = xs[max];
			long const y = ys[max];

			cubes.erase(cubes.find(std::make_pair(x, y)));

			std::map< std::pair<long, long>, long>::iterator pit = cubes.find(std::make_pair(x - 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 2, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 2, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 2, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 2, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x - 1, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x + 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x + 1, y - 1))
				numbers.insert(pit->second);
		}
		if (!numbers.empty()) {
			std::set<long>::iterator it = numbers.begin();
			unsigned long long const min = *it;
			numbers.erase(it);

			result = (result * m + min) % base;
			long const x = xs[min];
			long const y = ys[min];

			cubes.erase(cubes.find(std::make_pair(x, y)));

			std::map< std::pair<long, long>, long>::iterator pit = cubes.find(std::make_pair(x - 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 2, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x - 2, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 1, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 1, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x + 2, y));
			if (pit != cubes.end()) {
				it = numbers.find(pit->second);
				if (it != numbers.end() && !can_delete(cubes, x + 2, y))
					numbers.erase(it);
			}

			pit = cubes.find(std::make_pair(x - 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x - 1, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x, y - 1))
				numbers.insert(pit->second);

			pit = cubes.find(std::make_pair(x + 1, y - 1));
			if (pit != cubes.end() && can_delete(cubes, x + 1, y - 1))
				numbers.insert(pit->second);
		}
	}

	std::cout << result << std::endl;

	return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<set>
using namespace std;
const long long mod=1e9+9;
map<pair<long long,long long>,long long> mp;
long long m,x,y,pos,ans,p;
pair<long long,long long> a[111111];
set<long long> s;
long long finddown(long long x,long long y,pair<long long,long long> &p)
{
	long long res=0;
	if (mp[make_pair(x+1,y-1)])
	{
		res++;
		p=make_pair(x+1,y-1);
	}
	if (mp[make_pair(x,y-1)])
	{
		res++;
		p=make_pair(x,y-1);
	}
	if (mp[make_pair(x-1,y-1)])
	{
		res++;
		p=make_pair(x-1,y-1);
	}
	return res;
}
bool check(long long x,long long y)
{
	pair<long long,long long> p;
	if (mp[make_pair(x,y+1)] && finddown(x,y+1,p)==1) return 0;
	if (mp[make_pair(x+1,y+1)] && finddown(x+1,y+1,p)==1) return 0;
	if (mp[make_pair(x-1,y+1)] && finddown(x-1,y+1,p)==1) return 0;
	return 1;
}
void update(long long x,long long y)
{
	mp[make_pair(x,y)]=0;
	if (mp[make_pair(x-1,y-1)] && check(x-1,y-1)) s.insert(mp[make_pair(x-1,y-1)]-1);
	if (mp[make_pair(x,y-1)] && check(x,y-1)) s.insert(mp[make_pair(x,y-1)]-1);
	if (mp[make_pair(x+1,y-1)] && check(x+1,y-1)) s.insert(mp[make_pair(x+1,y-1)]-1);
	pair<long long,long long> p;
	if (mp[make_pair(x-1,y+1)] && finddown(x-1,y+1,p)==1 && s.find(mp[p]-1)!=s.end()) s.erase(s.find(mp[p]-1));
	if (mp[make_pair(x,y+1)] && finddown(x,y+1,p)==1 && s.find(mp[p]-1)!=s.end()) s.erase(s.find(mp[p]-1));
	if (mp[make_pair(x+1,y+1)] && finddown(x+1,y+1,p)==1 && s.find(mp[p]-1)!=s.end()) s.erase(s.find(mp[p]-1));
}
long long mul(long long a,long long n)
{
	long long res=1ll,p=a;
	for (long long i=n;i;i>>=1)
	{
		if (i&1) res=res*p%mod;
		p=p*p%mod;
	}
	return res;
}
void print()
{
	for (set<long long>::iterator it=s.begin();it!=s.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<"fuck"<<endl;
}
int main()
{
	scanf("%I64d",&m);
	for (long long i=0;i<m;i++)
	{
		scanf("%I64d%I64d",&x,&y);
		a[i]=make_pair(x,y);
		mp[make_pair(x,y)]=i+1;
	}
	for (long long i=0;i<m;i++)
	{
		if (check(a[i].first,a[i].second)) s.insert(i);
	}
	while(pos<m)
	{
		p=*s.rbegin();
		s.erase(s.find(p));
		ans=(ans+p*mul(m,m-pos-1)%mod)%mod;
		update(a[p].first,a[p].second);
		pos++;
		if (pos>=m) break;
		p=*s.begin();
		s.erase(s.find(p));
		ans=(ans+p*mul(m,m-pos-1)%mod)%mod;
		update(a[p].first,a[p].second);
		pos++;
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<set>
using namespace std;
const long long mod=1e9+9;
map<pair<long long,long long>,long long> mp;
long long m,x,y,pos,ans,p;
pair<long long,long long> a[111111];
set<long long> s;
bool check(long long x,long long y)
{
	if (!mp[make_pair(x,y+1)] &&
	!mp[make_pair(x+1,y+1)] &&
	!mp[make_pair(x-1,y+1)])
	return 1;
	return 0;
}
void update(int x,int y)
{
	mp[make_pair(x,y)]=0;
	if (mp[make_pair(x-1,y-1)] && check(x-1,y-1)) s.insert(mp[make_pair(x-1,y-1)]-1);
	if (mp[make_pair(x,y-1)] && check(x,y-1)) s.insert(mp[make_pair(x,y-1)]-1);
	if (mp[make_pair(x+1,y-1)] && check(x+1,y-1)) s.insert(mp[make_pair(x+1,y-1)]-1);
}
long long mul(long long a,long long n)
{
	long long res=1ll,p=a;
	for (int i=n;i;i>>=1)
	{
		if (i&1) res=res*p%mod;
		p=p*p%mod;
	}
	return res;
}
void print()
{
	for (set<long long>::iterator it=s.begin();it!=s.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}
int main()
{
	scanf("%I64d",&m);
	for (long long i=0;i<m;i++)
	{
		scanf("%I64d%I64d",&x,&y);
		a[i]=make_pair(x,y);
		mp[make_pair(x,y)]=i+1;
	}
	for (long long i=0;i<m;i++)
	{
		if (check(a[i].first,a[i].second)) s.insert(i);
	}
	while(pos<m)
	{
		p=*s.rbegin();
		s.erase(s.find(p));
		ans=(ans+p*mul(m,m-pos-1)%mod)%mod;
		update(a[p].first,a[p].second);
		pos++;
		if (pos>=m) break;
		p=*s.begin();
		s.erase(s.find(p));
		ans=(ans+p*mul(m,m-pos-1)%mod)%mod;
		update(a[p].first,a[p].second);
		pos++;
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<set>
using namespace std;
const long long mod=1e9+9;
map<pair<long long,long long>,long long> mp;
long long m,x,y,pos,ans,p;
pair<long long,long long> a[111111];
set<long long> s;
long long finddown(long long x,long long y,pair<long long,long long> &p)
{
	long long res=0;
	if (mp[make_pair(x+1,y-1)])
	{
		res++;
		p=make_pair(x+1,y-1);
	}
	if (mp[make_pair(x,y-1)])
	{
		res++;
		p=make_pair(x,y-1);
	}
	if (mp[make_pair(x-1,y-1)])
	{
		res++;
		p=make_pair(x-1,y-1);
	}
	return res;
}
bool check(long long x,long long y)
{
	pair<long long,long long> p;
	if (mp[make_pair(x,y+1)] && finddown(x,y+1,p)==1) return 0;
	if (mp[make_pair(x+1,y+1)] && finddown(x+1,y+1,p)==1) return 0;
	if (mp[make_pair(x-1,y+1)] && finddown(x-1,y+1,p)==1) return 0;
	return 1;
}
void update(long long x,long long y)
{
	mp[make_pair(x,y)]=0;
	if (mp[make_pair(x-1,y-1)] && check(x-1,y-1)) s.insert(mp[make_pair(x-1,y-1)]-1);
	if (mp[make_pair(x,y-1)] && check(x,y-1)) s.insert(mp[make_pair(x,y-1)]-1);
	if (mp[make_pair(x+1,y-1)] && check(x+1,y-1)) s.insert(mp[make_pair(x+1,y-1)]-1);
	pair<long long,long long> p;
	if (mp[make_pair(x-1,y+1)] && finddown(x-1,y+1,p)==1) s.erase(s.find(mp[p]-1));
	if (mp[make_pair(x,y+1)] && finddown(x,y+1,p)==1) s.erase(s.find(mp[p]-1));
	if (mp[make_pair(x+1,y+1)] && finddown(x+1,y+1,p)==1) s.erase(s.find(mp[p]-1));
}
long long mul(long long a,long long n)
{
	long long res=1ll,p=a;
	for (int i=n;i;i>>=1)
	{
		if (i&1) res=res*p%mod;
		p=p*p%mod;
	}
	return res;
}
void print()
{
	for (set<long long>::iterator it=s.begin();it!=s.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<"fuck"<<endl;
}
int main()
{
	scanf("%I64d",&m);
	for (long long i=0;i<m;i++)
	{
		scanf("%I64d%I64d",&x,&y);
		a[i]=make_pair(x,y);
		mp[make_pair(x,y)]=i+1;
	}
	for (long long i=0;i<m;i++)
	{
		if (check(a[i].first,a[i].second)) s.insert(i);
	}
	while(pos<m)
	{
		p=*s.rbegin();
		s.erase(s.find(p));
		ans=(ans+p*mul(m,m-pos-1)%mod)%mod;
		update(a[p].first,a[p].second);
		pos++;
		if (pos>=m) break;
		p=*s.begin();
		s.erase(s.find(p));
		ans=(ans+p*mul(m,m-pos-1)%mod)%mod;
		update(a[p].first,a[p].second);
		pos++;
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#define MAXN 100010
#define MOD 1000000009ll
typedef long long ll;
using namespace std;

map<pair<int,int>,int >Map;
set<pair<int,int> >Set;
set<int >leaf;

int  x[MAXN],y[MAXN],n;

ll res;
int count_parent(int x,int y)
{
	int s=0;
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y-1))!=Set.end())
			s++;
	return s;
}

bool isleaf(int x,int y)
{
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y+1))!=Set.end()&&count_parent(x+i,y+1)==1)
			return false;
	return true;

}

void update(int nown)
{
	for(int i=x[nown]-2;i<=x[nown]+2;i++)
		for(int j=y[nown]-2;j<=y[nown]+2;j++)
		{
			if (Set.find(make_pair(i,j))==Set.end()) continue;
			int id=Map[make_pair(i,j)];
			if (leaf.find(id)!=leaf.end()) leaf.erase(id);
			if (isleaf(x[id],y[id])) leaf.insert(id);
		}
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",x+i,y+i);
		Map[make_pair(x[i],y[i])]=i;
		Set.insert(make_pair(x[i],y[i]));
	}
	for(int i=0;i<n;i++)
		if (isleaf(x[i],y[i])) leaf.insert(i);

	for(int i=0;i<n;i++)
	{
		int nown;
		if (!i%2) nown=*(--leaf.end());
		else nown=*leaf.begin();
		res=(res*n+nown)%MOD;
		Set.erase (make_pair(x[nown],y[nown]) );
		leaf.erase(nown);
		update(nown);
	}
	printf("%I64d\n",res);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#define MAXN 100010
#define MOD 1000000009
typedef long long ll;
using namespace std;

map<pair<int,int>,int >Map;
set<pair<int,int> >Set;
set<int >leaf;

int  x[MAXN],y[MAXN],n;

ll res;
int count_parent(int x,int y)
{
	int s=0;
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y-1))!=Set.end())
			s++;
	return s;
}

bool isleaf(int x,int y)
{
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y+1))!=Set.end()&&count_parent(x+i,y+1)==1)
			return false;
	return true;

}

void update(int nown)
{
	for(int i=x[nown]-2;i<=x[nown]+2;i++)
		for(int j=y[nown]-2;j<=y[nown]+2;j++)
		{
			if (Set.find(make_pair(i,j))==Set.end()) continue;
			int id=Map[make_pair(i,j)];
			if (leaf.find(id)!=leaf.end()) leaf.erase(id);
			if (isleaf(i,j)) leaf.insert(id);
		}
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",x+i,y+i);
		Map[make_pair(x[i],y[i])]=i;
		Set.insert(make_pair(x[i],y[i]));
	}
	for(int i=0;i<n;i++)
		if (isleaf(x[i],y[i])) leaf.insert(i);

	for(int i=0;i<n;i++)
	{
		int nown;
		if (!i%2) nown=*(--leaf.end());
		else nown=*leaf.begin();
		res=(res*n+nown)%MOD;
		Set.erase (make_pair(x[nown],y[nown]) );
		leaf.erase(nown);
		update(nown);
	}
	printf("%d\n",res);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#define MAXN 100010
#define MOD 1000000009ll
typedef long long ll;
using namespace std;

map<pair<int,int>,int >Map;
set<pair<int,int> >Set;
set<int >leaf;

int  x[MAXN],y[MAXN],n;

ll res;
int count_parent(int x,int y)
{
	int s=0;
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y-1))!=Set.end())
			s++;
	return s;
}

bool isleaf(int x,int y)
{
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y+1))!=Set.end()&&count_parent(x+i,y+1)==1)
			return false;
	return true;

}

void update(int nown)
{
	for(int i=x[nown]-2;i<=x[nown]+2;i++)
		for(int j=y[nown]-2;j<=y[nown]+2;j++)
		{
			if (Set.find(make_pair(i,j))==Set.end()) continue;
			int id=Map[make_pair(i,j)];
			if (leaf.find(id)!=leaf.end()) leaf.erase(id);
			if (isleaf(x[id],y[id])) leaf.insert(id);
		}
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",x+i,y+i);
		Map[make_pair(x[i],y[i])]=i;
		Set.insert(make_pair(x[i],y[i]));
	}
	for(int i=0;i<n;i++)
		if (isleaf(x[i],y[i])) leaf.insert(i);

	for(int i=0;i<n;i++)
	{
		int nown;
		if (i%2==0) nown=*(--leaf.end());
		else nown=*(leaf.begin());

		res=(res*n+nown)%MOD;
		Set.erase (make_pair(x[nown],y[nown]) );
		leaf.erase(nown);
		update(nown);
	}
	printf("%I64d\n",res);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#define MAXN 100010
#define MOD 1000000009
typedef long long ll;
using namespace std;

map<pair<int,int>,int >Map;
set<pair<int,int> >Set;
set<int >leaf;

int  x[MAXN],y[MAXN],n;

ll res;
int count_parent(int x,int y)
{
	int s=0;
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y-1))!=Set.end())
			s++;
	return s;
}

bool isleaf(int x,int y)
{
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y+1))!=Set.end()&&count_parent(x+i,y+1)==1)
			return false;
	return true;

}

void update(int nown)
{
	for(int i=x[nown]-2;i<=x[nown]+2;i++)
		for(int j=y[nown]-2;j<=y[nown]+2;j++)
		{
			if (Set.find(make_pair(i,j))==Set.end()) continue;
			int id=Map[make_pair(i,j)];
			if (leaf.find(id)!=leaf.end()) leaf.erase(id);
			if (isleaf(x[id],y[id])) leaf.insert(id);
		}
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",x+i,y+i);
		Map[make_pair(x[i],y[i])]=i;
		Set.insert(make_pair(x[i],y[i]));
	}
	for(int i=0;i<n;i++)
		if (isleaf(x[i],y[i])) leaf.insert(i);

	for(int i=0;i<n;i++)
	{
		int nown;
		if (!i%2) nown=*(--leaf.end());
		else nown=*leaf.begin();
		res=(res*n+nown)%MOD;
		Set.erase (make_pair(x[nown],y[nown]) );
		leaf.erase(nown);
		update(nown);
	}
	printf("%I64d\n",res);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#define MAXN 100010
#define MOD 1000000009ll
typedef long long ll;
using namespace std;

map<pair<int,int>,int >Map;
set<pair<int,int> >Set;
set<int >leaf;

int  x[MAXN],y[MAXN],n;

ll res;
int count_parent(int x,int y)
{
	int s=0;
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y-1))!=Set.end())
			s++;
	return s;
}

bool isleaf(int x,int y)
{
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y+1))!=Set.end()&&count_parent(x+i,y+1)==1)
			return false;
	return true;

}

void update(int nown)
{
	for(int i=x[nown]-2;i<=x[nown]+2;i++)
		for(int j=y[nown]-2;j<=y[nown]+2;j++)
		{
			if (Set.find(make_pair(i,j))==Set.end()) continue;
			int id=Map[make_pair(i,j)];
			if (leaf.find(id)!=leaf.end()) leaf.erase(id);
			if (isleaf(x[id],y[id])) leaf.insert(id);
		}
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",x+i,y+i);
		Map[make_pair(x[i],y[i])]=i;
		Set.insert(make_pair(x[i],y[i]));
	}
	for(int i=0;i<n;i++)
		if (isleaf(x[i],y[i])) leaf.insert(i);

	for(int i=0;i<n;i++)
	{
		int nown;
		if (!i%2) nown=*(--leaf.end());
		else nown=*(leaf.begin());
		res=(res*n+nown)%MOD;
		Set.erase (make_pair(x[nown],y[nown]) );
		leaf.erase(nown);
		update(nown);
	}
	printf("%I64d\n",res);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#define MAXN 100010
#define MOD 1000000009ll
typedef long long ll;
using namespace std;

map<pair<int,int>,int >Map;
set<pair<int,int> >Set;
set<int >leaf;

int  x[MAXN],y[MAXN],n;

ll res;
int count_parent(int x,int y)
{
	int s=0;
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y-1))!=Set.end())
			s++;
	return s;
}

bool isleaf(int x,int y)
{
	for(int i=-1;i<=1;i++)
		if (Set.find(make_pair(x+i,y+1))!=Set.end()&&count_parent(x+i,y+1)==1)
			return false;
	return true;

}

void update(int nown)
{
	for(int i=x[nown]-1;i<=x[nown]+1;i++)
		for(int j=y[nown]-1;j<=y[nown]+1;j++)
		{
			if (Set.find(make_pair(i,j))==Set.end()) continue;
			int id=Map[make_pair(i,j)];
			if (leaf.find(id)!=leaf.end()) leaf.erase(id);
			if (isleaf(x[id],y[id])) leaf.insert(id);
		}
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",x+i,y+i);
		Map[make_pair(x[i],y[i])]=i;
		Set.insert(make_pair(x[i],y[i]));
	}
	for(int i=0;i<n;i++)
		if (isleaf(x[i],y[i])) leaf.insert(i);

	for(int i=0;i<n;i++)
	{
		int nown;
		if (!i%2) nown=*(--leaf.end());
		else nown=*(leaf.begin());
		res=(res*n+nown)%MOD;
		Set.erase (make_pair(x[nown],y[nown]) );
		leaf.erase(nown);
		update(nown);
	}
	printf("%I64d\n",res);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define INF 99999999999
#define NMAX 100000+5
#define MOD 1000000000+9

pair <long long, long long> p[NMAX];
map <pair<long long, long long>, long long> c;
set <long long> s;

bool comprobar(long long x, long long y)
{
    if(c[mp(x, y)]==0)
        return true;
    if((c[mp(x-1, y-1)]>0) + (c[mp(x, y-1)]>0) + (c[mp(x+1, y-1)]>0)>1)
        return true;
    return false;
}

void comprobar1(long long x, long long y)
{
    if(c[mp(x-2, y)] and s.count(c[mp(x-2, y)]) and !comprobar(x-1, y+1))
        s.erase(c[mp(x-2, y)]);
    if(c[mp(x-1, y)] and s.count(c[mp(x-1, y)]) and (!comprobar(x-1, y+1) or !comprobar(x, y+1)))
        s.erase(c[mp(x-1, y)]);
    if(c[mp(x+1, y)] and s.count(c[mp(x+1, y)]) and (!comprobar(x+1, y+1) or !comprobar(x, y+1)))
        s.erase(c[mp(x+1, y)]);
    if(c[mp(x+2, y)] and s.count(c[mp(x+2, y)]) and !comprobar(x+1, y+1))
        s.erase(c[mp(x+2, y)]);
    if(c[mp(x-1, y-1)] and s.count(c[mp(x-1, y-1)])==0 and comprobar(x-2, y) and comprobar(x-1, y))
        s.insert(c[mp(x-1, y-1)]);
    if(c[mp(x, y-1)] and s.count(c[mp(x, y-1)])==0 and comprobar(x-1, y) and comprobar(x+1, y))
        s.insert(c[mp(x, y-1)]);
    if(c[mp(x+1, y-1)] and s.count(c[mp(x+1, y-1)])==0 and comprobar(x+1, y) and comprobar(x+2, y))
        s.insert(c[mp(x+1, y-1)]);
}

int main()
{
    long long m;
    cin>>m;
    long long x[m], y[m];
    for(long long i=0;i<m;i++)
    {
        cin>>x[i]>>y[i];
        c[mp(x[i], y[i])]=i+1;
        p[i+1]=mp(x[i], y[i]);
    }
    for(long long i=0;i<m;i++)
    {
        if(comprobar(x[i]-1, y[i]+1) and comprobar(x[i], y[i]+1) and comprobar(x[i]+1, y[i]+1))
            s.insert(i+1);
    }
    set <long long>::iterator it;
    long long sol[m], asdf=0;
    for(long long e=0;e<m;e++)
    {
        if(asdf==0)
        {
            it=s.end();
            it--;
        }
        else
        {
            it=s.begin();
        }
        asdf++;
        asdf%=2;
        sol[e]=*it-1;
        long long i=p[*it].first, j=p[*it].second;
        s.erase(it);
        c.erase(mp(i, j));
        comprobar1(i, j);
    }
    long long pot=1, ans=0;
    for(long long i=m-1;i>=0;i--)
    {
        ans+=(pot*sol[i]);
        ans%=MOD;
        pot*=m;
        pot%=MOD;
    }
    cout<<ans<<endl;
}


#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define INF 99999999999
#define NMAX 100000+5
#define MOD 1000000000+9

pair <long long, long long> p[NMAX];
map <pair<long long, long long>, int> c;
set <int> s;

bool comprobar(long long x, long long y)
{
    if(c[mp(x, y)]==0)
        return true;
    if((c[mp(x-1, y-1)]>0) + (c[mp(x, y-1)]>0) + (c[mp(x+1, y-1)]>0)>1)
        return true;
    return false;
}

void comprobar1(long long x, long long y)
{
    if(c[mp(x-2, y)] and s.count(c[mp(x-2, y)]) and !comprobar(x-1, y+1))
        s.erase(c[mp(x-2, y)]);
    if(c[mp(x-1, y)] and s.count(c[mp(x-1, y)]) and (!comprobar(x-1, y+1) or !comprobar(x, y+1)))
        s.erase(c[mp(x-1, y)]);
    if(c[mp(x+1, y)] and s.count(c[mp(x+1, y)]) and (!comprobar(x+1, y+1) or !comprobar(x, y+1)))
        s.erase(c[mp(x+1, y)]);
    if(c[mp(x+2, y)] and s.count(c[mp(x+2, y)]) and !comprobar(x+1, y+1))
        s.erase(c[mp(x+2, y)]);
    if(c[mp(x-1, y-1)] and s.count(c[mp(x-1, y-1)])==0 and !c[mp(x-2, y)] and !c[mp(x-1, y)])
        s.insert(c[mp(x-1, y-1)]);
    if(c[mp(x, y-1)] and s.count(c[mp(x, y-1)])==0 and !c[mp(x-1, y)] and !c[mp(x+1, y)])
        s.insert(c[mp(x, y-1)]);
    if(c[mp(x+1, y-1)] and s.count(c[mp(x+1, y-1)])==0 and !c[mp(x+1, y)] and !c[mp(x+2, y)])
        s.insert(c[mp(x+1, y-1)]);
}

int main()
{
    int m;
    cin>>m;
    long long x[m], y[m];
    for(int i=0;i<m;i++)
    {
        cin>>x[i]>>y[i];
        c[mp(x[i], y[i])]=i+1;
        p[i+1]=mp(x[i], y[i]);
    }
    for(int i=0;i<m;i++)
    {
        if(comprobar(x[i]-1, y[i]+1) and comprobar(x[i], y[i]+1) and comprobar(x[i]+1, y[i]+1))
            s.insert(i+1), cerr<<i+1<<": "<<x[i]<<' '<<y[i]<<endl;
    }
    set <int>::iterator it;
    long long sol[m], asdf=0;
    for(int e=0;e<m;e++)
    {
        if(asdf==0)
        {
            it=s.end();
            it--;
        }
        else
        {
            it=s.begin();
        }
        asdf++;
        asdf%=2;
        sol[e]=*it-1;
        long long i=p[*it].first, j=p[*it].second;
        s.erase(it);
        c.erase(mp(i, j));
        comprobar1(i, j);
    }
    long long pot=1, ans=0;
    for(int i=m-1;i>=0;i--)
    {
        ans+=(pot*sol[i]);
        ans%=MOD;
        pot*=m;
        pot%=MOD;
    }
    cout<<ans<<endl;
}


#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define INF 99999999999
#define NMAX 100000+5
#define MOD 1000000000+9

pair <long long, long long> p[NMAX];
map <pair<long long, long long>, long long> c;
set <long long> s;

bool comprobar(long long x, long long y)
{
    if(c[mp(x, y)]==0)
        return true;
    if((c[mp(x-1, y-1)]>0) + (c[mp(x, y-1)]>0) + (c[mp(x+1, y-1)]>0)>1)
        return true;
    return false;
}

void comprobar1(long long x, long long y)
{
    if(c[mp(x-2, y)] and s.count(c[mp(x-2, y)]) and !comprobar(x-1, y+1))
        s.erase(c[mp(x-2, y)]);
    if(c[mp(x-1, y)] and s.count(c[mp(x-1, y)]) and (!comprobar(x-1, y+1) or !comprobar(x, y+1)))
        s.erase(c[mp(x-1, y)]);
    if(c[mp(x+1, y)] and s.count(c[mp(x+1, y)]) and (!comprobar(x+1, y+1) or !comprobar(x, y+1)))
        s.erase(c[mp(x+1, y)]);
    if(c[mp(x+2, y)] and s.count(c[mp(x+2, y)]) and !comprobar(x+1, y+1))
        s.erase(c[mp(x+2, y)]);
    if(c[mp(x-1, y-1)] and s.count(c[mp(x-1, y-1)])==0 and comprobar(x-2, y) and comprobar(x-1, y))
        s.insert(c[mp(x-1, y-1)]);
    if(c[mp(x, y-1)] and s.count(c[mp(x, y-1)])==0 and comprobar(x-1, y) and comprobar(x+1, y))
        s.insert(c[mp(x, y-1)]);
    if(c[mp(x+1, y-1)] and s.count(c[mp(x+1, y-1)])==0 and comprobar(x+1, y) and comprobar(x+2, y))
        s.insert(c[mp(x+1, y-1)]);
}

int main()
{
    long long m;
    cin>>m;
    long long x[m], y[m];
    for(long long i=0;i<m;i++)
    {
        cin>>x[i]>>y[i];
        c[mp(x[i], y[i])]=i+1;
        p[i+1]=mp(x[i], y[i]);
    }
    for(long long i=0;i<m;i++)
    {
        if(comprobar(x[i]-1, y[i]+1) and comprobar(x[i], y[i]+1) and comprobar(x[i]+1, y[i]+1))
            s.insert(i+1),
    }
    set <long long>::iterator it;
    long long sol[m], asdf=0;
    for(long long e=0;e<m;e++)
    {
        if(asdf==0)
        {
            it=s.end();
            it--;
        }
        else
        {
            it=s.begin();
        }
        asdf++;
        asdf%=2;
        sol[e]=*it-1;
        long long i=p[*it].first, j=p[*it].second;
        s.erase(it);
        c.erase(mp(i, j));
        comprobar1(i, j);
    }
    long long pot=1, ans=0;
    for(long long i=m-1;i>=0;i--)
    {
        ans+=(pot*sol[i]);
        ans%=MOD;
        pot*=m;
        pot%=MOD;
    }
    cout<<ans<<endl;
}


#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define INF 99999999999
#define NMAX 100000+5
#define MOD 1000000000+9

pair <int, int> p[NMAX];
map <pair<int, int>, int> c;
set <int> s;

bool comprobar(int x, int y)
{
	if(c[mp(x, y)]==0)
		return true;
	if((c[mp(x-1, y-1)]>0) + (c[mp(x, y-1)]>0) + (c[mp(x+1, y-1)]>0)>1)
		return true;
	return false;
}

void comprobar1(int x, int y)
{
	if(c[mp(x-2, y)] and s.count(c[mp(x-2, y)]) and !comprobar(x-1, y+1))
		s.erase(c[mp(x-2, y)]);
	if(c[mp(x-1, y)] and s.count(c[mp(x-1, y)]) and (!comprobar(x-1, y+1) or !comprobar(x, y+1)))
		s.erase(c[mp(x-1, y)]);
	if(c[mp(x+1, y)] and s.count(c[mp(x+1, y)]) and (!comprobar(x+1, y+1) or !comprobar(x, y+1)))
		s.erase(c[mp(x+1, y)]);
	if(c[mp(x+2, y)] and s.count(c[mp(x+2, y)]) and !comprobar(x+1, y+1))
		s.erase(c[mp(x+2, y)]);
	if(c[mp(x-1, y-1)] and s.count(c[mp(x-1, y-1)])==0 and !c[mp(x-2, y)] and !c[mp(x-1, y)])
		s.insert(c[mp(x-1, y-1)]);
	if(c[mp(x, y-1)] and s.count(c[mp(x, y-1)])==0 and !c[mp(x-1, y)] and !c[mp(x+1, y)])
		s.insert(c[mp(x, y-1)]);
	if(c[mp(x+1, y-1)] and s.count(c[mp(x+1, y-1)])==0 and !c[mp(x+1, y)] and !c[mp(x+2, y)])
		s.insert(c[mp(x+1, y-1)]);
}

int main()
{
	int m;
	cin>>m;
	int x[m], y[m];
	for(int i=0;i<m;i++)
	{
		cin>>x[i]>>y[i];
		c[mp(x[i], y[i])]=i+1;
		p[i+1]=mp(x[i], y[i]);
	}
	for(int i=0;i<m;i++)
	{
		if(comprobar(x[i]-1, y[i]+1) and comprobar(x[i], y[i]+1) and comprobar(x[i]+1, y[i]+1))
			s.insert(i+1), cerr<<i+1<<": "<<x[i]<<' '<<y[i]<<endl;
	}
	set <int>::iterator it;
	int sol[m], asdf=0;
	for(int e=0;e<m;e++)
	{
		if(asdf==0)
		{
			it=s.end();
			it--;
		}
		else
		{
			it=s.begin();
		}
		asdf++;
		asdf%=2;
		sol[e]=*it-1;
		int i=p[*it].first, j=p[*it].second;
		s.erase(it);
		c.erase(mp(i, j));
		comprobar1(i, j);
	}
	long long pot=1, ans=0;
	for(int i=m-1;i>=0;i--)
	{
		ans+=(pot*sol[i]);
		ans%=MOD;
		pot*=m;
		pot%=MOD;
	}
	cout<<ans<<endl;
}


#include <iostream>
#include <set>
#include <map>

#define rep(i,n) for(int i=0;i<n;i++)
#define pi pair<int,int>
#define ll long long
#define MOD 1000000009L

using namespace std;

int n,x[100010],y[100010],c[100010],dx[3]={-1,0,1},nx,ny,b,p,q;
map< pi, int> m;
set< int > s;
ll r,k[100010];
set<int>::iterator it;

int main(){
  cin>>n;
  rep(i,n){
    cin>>x[i]>>y[i];
    m[pi(x[i],y[i])] = i+1;
  }
  rep(i,n){
    rep(j,3){
      nx = x[i] + dx[j];
      ny = y[i] + 1;
      if(m[pi(nx,ny)]!=0){
        c[i]++;
      }
    }
    if(c[i]==0)s.insert(i);
  }
  k[0] = 1; rep(i,100010)k[i+1] = k[i]*n%MOD;
   r=0;
  while(!s.empty()){
    b++;
    if(b%2){
      it = s.end();it--;
      p = *it;
      s.erase(it);
    }
    else {
      it = s.begin();
      p = *it;
      s.erase(it);
    }

    rep(j,3){
      nx = x[p]+dx[j];
      ny = y[p]-1;
      q = m[pi(nx,ny)];
      if(q!=0 && (--c[q-1]==0)){
        s.insert(q-1);
      }
    }
    r = (r+k[n-b]*p%MOD)%MOD;
  }
  cout<<r<<endl;
}


#include <iostream>
#include <set>
#include <map>

#define rep(i,n) for(int i=0;i<n;i++)
#define pi pair<int,int>
#define ll long long
#define MOD 1000000009L

using namespace std;

int n,x[100010],y[100010],c[100010],dx[3]={-1,0,1},nx,ny,b,p,q;
map< pi, int> m;
set< int > s;
ll r,k[100010];
set<int>::iterator it;

int main(){
  cin>>n;
  rep(i,n){
    cin>>x[i]>>y[i];
    m[pi(x[i],y[i])] = i+1;
  }
  rep(i,n){
    rep(j,3){
      nx = x[i] + dx[j];
      ny = y[i] + 1;
      if(m[pi(nx,ny)]!=0){
        c[i]++;
      }
    }
    if(c[i]==0)s.insert(i);
  }
  k[0] = 1; rep(i,100010)k[i+1] = k[i]*n%MOD;

  while(!s.empty()){
    b++;
    if(b%2){
      it = s.end();it--;
      p = *it;
      s.erase(it);
    }
    else {
      it = s.begin();
      p = *it;
      s.erase(it);
    }

    rep(j,3){
      nx = x[p]+dx[j];
      ny = y[p]-1;
      q = m[pi(nx,ny)];
      if(q!=0 && (--c[q-1]==0)){
        s.insert(q-1);
      }
    }
    r += k[n-b]*p%MOD;
  }
  cout<<r<<endl;
}


#include <iostream>
#include <set>
#include <map>

#define rep(i,n) for(int i=0;i<n;i++)
#define pi pair<int,int>
#define ll long long
#define MOD 1000000009L

using namespace std;

int n,x[100010],y[100010],c[100010],dx[3]={-1,0,1},nx,ny,b,p,q;
map< pi, int> m;
set< int > s;
ll r,k[100010];
set<int>::iterator it;

int main(){
  cin>>n;
  rep(i,n){
    cin>>x[i]>>y[i];
    m[pi(x[i],y[i])] = i+1;
  }
  rep(i,n){
    rep(j,3){
      nx = x[i] + dx[j];
      ny = y[i] + 1;
      if(m[pi(nx,ny)]!=0){
        c[i]++;
      }
    }
    if(c[i]==0)s.insert(i);
  }
  k[0] = 1; rep(i,100010)k[i+1] = k[i]*n%MOD;
   r=0;
  while(!s.empty()){
    b++;
    if(b%2){
      it = s.end();it--;
      p = *it;
      s.erase(it);
    }
    else {
      it = s.begin();
      p = *it;
      s.erase(it);
    }

    rep(j,3){
      nx = x[p]+dx[j];
      ny = y[p]-1;
      q = m[pi(nx,ny)];
      if(q!=0 && (--c[q-1]==0)){
        s.insert(q-1);
      }
    }
    r += k[n-b]*p%MOD;
  }
  cout<<r<<endl;
}