#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<int> linearEquationSolver(int n, int p, int q) {
	vector<int> solver;
	for (int a = 0; a < n; a++) {
		for (int b = 0; b < n; b++){
			if ( (a*p + b*q) == n) {
				solver.push_back(a);
				solver.push_back(b);
				return solver;
			}
		}
	}
	return solver;
}

int main(int argc, char const *argv[]) {
	int n, p, q;
	int a, b;
	int startPos = 0;
	string s;
	vector<int> solver;

	cin >> n >> p >> q;
	cin >> s;

	if (n == p || n == q) {
		cout << 1 << endl;
		cout << s << endl;
	}
	else {
		solver= linearEquationSolver(n, p, q);
		if (solver.empty())
			cout << -1;

		else {
			a = solver[0];
			b = solver[1];

			cout << a+b << endl;

			if (a > 0) {
				for (int i = 0; i < a; i++) {
					cout << s.substr(startPos, p) << endl;
					startPos = startPos + p;
				}
			}

			if (b > 0) {
				for (int i = 0; i < b; i++){
					cout << s.substr(startPos, q) << endl;
					startPos = startPos + q;
				}
			}
		}
	}
	return 0;
}


#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<int> linearEquationSolver(int n, int p, int q) {
	vector<int> solver;
	for (int a = 0; a < n; a++) {
		for (int b = 0; b < n; b++){
			if ( (a*p + b*q) == n) {
				solver.push_back(a);
				solver.push_back(b);
				return solver;
			}
		}
	}
	return solver;
}

int main(int argc, char const *argv[]) {
	int n, p, q;
	int a, b;
	int startPos = 0;
	string s;
	vector<int> solver;

	cin >> n >> p >> q;
	cin >> s;

	solver= linearEquationSolver(n, p, q);

	if (solver.empty())
		cout << -1;
	else {
		a = solver[0];
		b = solver[1];

		cout << a+b << endl;

		if (a > 0) {
			for (int i = 0; i < a; i++) {
				cout << s.substr(startPos, p) << endl;
				startPos = startPos + p;
			}
		}

		if (b > 0) {
			for (int i = 0; i < b; i++){
				cout << s.substr(startPos, q) << endl;
				startPos = startPos + q;
			}
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<string>v;
void process(int n , int p, int q, string str){
    int x = 0,s =0,z=p;
    string a,b;
    while(x < n){
        a = "", b = "";
        for(int i = s; i < p+s; i++){
            a += str[i];
        }
        v.push_back(a);
        for(int j = z; j < z+q; j++){
            b += str[j];
        }
        v.push_back(b);
        x += p+q;
        s = x;
        z = s+p;
    }
}
int main() {
    int n,p,q;
    cin >> n >> p >> q;
    string str; cin >> str;
    if(str.size() == 1 && min(p,q) == 1){
        cout << str.size() << endl;
        cout << str[0] << endl;
    }
    else if(p + q <= n){
        process(n,p,q,str);
        cout << v.size() << endl;
        for(auto s : v)
            cout <<  s << endl;
    }
    else{
        int m = min(p,q);
        if( (n % m) != 0)
            cout << -1 << endl;
        else{
            process(n,m,m,str);
            cout << v.size() << endl;
            for(auto s : v)
                cout << s << endl;
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

int main(){
    string s;
    int nn,a,b,p=-1,q=-1;
    cin>>nn>>a>>b;
    cin>>s;
    for(int i=0;i<=nn;i++){
        int tpp = i, tpq = nn - tpp;
        //trace(tpp,tpq,tpp%a,tpq%b);
        if(tpp%a==0 and tpq%b==0){
            p = tpp;
            q = tpq;
            break;
        }
    }
    if(p == -1 and q == -1) cout<<-1<<endl;
    else{
        int n = p/a, m = q/b;
        //trace(n,m);
        cout<<n+m<<endl;
        int y = 0;
        for(int i=0;i<n;i++) {
            for(int j = y; j < a+y; j++){
                cout << s[j];
            }cout << endl;
            y += a;
        }
        for(int i=0;i<m;i++) {
            int x = y;
            for(int j = y; j < x+b; j++){
                cout << s[j];
            }
            cout << endl;
            y+=b;
            x+=b;
        }
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<string>v;
void process(int n , int p, int q, string str){
    int x = 0,s =0,z=p;
    string a,b;
    while(x < n){
        a = "", b = "";
        for(int i = s; i < p+s; i++){
            a += str[i];
        }
        v.push_back(a);
        for(int j = z; j < z+q; j++){
            b += str[j];
        }
        v.push_back(b);
        x += p+q;
        s = x;
        z = s+p;
    }
}
int main() {
    int n,p,q;
    cin >> n >> p >> q;
    string str; cin >> str;
    if(str.size() == 1 && min(p,q) == 1){
        cout << str.size() << endl;
        cout << str[0] << endl;
    }
    else if ( n % (p + q) == 0){
        process(n,p,q,str);
        cout << v.size() << endl;
        for(auto s : v)
            cout <<  s << endl;
    }
    else{
        int m = min(p,q);
        if( (n % m) != 0)
            cout << -1 << endl;
        else{
            process(n,m,m,str);
            cout << n / m << endl;
            for(int i = 0; i < n/m; i++)
                cout << v[i] << endl;
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

vector<string>v;
void process(int n , int p, int q, string str){
    int x = 0,s =0,z=p;
    string a,b;
    while(x < n){
        a = "", b = "";
        for(int i = s; i < p+s; i++){
            a += str[i];
        }
        v.push_back(a);
        for(int j = z; j < z+q; j++){
            b += str[j];
        }
        v.push_back(b);
        x += p+q;
        s = x;
        z = s+p;
    }
}
int main() {
    int n,p,q;
    cin >> n >> p >> q;
    string str; cin >> str;
    if(str.size() == 1 && min(p,q) == 1){
        cout << str.size() << endl;
        cout << str[0] << endl;
    }
    else if ( n % (p + q) == 0){
        process(n,p,q,str);
        cout << v.size() << endl;
        for(auto s : v)
            cout <<  s << endl;
    }
    else{
        int m = min(p,q);
        if( (n % m) != 0)
            cout << -1 << endl;
        else{
            process(n,m,m,str);
            cout << v.size() << endl;
            for(auto s : v)
                cout << s << endl;
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

vector<string>v;
void process(int n , int p, int q, string str){
    int x = 0,s =0,z=p;
    string a,b;
    while(x < n){
        a = "", b = "";
        for(int i = s; i < p+s; i++){
            a += str[i];
        }
        v.push_back(a);
        for(int j = z; j < z+q; j++){
            b += str[j];
        }
        v.push_back(b);
        x += p+q;
        s = x;
        z = s+p;
    }
}
int main() {
    int n,p,q;
    cin >> n >> p >> q;
    string str; cin >> str;
    if(p + q <= n){
        process(n,p,q,str);
        cout << v.size() << endl;
        for(auto s : v)
            cout <<  s << endl;
    }else{
        int m = min(p,q);
        if( (n % m) != 0)
            cout << -1 << endl;
        else{
            process(n,m,m,str);
            cout << v.size() << endl;
            for(auto s : v)
                cout << s << endl;
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

vector<string>v;
void process(int n , int p, int q, string str){
    int x = 0,s =0,z=p;
    string a,b;
    while(x < n){
        a = "", b = "";
        for(int i = s; i < p+s; i++){
            a += str[i];
        }
        v.push_back(a);
        for(int j = z; j < z+q; j++){
            b += str[j];
        }
        v.push_back(b);
        x += p+q;
        s = x;
        z = s+p;
    }
}
int main(){
    string s;
    int nn,a,b,p=-1,q=-1;
    cin>>nn>>a>>b;
    cin>>s;
    for(int i=0;i<=nn;i++){
        int tpp = i, tpq = nn - tpp;
        //trace(tpp,tpq,tpp%a,tpq%b);
        if(tpp%a==0 and tpq%b==0){
            p = tpp;
            q = tpq;
            break;
        }
    }
    if(p == -1 and q == -1) cout<<-1<<endl;
    else{
        int n = p/a, m = q/b;
        //trace(n,m);
        cout<<n+m<<endl;
        for(int i=0;i<n;i++)    cout<<s.substr(i*a,a)<<endl;
        for(int i=0;i<m;i++) cout<<s.substr(i*b+n*a,b)<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int n,p,q;
  cin>>n>>p>>q;
  string s;
  cin>>s;
  if(n%p==0)
  { cout<<n/p<<endl;
   int c=0;
     for(int i=0;i<n;i++)
     {
         cout<<s[i];
         c++;
         if(c==p){
          cout<<"\n";
         c=0;

         }
     }
  }
  else if(n%q==0)
  {
     cout<<n/q<<endl;
   int c=0;
     for(int i=0;i<n;i++)
     {
         cout<<s[i];
         c++;
         if(c==q){
          cout<<"\n";

             c=0;
         }
     }
  }
  else
  {int g=n,co=0;
     while(1)
     { co++;
         g=g-p;
         if(g%q==0&&g>=q)
         {
             cout<<co+g/q<<endl;
             int i,c=0;
             for(i=0;i<=co*p;i++)
             {
                 cout<<s[i];
                 c++;
                 if(c==p){
                  cout<<"\n";
                 c=0;

                 }
             }c=0;
             for(;i<n;i++)
             {c++;
                 if(c==q){
                  cout<<"\n";
                 c=0;

                 }
                 cout<<s[i];

             }

             break;
         }
         if(g<0)
          {
              cout<<-1;
              break;
          }
     }
  }
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int n,p,q;
  cin>>n>>p>>q;
  string s;
  cin>>s;
  if(n%p==0)
  { cout<<n/p<<endl;
   int c=0;
     for(int i=0;i<n;i++)
     {
         cout<<s[i];
         c++;
         if(c==p){
          cout<<"\n";
         c=0;

         }
     }
  }
  else if(n%q==0)
  {
     cout<<n/q<<endl;
   int c=0;
     for(int i=0;i<n;i++)
     {
         cout<<s[i];
         c++;
         if(c==q){
          cout<<"\n";

             c=0;
         }
     }
  }
  else
  {int g=n,co=0;
     while(1)
     { co++;
         g=g-p;
         if(g%q==0)
         {
             cout<<co+g/q<<endl;
             int i,c=0;
             for(i=0;i<=co*p;i++)
             {
                 cout<<s[i];
                 c++;
                 if(c==p){
                  cout<<"\n";
                 c=0;

                 }
             }c=0;
             for(;i<n;i++)
             {
                 cout<<s[i];
                 c++;
                 if(c==q){
                  cout<<"\n";
                 c=0;

                 }
             }

             break;
         }
         if(g<0)
          {
              cout<<-1;
              break;
          }
     }
  }
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int n,p,q;
  cin>>n>>p>>q;
  string s;
  cin>>s;
  if(n%p==0)
  { cout<<n/p<<endl;
   int c=0;
     for(int i=0;i<n;i++)
     {
         cout<<s[i];
         c++;
         if(c==p){
          cout<<"\n";
         c=0;

         }
     }
  }
  else if(n%q==0)
  {
     cout<<n/q<<endl;
   int c=0;
     for(int i=0;i<n;i++)
     {
         cout<<s[i];
         c++;
         if(c==q){
          cout<<"\n";

             c=0;
         }
     }
  }
  else
  {int g=n,co=0;
     while(1)
     { co++;
         g=g-p;
         if(g%q==0)
         {
             cout<<co+g/q<<endl;
             int i,c=0;
             for(i=0;i<=co*p;i++)
             {
                 cout<<s[i];
                 c++;
                 if(c==p){
                  cout<<"\n";
                 c=0;

                 }
             }c=0;
             for(;i<n;i++)
             {c++;
                 if(c==q){
                  cout<<"\n";
                 c=0;

                 }
                 cout<<s[i];

             }

             break;
         }
         if(g<0)
          {
              cout<<-1;
              break;
          }
     }
  }
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int n,p,q;
  cin>>n>>p>>q;
  string s;
  cin>>s;
  if(n%p==0)
  { cout<<n/p<<endl;
   int c=0;
     for(int i=0;i<n;i++)
     {
         cout<<s[i];
         c++;
         if(c==p){
          cout<<"\n";
         c=0;

         }
     }
  }
  else if(n%q==0)
  {
     cout<<n/q<<endl;
   int c=0;
     for(int i=0;i<n;i++)
     {
         cout<<s[i];
         c++;
         if(c==q)
          cout<<"\n";
     }
  }
  else
  {int g=n,co=0;
     while(1)
     { co++;
         g=g-p;
         if(g%q==0)
         {
             cout<<co+g/q<<endl;
             int i,c=0;
             for(i=0;i<=co*p;i++)
             {
                 cout<<s[i];
                 c++;
                 if(c==p){
                  cout<<"\n";
                 c=0;

                 }
             }c=0;
             for(;i<n;i++)
             {
                 cout<<s[i];
                 c++;
                 if(c==q){
                  cout<<"\n";
                 c=0;

                 }
             }

             break;
         }
         if(g<0)
          {
              cout<<-1;
              break;
          }
     }
  }
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ff                  first
#define ss                  second
#define int                 long long
#define pb                  push_back
#define mp                  make_pair
#define pii                 pair<int,int>
#define vi                  vector<int>
#define vvi				    vector< vi >
#define vpii                vector< pair<int,int> >
#define mii                 map<int,int>
#define pqb                 priority_queue<int>
#define pqs                 priority_queue<int,vi,greater<int> >
#define loop(i,a,b)		    for(int i=a;i<b;i++)
#define LOOP(i,a,b)		    for(int i=a;i<=b;i++)
#define looprev(i,a,b)		for(int i=a;i>=b;i--)
#define rloop(it,c)         for(auto& it : c)
#define sz(a)			    a.size()
#define all(c) 			    c.begin(),c.end()
#define tr(c,i) 		    for(auto i = c.begin(); i != c.end(); i++)
#define present(c,x) 	    (c.find(x) != c.end())
#define cpresent(c,x) 	    (find(all(c),x) != c.end())
#define spresent(s,x)       (s.find(x) != s.npos)           //use 'x' while passing to parameters  ||  we can also use cpresent(c,x)
#define setbits(x)          __builtin_popcountll(x)
#define zrobits(x)          __builtin_ctzll(x)
#define SETINT(a,x)         memset(a, x, sizeof(a))
#define SETCHAR(str,x)      memset(str, x, sizeof(str)      //use 'x' while passing to parameters
#define mod                 1000000007
#define inf                 1e18
#define ps(x,y)             fixed<<setprecision(y)<<x
#define w(x)                int x; cin>>x; while(x--)
mt19937                     rng(chrono::steady_clock::now().time_since_epoch().count());

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

int raise(int a,int n,int m = mod)
{
    if(n == 0)return 1;
    if(n == 1)return a;
    int x = 1;
    x *= raise(a,n/2,m);
    x %= m;
    x *= x;
    x %= m;
    if(n%2)x*= a;
    x %= m;
    return x;
}

int floor1(int n,int k)
{
    if(n%k == 0 || n >= 0)return n/k;
    return (n/k)-1;
}

int ceil1(int n,int k)
{
    return floor1(n+k-1,k);
}

void Gur27()
{
    ios::sync_with_stdio(0); cin.tie(0);

}

int32_t main()
{
    Gur27();
    int n,p,q;
    cin>>n>> p>> q;
    string s;
    cin>>s;
    if(!(n%p))
    {
        cout<<n<<'\n';
        for(int i=0;i<n;i+=p)
            cout<<s.substr(i,p)<<'\n';
    }
    else if(!(n%q))
    {
        cout<<n<<'\n';
        for(int i=0;i<n;i+=q)
            cout<<s.substr(i,q)<<'\n';
    }
    else if(n!=(p+q))
        cout<<-1;
    else
    {
        cout<<2<<'\n';
        cout<<s.substr(0,p)<<'\n';
        cout<<s.substr(p,q)<<'\n';
    }
    return 0;

}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ff                  first
#define ss                  second
#define int                 long long
#define pb                  push_back
#define mp                  make_pair
#define pii                 pair<int,int>
#define vi                  vector<int>
#define vvi				    vector< vi >
#define vpii                vector< pair<int,int> >
#define mii                 map<int,int>
#define pqb                 priority_queue<int>
#define pqs                 priority_queue<int,vi,greater<int> >
#define loop(i,a,b)		    for(int i=a;i<b;i++)
#define LOOP(i,a,b)		    for(int i=a;i<=b;i++)
#define looprev(i,a,b)		for(int i=a;i>=b;i--)
#define rloop(it,c)         for(auto& it : c)
#define sz(a)			    a.size()
#define all(c) 			    c.begin(),c.end()
#define tr(c,i) 		    for(auto i = c.begin(); i != c.end(); i++)
#define present(c,x) 	    (c.find(x) != c.end())
#define cpresent(c,x) 	    (find(all(c),x) != c.end())
#define spresent(s,x)       (s.find(x) != s.npos)           //use 'x' while passing to parameters  ||  we can also use cpresent(c,x)
#define setbits(x)          __builtin_popcountll(x)
#define zrobits(x)          __builtin_ctzll(x)
#define SETINT(a,x)         memset(a, x, sizeof(a))
#define SETCHAR(str,x)      memset(str, x, sizeof(str)      //use 'x' while passing to parameters
#define mod                 1000000007
#define inf                 1e18
#define ps(x,y)             fixed<<setprecision(y)<<x
#define w(x)                int x; cin>>x; while(x--)
mt19937                     rng(chrono::steady_clock::now().time_since_epoch().count());

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

int raise(int a,int n,int m = mod)
{
    if(n == 0)return 1;
    if(n == 1)return a;
    int x = 1;
    x *= raise(a,n/2,m);
    x %= m;
    x *= x;
    x %= m;
    if(n%2)x*= a;
    x %= m;
    return x;
}

int floor1(int n,int k)
{
    if(n%k == 0 || n >= 0)return n/k;
    return (n/k)-1;
}

int ceil1(int n,int k)
{
    return floor1(n+k-1,k);
}

void Gur27()
{
    ios::sync_with_stdio(0); cin.tie(0);

}

int32_t main()
{
    Gur27();
    int n,p,q;
    cin>>n>> p>> q;
    string s;
    cin>>s;
    if(!(n%p))
    {
        cout<<n/p<<'\n';
        for(int i=0;i<n;i+=p)
            cout<<s.substr(i,p)<<'\n';
    }
    else if(!(n%q))
    {
        cout<<n/q<<'\n';
        for(int i=0;i<n;i+=q)
            cout<<s.substr(i,q)<<'\n';
    }
    else if(n!=(p+q))
        cout<<-1;
    else
    {
        cout<<2<<'\n';
        cout<<s.substr(0,p)<<'\n';
        cout<<s.substr(p,q)<<'\n';
    }
    return 0;

}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ff                  first
#define ss                  second
#define int                 long long
#define pb                  push_back
#define mp                  make_pair
#define pii                 pair<int,int>
#define vi                  vector<int>
#define vvi				    vector< vi >
#define vpii                vector< pair<int,int> >
#define mii                 map<int,int>
#define pqb                 priority_queue<int>
#define pqs                 priority_queue<int,vi,greater<int> >
#define loop(i,a,b)		    for(int i=a;i<b;i++)
#define LOOP(i,a,b)		    for(int i=a;i<=b;i++)
#define looprev(i,a,b)		for(int i=a;i>=b;i--)
#define rloop(it,c)         for(auto& it : c)
#define sz(a)			    a.size()
#define all(c) 			    c.begin(),c.end()
#define tr(c,i) 		    for(auto i = c.begin(); i != c.end(); i++)
#define present(c,x) 	    (c.find(x) != c.end())
#define cpresent(c,x) 	    (find(all(c),x) != c.end())
#define spresent(s,x)       (s.find(x) != s.npos)           //use 'x' while passing to parameters  ||  we can also use cpresent(c,x)
#define setbits(x)          __builtin_popcountll(x)
#define zrobits(x)          __builtin_ctzll(x)
#define SETINT(a,x)         memset(a, x, sizeof(a))
#define SETCHAR(str,x)      memset(str, x, sizeof(str)      //use 'x' while passing to parameters
#define mod                 1000000007
#define inf                 1e18
#define ps(x,y)             fixed<<setprecision(y)<<x
#define w(x)                int x; cin>>x; while(x--)
mt19937                     rng(chrono::steady_clock::now().time_since_epoch().count());

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

int raise(int a,int n,int m = mod)
{
    if(n == 0)return 1;
    if(n == 1)return a;
    int x = 1;
    x *= raise(a,n/2,m);
    x %= m;
    x *= x;
    x %= m;
    if(n%2)x*= a;
    x %= m;
    return x;
}

int floor1(int n,int k)
{
    if(n%k == 0 || n >= 0)return n/k;
    return (n/k)-1;
}

int ceil1(int n,int k)
{
    return floor1(n+k-1,k);
}

void Gur27()
{
    ios::sync_with_stdio(0); cin.tie(0);

}

int32_t main()
{
    Gur27();
    int n,p,q;
    cin>>n>> p>> q;
    string s;
    cin>>s;
    for(int i = 0; i <= n/p; ++i){
    int d = (n-i*p);
    if(d%q) continue;
    int j = d/q;
    cout << i+j << endl;
    for(int k = 0; k < p*i; k+=p){
      cout << s.substr(k,p) << "\n";
    }
    for(int k = 0; k < q*j; k+=q){
      cout << s.substr(i*p+k,q) << "\n";
    }
    return 0;
  }
  cout << -1 << endl;
}


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

typedef long long ll;
typedef unsigned int ui;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef pair<int, int> ii;
typedef vector<ii> vii;
const int INF = int (1e9) + int (1e5);
const ll INFL = ll(2e18) + ll(1e10);
const ui MOD = 1E9 + 7;
const double EPS = 1e-9;
#define FOR(i,n) for (long long i=0;i<(n);++i)
#define FOR2(i,a,b) for (long long i=(a);i<(b);++i)
#define ROF(i,x) for(long long i = (x) ; i >= 0 ; --i)
#define ROF2(i,x,y) for(long long i = (x) ; i >= (y) ; --i)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define ALL(a) (a).begin(),(a).end()
#define ODD(x) (((x)&1)==0?(0):(1))
#define FAST ios_base::sync_with_stdio(false); cin.tie(0)

//template<class T,class U>
//ostream &operator<<(ostream &os,const pair<T,U> &x) {
//    return os<<"("<<x.first<<","<<x.second<<")";
//}
//
//template<class T>
//ostream &operator<<(ostream &os,const vector<T> &x) {
//    os << '[';
//    if ( !x.empty() ) {
//        std::copy (x.begin(), x.end(), std::ostream_iterator<T>(os, ","));
//        os << "\b";
//    }
//    os << "]";
//    return os;
//}
//template<class T>
//ostream &operator<<(ostream &os,const vector<vector<T> > &x) {
//    os << '[';
//    if ( !x.empty() ) {
//        os << x[0];
//        for (int i=1;i<x.size();i++) os << endl << " " << x[i];
//    } else os << "[]";
//    os << "]";
//    return os;
//}
//template<class T>
//bool isPrime(T n){
//	if(n==1)return false;
//	T i = 2;
//	while(i*i<=n){
//	   if(n%i==0)return false;
//	   i+=1;
//	}
//    return true;
//}
//
//__int128 mpow(ll a, ll b, ll m){
//	if(!b)return 1;
//	if(b&1){
//		return ((__int128)a*mpow(a,b-1,m))%m;
//	}else{
//		__int128 v = mpow(a,b/2,m);
//		return (v*v)%m;
//	}
//}
//
//bool isPrime(ll n){
//	//Efficient algo for primality test
//	//upto 1E18 in 1 second.
//	if(n<=2)return false;
//	for(ll i=2;i*i*i<=n;++i){
//		if(n%i==0)return false;
//	}
//	for(int it=0;it<1E5;++it){
//		ll i = rand()%(n-1)+1;
//		if(__gcd(i,n)!=1)return false;
//		if(mpow(i,n-1,n)!=1)return false;
//	}
//	return true;
//}
// bool prime[100005];
// void seive()
// {
// 	memset(prime,true,sizeof(prime));
// 	prime[0]=0;
// 	prime[1]=0;
// 	for(ll p=2;p*p<=100000;p++)
// 	{
// 		if(prime[p]==true)
// 		{
// 			for(ll i=p*2;i<=100000;i+=p)
// 			prime[i]=false;
// 		}
// 	}

// }
//
//template < class T > inline T gcd(T a, T b) { return a ? gcd(b % a, a) : b; }
//template < class T > inline T LCM(T a, T b) { return (a * b) / GCD(a, b); }
//template < class T > inline string toString(T a) {return to_string(a); }  // Convert int to string
//template < class T > inline void toInt(string s, T &x) { stringstream str(s); str >> x;}  // Convert string to int

int main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	FAST;

	int n,p,q; cin>>n>>p>>q;
	string s; cin>>s;
	if(n%p==0 || n%q==0 || n%(p+q)==0){
		if(n%p==0){
			cout<<n/p;
			for(int i=0;i<n;++i){
				if(i%p==0)cout<<'\n';
				cout<<s[i];
			}
		}else if(n%q==0){
			cout<<n/q;
			for(int i=0;i<n;++i){
				if(i%q==0)cout<<'\n';
				cout<<s[i];
			}
		}else{
			cout<<n/(p+q)*2;
			int f = 1;
			int x = p*(n/(p+q)), y = q*(n/(p+q));
			for(int i=0;x>0;++i){
				if(i%p==0){
					cout<<'\n';
				}
				cout<<s[i];
				--x;
			}
			for(int i=p*(n/(p+q));i<n;++i){
				if(y%q==0){
					cout<<'\n';
				}
				cout<<s[i];
				--y;
			}
		}
	}else if((n%p)%q==0){
			cout<<n/p + (n%p)/q;
			int f = 1;
			int x = p*(n/p), y = q*((n%p)/q);
			for(int i=0;x>0;++i){
				if(i%p==0){
					cout<<'\n';
				}
				cout<<s[i];
				--x;
			}
			for(int i=p*(n/(p+q));i<n;++i){
				if(y%q==0){
					cout<<'\n';
				}
				cout<<s[i];
				--y;
			}
	}else if((n%q)%p==0){
		cout<<n/q + (n%q)/p;
			int f = 1;
			int y = p*(n/p), x = q*((n%p)/q);
			for(int i=0;x>0;++i){
				if(i%p==0){
					cout<<'\n';
				}
				cout<<s[i];
				--x;
			}
			for(int i=p*(n/(p+q));i<n;++i){
				if(y%q==0){
					cout<<'\n';
				}
				cout<<s[i];
				--y;
			}
	}else{
		cout<<-1<<'\n';
	}

	return 0;
}


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

typedef long long ll;
typedef unsigned int ui;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef pair<int, int> ii;
typedef vector<ii> vii;
const int INF = int (1e9) + int (1e5);
const ll INFL = ll(2e18) + ll(1e10);
const ui MOD = 1E9 + 7;
const double EPS = 1e-9;
#define FOR(i,n) for (long long i=0;i<(n);++i)
#define FOR2(i,a,b) for (long long i=(a);i<(b);++i)
#define ROF(i,x) for(long long i = (x) ; i >= 0 ; --i)
#define ROF2(i,x,y) for(long long i = (x) ; i >= (y) ; --i)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define ALL(a) (a).begin(),(a).end()
#define ODD(x) (((x)&1)==0?(0):(1))
#define FAST ios_base::sync_with_stdio(false); cin.tie(0)

//template<class T,class U>
//ostream &operator<<(ostream &os,const pair<T,U> &x) {
//    return os<<"("<<x.first<<","<<x.second<<")";
//}
//
//template<class T>
//ostream &operator<<(ostream &os,const vector<T> &x) {
//    os << '[';
//    if ( !x.empty() ) {
//        std::copy (x.begin(), x.end(), std::ostream_iterator<T>(os, ","));
//        os << "\b";
//    }
//    os << "]";
//    return os;
//}
//template<class T>
//ostream &operator<<(ostream &os,const vector<vector<T> > &x) {
//    os << '[';
//    if ( !x.empty() ) {
//        os << x[0];
//        for (int i=1;i<x.size();i++) os << endl << " " << x[i];
//    } else os << "[]";
//    os << "]";
//    return os;
//}
//template<class T>
//bool isPrime(T n){
//	if(n==1)return false;
//	T i = 2;
//	while(i*i<=n){
//	   if(n%i==0)return false;
//	   i+=1;
//	}
//    return true;
//}
//
//__int128 mpow(ll a, ll b, ll m){
//	if(!b)return 1;
//	if(b&1){
//		return ((__int128)a*mpow(a,b-1,m))%m;
//	}else{
//		__int128 v = mpow(a,b/2,m);
//		return (v*v)%m;
//	}
//}
//
//bool isPrime(ll n){
//	//Efficient algo for primality test
//	//upto 1E18 in 1 second.
//	if(n<=2)return false;
//	for(ll i=2;i*i*i<=n;++i){
//		if(n%i==0)return false;
//	}
//	for(int it=0;it<1E5;++it){
//		ll i = rand()%(n-1)+1;
//		if(__gcd(i,n)!=1)return false;
//		if(mpow(i,n-1,n)!=1)return false;
//	}
//	return true;
//}
// bool prime[100005];
// void seive()
// {
// 	memset(prime,true,sizeof(prime));
// 	prime[0]=0;
// 	prime[1]=0;
// 	for(ll p=2;p*p<=100000;p++)
// 	{
// 		if(prime[p]==true)
// 		{
// 			for(ll i=p*2;i<=100000;i+=p)
// 			prime[i]=false;
// 		}
// 	}

// }
//
//template < class T > inline T gcd(T a, T b) { return a ? gcd(b % a, a) : b; }
//template < class T > inline T LCM(T a, T b) { return (a * b) / GCD(a, b); }
//template < class T > inline string toString(T a) {return to_string(a); }  // Convert int to string
//template < class T > inline void toInt(string s, T &x) { stringstream str(s); str >> x;}  // Convert string to int

int main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	FAST;

	int n,p,q; cin>>n>>p>>q;
	string s; cin>>s;
	if(n%p==0 || n%q==0 || n%(p+q)==0){
		if(n%p==0){
			cout<<n/p;
			for(int i=0;i<n;++i){
				if(i%p==0)cout<<'\n';
				cout<<s[i];
			}
		}else if(n%q==0){
			cout<<n/q;
			for(int i=0;i<n;++i){
				if(i%q==0)cout<<'\n';
				cout<<s[i];
			}
		}else{
			cout<<n/(p+q);
			int f = 1;
			int x = p*(n/(p+q)), y = q*(n/(p+q));
			for(int i=0;x>0;++i){
				if(i%p==0){
					cout<<'\n';
				}
				cout<<s[i];
				--x;
			}
			for(int i=p*(n/(p+q));i<n;++i){
				if(y%q==0){
					cout<<'\n';
				}
				cout<<s[i];
				--y;
			}
		}
	}else{
		cout<<-1<<'\n';
	}

	return 0;
}


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

typedef long long ll;
typedef unsigned int ui;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef pair<int, int> ii;
typedef vector<ii> vii;
const int INF = int (1e9) + int (1e5);
const ll INFL = ll(2e18) + ll(1e10);
const ui MOD = 1E9 + 7;
const double EPS = 1e-9;
#define FOR(i,n) for (long long i=0;i<(n);++i)
#define FOR2(i,a,b) for (long long i=(a);i<(b);++i)
#define ROF(i,x) for(long long i = (x) ; i >= 0 ; --i)
#define ROF2(i,x,y) for(long long i = (x) ; i >= (y) ; --i)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define ALL(a) (a).begin(),(a).end()
#define ODD(x) (((x)&1)==0?(0):(1))
#define FAST ios_base::sync_with_stdio(false); cin.tie(0)

//template<class T,class U>
//ostream &operator<<(ostream &os,const pair<T,U> &x) {
//    return os<<"("<<x.first<<","<<x.second<<")";
//}
//
//template<class T>
//ostream &operator<<(ostream &os,const vector<T> &x) {
//    os << '[';
//    if ( !x.empty() ) {
//        std::copy (x.begin(), x.end(), std::ostream_iterator<T>(os, ","));
//        os << "\b";
//    }
//    os << "]";
//    return os;
//}
//template<class T>
//ostream &operator<<(ostream &os,const vector<vector<T> > &x) {
//    os << '[';
//    if ( !x.empty() ) {
//        os << x[0];
//        for (int i=1;i<x.size();i++) os << endl << " " << x[i];
//    } else os << "[]";
//    os << "]";
//    return os;
//}
//template<class T>
//bool isPrime(T n){
//	if(n==1)return false;
//	T i = 2;
//	while(i*i<=n){
//	   if(n%i==0)return false;
//	   i+=1;
//	}
//    return true;
//}
//
//__int128 mpow(ll a, ll b, ll m){
//	if(!b)return 1;
//	if(b&1){
//		return ((__int128)a*mpow(a,b-1,m))%m;
//	}else{
//		__int128 v = mpow(a,b/2,m);
//		return (v*v)%m;
//	}
//}
//
//bool isPrime(ll n){
//	//Efficient algo for primality test
//	//upto 1E18 in 1 second.
//	if(n<=2)return false;
//	for(ll i=2;i*i*i<=n;++i){
//		if(n%i==0)return false;
//	}
//	for(int it=0;it<1E5;++it){
//		ll i = rand()%(n-1)+1;
//		if(__gcd(i,n)!=1)return false;
//		if(mpow(i,n-1,n)!=1)return false;
//	}
//	return true;
//}
// bool prime[100005];
// void seive()
// {
// 	memset(prime,true,sizeof(prime));
// 	prime[0]=0;
// 	prime[1]=0;
// 	for(ll p=2;p*p<=100000;p++)
// 	{
// 		if(prime[p]==true)
// 		{
// 			for(ll i=p*2;i<=100000;i+=p)
// 			prime[i]=false;
// 		}
// 	}

// }
//
//template < class T > inline T gcd(T a, T b) { return a ? gcd(b % a, a) : b; }
//template < class T > inline T LCM(T a, T b) { return (a * b) / GCD(a, b); }
//template < class T > inline string toString(T a) {return to_string(a); }  // Convert int to string
//template < class T > inline void toInt(string s, T &x) { stringstream str(s); str >> x;}  // Convert string to int

int main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	FAST;

	int n,p,q; cin>>n>>p>>q;
	string s; cin>>s;
	if(n%p==0 || n%q==0 || n%(p+q)==0){
		if(n%p==0){
			cout<<n/p;
			for(int i=0;i<n;++i){
				if(i%p==0)cout<<'\n';
				cout<<s[i];
			}
		}else if(n%q==0){
			cout<<n/q;
			for(int i=0;i<n;++i){
				if(i%q==0)cout<<'\n';
				cout<<s[i];
			}
		}else{
			cout<<n/(p+q)*2;
			int f = 1;
			int x = p*(n/(p+q)), y = q*(n/(p+q));
			for(int i=0;x>0;++i){
				if(i%p==0){
					cout<<'\n';
				}
				cout<<s[i];
				--x;
			}
			for(int i=p*(n/(p+q));i<n;++i){
				if(y%q==0){
					cout<<'\n';
				}
				cout<<s[i];
				--y;
			}
		}
	}else{
		cout<<-1<<'\n';
	}

	return 0;
}


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

typedef long long ll;
typedef unsigned int ui;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef pair<int, int> ii;
typedef vector<ii> vii;
const int INF = int (1e9) + int (1e5);
const ll INFL = ll(2e18) + ll(1e10);
const ui MOD = 1E9 + 7;
const double EPS = 1e-9;
#define FOR(i,n) for (long long i=0;i<(n);++i)
#define FOR2(i,a,b) for (long long i=(a);i<(b);++i)
#define ROF(i,x) for(long long i = (x) ; i >= 0 ; --i)
#define ROF2(i,x,y) for(long long i = (x) ; i >= (y) ; --i)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define ALL(a) (a).begin(),(a).end()
#define ODD(x) (((x)&1)==0?(0):(1))
#define FAST ios_base::sync_with_stdio(false); cin.tie(0)

//template<class T,class U>
//ostream &operator<<(ostream &os,const pair<T,U> &x) {
//    return os<<"("<<x.first<<","<<x.second<<")";
//}
//
//template<class T>
//ostream &operator<<(ostream &os,const vector<T> &x) {
//    os << '[';
//    if ( !x.empty() ) {
//        std::copy (x.begin(), x.end(), std::ostream_iterator<T>(os, ","));
//        os << "\b";
//    }
//    os << "]";
//    return os;
//}
//template<class T>
//ostream &operator<<(ostream &os,const vector<vector<T> > &x) {
//    os << '[';
//    if ( !x.empty() ) {
//        os << x[0];
//        for (int i=1;i<x.size();i++) os << endl << " " << x[i];
//    } else os << "[]";
//    os << "]";
//    return os;
//}
//template<class T>
//bool isPrime(T n){
//	if(n==1)return false;
//	T i = 2;
//	while(i*i<=n){
//	   if(n%i==0)return false;
//	   i+=1;
//	}
//    return true;
//}
//
//__int128 mpow(ll a, ll b, ll m){
//	if(!b)return 1;
//	if(b&1){
//		return ((__int128)a*mpow(a,b-1,m))%m;
//	}else{
//		__int128 v = mpow(a,b/2,m);
//		return (v*v)%m;
//	}
//}
//
//bool isPrime(ll n){
//	//Efficient algo for primality test
//	//upto 1E18 in 1 second.
//	if(n<=2)return false;
//	for(ll i=2;i*i*i<=n;++i){
//		if(n%i==0)return false;
//	}
//	for(int it=0;it<1E5;++it){
//		ll i = rand()%(n-1)+1;
//		if(__gcd(i,n)!=1)return false;
//		if(mpow(i,n-1,n)!=1)return false;
//	}
//	return true;
//}
// bool prime[100005];
// void seive()
// {
// 	memset(prime,true,sizeof(prime));
// 	prime[0]=0;
// 	prime[1]=0;
// 	for(ll p=2;p*p<=100000;p++)
// 	{
// 		if(prime[p]==true)
// 		{
// 			for(ll i=p*2;i<=100000;i+=p)
// 			prime[i]=false;
// 		}
// 	}

// }
//
//template < class T > inline T gcd(T a, T b) { return a ? gcd(b % a, a) : b; }
//template < class T > inline T LCM(T a, T b) { return (a * b) / GCD(a, b); }
//template < class T > inline string toString(T a) {return to_string(a); }  // Convert int to string
//template < class T > inline void toInt(string s, T &x) { stringstream str(s); str >> x;}  // Convert string to int

int main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	FAST;

	int n,p,q; cin>>n>>p>>q;

	string s; cin>>s;

	int a = -1, b = -1;
	bool f = false;
	for(int i=0;i<=100;++i){
		for(int j=0;j<=100;++j){
			if(p*i + q*j == n){
				a = i; b = j; f= true; break;
			}
		}
		if(f)break;
	}

	if(a==-1 && b==-1){
		cout<<-1;
	}else{
		cout<<a+b<<'\n';
		int x = 0;
		int i;
		for(i=0;i<n && x<a;++i){
			cout<<s[i];
			if((i+1)%p==0){
				cout<<'\n'; ++x;
			}
		}
		int y = 0,c=0;
		int j = (a==-1)?0:a*p;
		for(;j<n && y<b;++j){
			cout<<s[j];
			++c;
			if(c%q==0){
				cout<<'\n'; c = 0; ++y;
			}
		}
	}

}


#include <bits/stdc++.h>
#define st first
#define nd second

using namespace std;

const int mod = 1000000009;

typedef pair<int,int> ii;

map<ii, int> mapa;
ii arr[100005];
int indeg[100005], outdeg[100005];
bool gone[100005];

bool ok(int x) {
  bool yes = true;
  for (int dx = -1; dx <= 1; ++dx) {
    int nx = arr[x].st + dx;
    int ny = arr[x].nd + 1;
    map<ii,int>::iterator it = mapa.find(ii(nx,ny));
    if (it != mapa.end()) {
      yes &= outdeg[it->nd] > 1 || gone[it->nd] || arr[it->nd].nd == 0;
    }
  }
  return yes;
}

int main() {
  int n; scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%d %d", &arr[i].st, &arr[i].nd);
    mapa[ii(arr[i].st,arr[i].nd)] = i;
  }
  for (int i = 0; i < n; ++i) {
    for (int dx = -1; dx <= 1; ++dx) {
      int nx = arr[i].st + dx;
      int ny = arr[i].nd - 1;
      map<ii,int>::iterator it = mapa.find(ii(nx,ny));
      if (it != mapa.end()) {
        ++indeg[it->nd];
        ++outdeg[i];
      }
    }
  }
  set<int> s;
  for (int i = 0; i < n; ++i) {
    if (ok(i)) {
      s.insert(i);
    }
  }
  int turn = 0;
  long long ans = 0;
  for (int i = 0; i < n; ++i) {
    int v;
    if (turn) v = *s.begin();
    else v = *s.rbegin();
    s.erase(v);
    gone[v] = true;
    for (int dx = -1; dx <= 1; ++dx) {
      int nx = arr[v].st + dx;
      int ny = arr[v].nd - 1;
      map<ii,int>::iterator it = mapa.find(ii(nx,ny));
      if (it != mapa.end()) {
        --outdeg[v];
        --indeg[it->nd];
      }
    }
    ans = ((ans * n)%mod + v)%mod;
    turn = 1 - turn;
    for (int dx = -1; dx <= 1; ++dx) {
      int nx = arr[v].st + dx;
      int ny = arr[v].nd - 1;
      map<ii,int>::iterator it = mapa.find(ii(nx,ny));
      if (it != mapa.end()) {
        if (ok(it->nd)) s.insert(it->nd);
      }
    }
  }
  cout << ans << "\n";
  return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <iomanip>
#include <algorithm>
#include <climits>
#include <string>
#include <stack>
#include <queue>
#include <cmath>

using namespace std;

#define TRACE(x) cout << #x << ": " << x << endl;
#define MAX 1
#define mod 1000000009

typedef long long llong;
typedef unsigned long long ullong;

struct point{
    int x, y;
    int id;

    bool operator<(const point &b) const{
        if (y == b.y)
            return x < b.x;
        return y < b.y;
    }
};

set< point > points_coord;
vector< point > points;
set< int > available;

bool is_available(point &p){
    point aux = p;
    aux.y++;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        aux.x--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        aux.x += 2;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    aux = p;
    aux.y++;
    aux.x++;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        aux.x++;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    aux = p;
    aux.y++;
    aux.x--;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        aux.x--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    return true;
}

llong to_number(int n, int vid, llong ans){
    ans = (ans * n) % mod;
    return (ans + vid) % mod;
}

int main(){
    int n;
    cin >> n;

    for (int i = 0; i < n; i++){
        point p;
        cin >> p.x >> p.y;
        p.id = i;
        points.push_back(p);
        points_coord.insert(p);
    }

    for (int i = 0; i < n; i++){
        if (is_available(points[i])){
            available.insert(i);
            //TRACE(i);
        }
    }

    bool play = false;

    llong ans = 0;

    while (!available.empty()){
        set< int >::iterator id = (!play ? available.end() : available.begin());
        if (!play) id--;

        int vid = *id;
        available.erase(id);
        points_coord.erase(points[vid]);
        //TRACE(vid);

        ans = to_number(n, vid, ans);

        point aux = points[vid];

        for (int i = 0; i < 2; i++){
            aux.x--;

            if (!is_available(aux)){
                set< point >::iterator x = points_coord.find(aux);
                if (x != points_coord.end()){
                    //cout << "no available: " << x->id << endl;
                    available.erase(x->id);
                }
            }
        }

        aux = points[vid];

        for (int i = 0; i < 2; i++){
            aux.x++;

            if (!is_available(aux)){
                set< point >::iterator x = points_coord.find(aux);
                if (x != points_coord.end()){
                    //cout << "no available: " << x->id << endl;
                    available.erase(x->id);
                }
            }
        }

        aux = points[vid];

        aux.y--;
        aux.x++;

        for (int i = 0; i < 3; i++){

            if (is_available(aux)){
                set< point >::iterator x = points_coord.find(aux);
                if (x != points_coord.end()){
                    //cout << "available: " << x->id << endl;
                    available.insert(x->id);
                }
            }
            aux.x--;

        }

        play = !play;
    }

    cout << ans << endl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <iomanip>
#include <algorithm>
#include <climits>
#include <string>
#include <stack>
#include <queue>
#include <cmath>

using namespace std;

#define TRACE(x) cout << #x << ": " << x << endl;
#define MAX 1
#define mod 1000000009

typedef long long llong;
typedef unsigned long long ullong;

struct point{
    int x, y;
    int id;

    bool operator<(const point &b) const{
        if (y == b.y)
            return x < b.x;
        return y < b.y;
    }
};

set< point > points_coord;
vector< point > points;
set< int > available;

bool is_available(point &p){
    point aux = p;
    aux.y++;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        aux.x--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        aux.x += 2;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    aux = p;
    aux.y++;
    aux.x++;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    aux = p;
    aux.y++;
    aux.x--;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    return true;
}

llong to_number(int n, int vid, llong ans){
    ans = (ans * n) % mod;
    return (ans + vid) % mod;
}

int main(){
    int n;
    cin >> n;

    for (int i = 0; i < n; i++){
        point p;
        cin >> p.x >> p.y;
        p.id = i;
        points.push_back(p);
        points_coord.insert(p);
    }

    for (int i = 0; i < n; i++){
        if (is_available(points[i])){
            available.insert(i);
            //TRACE(i);
        }
    }

    bool play = false;

    llong ans = 0;

    while (!available.empty()){
        set< int >::iterator id = (!play ? available.end() : available.begin());
        if (!play) id--;

        int vid = *id;
        available.erase(id);
        points_coord.erase(points[vid]);
        //TRACE(vid);

        ans = to_number(n, vid, ans);

        point aux = points[vid];
        aux.x--;

        if (!is_available(aux)){
            set< point >::iterator x = points_coord.find(aux);
            if (x != points_coord.end()){
                //cout << "no available: " << x->id << endl;
                available.erase(x->id);
                points_coord.erase(x);
            }
        }

        aux.x += 2;

        if (!is_available(aux)){
            set< point >::iterator x = points_coord.find(aux);
            if (x != points_coord.end()){
                //cout << "no available: " << x->id << endl;
                available.erase(x->id);
                points_coord.erase(x);
            }
        }

        aux.y--;

        for (int i = 0; i < 3; i++){

            if (is_available(aux)){
                set< point >::iterator x = points_coord.find(aux);
                if (x != points_coord.end()){
                    //cout << "available: " << x->id << endl;
                    available.insert(x->id);
                }
            }
            aux.x--;

        }

        play = !play;
    }

    cout << ans << endl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <iomanip>
#include <algorithm>
#include <climits>
#include <string>
#include <stack>
#include <queue>
#include <cmath>

using namespace std;

#define TRACE(x) cout << #x << ": " << x << endl;
#define MAX 1
#define mod 1000000009

typedef long long llong;
typedef unsigned long long ullong;

struct point{
    int x, y;
    int id;

    bool operator<(const point &b) const{
        if (y == b.y)
            return x < b.x;
        return y < b.y;
    }
};

set< point > points_coord;
vector< point > points;
set< int > available;

bool is_available(point &p){
    point aux = p;
    aux.y++;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        aux.x--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        aux.x += 2;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    aux = p;
    aux.y++;
    aux.x++;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    aux = p;
    aux.y++;
    aux.x--;
    if (points_coord.find(aux) != points_coord.end()){
        aux.y--;
        if (points_coord.find(aux) != points_coord.end()) return true;
        return false;
    }

    return true;
}

llong to_number(int n, int vid, llong ans){
    ans = (ans * n) % mod;
    return (ans + vid) % mod;
}

int main(){
    int n;
    cin >> n;

    for (int i = 0; i < n; i++){
        point p;
        cin >> p.x >> p.y;
        p.id = i;
        points.push_back(p);
        points_coord.insert(p);
    }

    for (int i = 0; i < n; i++){
        if (is_available(points[i])){
            available.insert(i);
        }
    }

    bool play = false;

    llong ans = 0;

    while (!available.empty()){
        set< int >::iterator id = (!play ? available.end() : available.begin());
        if (!play) id--;

        int vid = *id;
        available.erase(id);
        points_coord.erase(points[vid]);

        ans = to_number(n, vid, ans);

        point aux = points[vid];
        aux.x--;

        if (!is_available(aux)){
            set< point >::iterator x = points_coord.find(aux);
            if (x != points_coord.end()){
                available.erase(x->id);
                points_coord.erase(x);
            }
        }

        aux.x += 2;

        if (!is_available(aux)){
            set< point >::iterator x = points_coord.find(aux);
            if (x != points_coord.end()){
                available.erase(x->id);
                points_coord.erase(x);
            }
        }

        aux.y--;

        for (int i = 0; i < 3; i++){

            if (is_available(aux)){
                set< point >::iterator x = points_coord.find(aux);
                if (x != points_coord.end()){
                    available.insert(x->id);
                }
            }
            aux.x--;

        }
    }

    cout << ans << endl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <iomanip>
#include <algorithm>
#include <climits>
#include <string>
#include <stack>
#include <queue>
#include <cmath>

using namespace std;

#define TRACE(x) cout << #x << ": " << x << endl;
#define MAX 1
#define mod 1000000009

typedef long long llong;
typedef unsigned long long ullong;

struct point{
    int x, y;
    int id;

    bool operator<(const point &b) const{
        if (y == b.y)
            return x < b.x;
        return y < b.y;
    }
};

set< point > points_coord;
vector< point > points;
set< int > available;

bool is_available(point &p){
    point aux = p;
    aux.y++;
    if (points_coord.find(aux) != points_coord.end()){
        bool ok = false;
        aux.y--;
        aux.x--;
        if (points_coord.find(aux) != points_coord.end()) ok = true;
        aux.x += 2;
        if (points_coord.find(aux) != points_coord.end()) ok = true;
        if (!ok) return false;
    }

    aux = p;
    aux.y++;
    aux.x++;
    if (points_coord.find(aux) != points_coord.end()){
        bool ok = false;
        aux.y--;
        if (points_coord.find(aux) != points_coord.end()) ok = true;
        aux.x++;
        if (points_coord.find(aux) != points_coord.end()) ok = true;
        if (!ok) return false;
    }

    aux = p;
    aux.y++;
    aux.x--;
    if (points_coord.find(aux) != points_coord.end()){
        bool ok = false;
        aux.y--;
        if (points_coord.find(aux) != points_coord.end()) ok = true;
        aux.x--;
        if (points_coord.find(aux) != points_coord.end()) ok = true;
        if (!ok) return false;
    }

    return true;
}

llong to_number(int n, int vid, llong ans){
    ans = (ans * n) % mod;
    return (ans + vid) % mod;
}

int main(){
    int n;
    cin >> n;

    for (int i = 0; i < n; i++){
        point p;
        cin >> p.x >> p.y;
        p.id = i;
        points.push_back(p);
        points_coord.insert(p);
    }

    for (int i = 0; i < n; i++){
        if (is_available(points[i])){
            available.insert(i);
            //TRACE(i);
        }
    }

    bool play = false;

    llong ans = 0;

    while (!available.empty()){
        set< int >::iterator id = (!play ? available.end() : available.begin());
        if (!play) id--;

        int vid = *id;
        available.erase(id);
        points_coord.erase(points[vid]);
        //TRACE(vid);

        ans = to_number(n, vid, ans);

        point aux = points[vid];

        for (int i = 0; i < 2; i++){
            aux.x--;

            if (!is_available(aux)){
                set< point >::iterator x = points_coord.find(aux);
                if (x != points_coord.end()){
                    //cout << "no available: " << x->id << endl;
                    available.erase(x->id);
                }
            }
        }

        aux = points[vid];

        for (int i = 0; i < 2; i++){
            aux.x++;

            if (!is_available(aux)){
                set< point >::iterator x = points_coord.find(aux);
                if (x != points_coord.end()){
                    //cout << "no available: " << x->id << endl;
                    available.erase(x->id);
                }
            }
        }

        aux = points[vid];

        aux.y--;
        aux.x++;

        for (int i = 0; i < 3; i++){

            if (is_available(aux)){
                set< point >::iterator x = points_coord.find(aux);
                if (x != points_coord.end()){
                    //cout << "available: " << x->id << endl;
                    available.insert(x->id);
                }
            }
            aux.x--;

        }

        play = !play;
    }

    cout << ans << endl;
    return 0;
}


#pragma region headers/definitions
//Author: Romanov Artem
#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS
#pragma region headers
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
#pragma endregion
using namespace std;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef long long int64;
typedef unsigned long long uint64;
#define EPS 1e-12
#define D_INF HUGE_VAL
#define D_NINF (-HUGE_VAL)
#define T_MAX(T) numeric_limits<T>::max()
#define T_MIN(T) numeric_limits<T>::min()
#define _IT ::iterator
#define _RIT ::reverse_iterator
#define _PT ::pointer
#define m_p make_pair
#pragma endregion
#define IN "input.txt"
//#define OUT "output.txt"

int64 m, mod = 1000000009, ans = 0;
int64 *p;
map< pair< int64, int64 >, pair< int64, uchar > > c;
map< int64, pair< int64, int64 > > s;
vector< int64 > v;

void perecalc(map< pair< int64, int64 >, pair< int64, uchar > >_IT &it)
{
	uchar e = 0x00;
	map< pair< int64, int64 >, pair< int64, uchar > >_IT ar[4];
	ar[0] = c.find(m_p(it->first.first - 2, it->first.second));
	ar[1] = c.find(m_p(it->first.first - 1, it->first.second));
	ar[2] = c.find(m_p(it->first.first + 1, it->first.second));
	ar[3] = c.find(m_p(it->first.first + 2, it->first.second));
	if (ar[0] != c.end() && (ar[0]->second.second & 0x02) >> 1)
		e |= 0x80;
	if (ar[1] != c.end() && (ar[1]->second.second & 0x02) >> 1)
		e |= 0x40;
	if (ar[2] != c.end() && (ar[2]->second.second & 0x02) >> 1)
		e |= 0x20;
	if (ar[3] != c.end() && (ar[3]->second.second & 0x02) >> 1)
		e |= 0x10;
	if (!((it->second.second & 0x80) >> 7 && !((e & 0x80) >> 7 | (e & 0x40) >> 6)) &&
		!((it->second.second & 0x40) >> 6 && !((e & 0x40) >> 6 | (e & 0x20) >> 5)) &&
		!((it->second.second & 0x20) >> 5 && !((e & 0x20) >> 5 | (e & 0x10) >> 4)))
	{
		it->second.second |= 0x01;
		s[it->second.first] = it->first;
	}
	else
	{
		it->second.second &= 0xFE;
		s.erase(it->second.first);
	}
}

void init() {
	cin >> m;
	p = new int64[m];
	p[0] = 1;
	for (int64 i = 0; i < m; i++)
	{
		int64 x, y;
		cin >> x >> y;
		c[m_p(x, y)] = m_p(i, 0x00);
		p[i + 1] = ((int64)p[i] * m) % mod;
	}
	for (map< pair< int64, int64 >, pair< int64, uchar > >_IT it = c.begin(); it != c.end(); ++it)
	{
		uchar e = 0x00;
		if (it->first.second == 0)
			it->second.second |= 0x1C;
		else
		{
			if (c.find(m_p(it->first.first - 1, it->first.second - 1)) != c.end())
				it->second.second |= 0x10;
			if (c.find(m_p(it->first.first, it->first.second - 1)) != c.end())
				it->second.second |= 0x08;
			if (c.find(m_p(it->first.first + 1, it->first.second - 1)) != c.end())
				it->second.second |= 0x04;
		}
		if (c.find(m_p(it->first.first - 1, it->first.second + 1)) != c.end())
			it->second.second |= 0x80;
		if (c.find(m_p(it->first.first, it->first.second + 1)) != c.end())
			it->second.second |= 0x40;
		if (c.find(m_p(it->first.first + 1, it->first.second + 1)) != c.end())
			it->second.second |= 0x20;
		it->second.second |= 0x02;
		if (c.find(m_p(it->first.first - 2, it->first.second)) != c.end())
			e |= 0x80;
		if (c.find(m_p(it->first.first - 1, it->first.second)) != c.end())
			e |= 0x40;
		if (c.find(m_p(it->first.first + 1, it->first.second)) != c.end())
			e |= 0x20;
		if (c.find(m_p(it->first.first + 2, it->first.second)) != c.end())
			e |= 0x10;
		if (!((it->second.second & 0x80) >> 7 && !((e & 0x80) >> 7 | (e & 0x40) >> 6)) &&
			!((it->second.second & 0x40) >> 6 && !((e & 0x40) >> 6 | (e & 0x20) >> 5)) &&
			!((it->second.second & 0x20) >> 5 && !((e & 0x20) >> 5 | (e & 0x10) >> 4)))
		{
			it->second.second |= 0x01;
			s[it->second.first] = it->first;
		}
	}
}

void build() {

}

void update() {

}

void solve() {
	for (int64 i = 0; i < m; i++)
	{
		map< int64, pair< int64, int64 > >_IT it = (i % 2 ? s.begin() : --s.end());
		v.push_back(it->first);
		map< pair< int64, int64 >, pair< int64, uchar > >_IT ft = c.find(it->second);
		map< pair< int64, int64 >, pair< int64, uchar > >_IT ar[10];
		ar[0] = ((ft->second.second & 0x80) >> 7 ? c.find(m_p(ft->first.first - 1, ft->first.second + 1)) : c.end());
		ar[1] = ((ft->second.second & 0x40) >> 6 ? c.find(m_p(ft->first.first, ft->first.second + 1)) : c.end());
		ar[2] = ((ft->second.second & 0x20) >> 5 ? c.find(m_p(ft->first.first + 1, ft->first.second + 1)) : c.end());
		ar[3] = ((ft->second.second & 0x10) >> 4 && ft->first.second != 0 ? c.find(m_p(ft->first.first - 1, ft->first.second - 1)) : c.end());
		ar[4] = ((ft->second.second & 0x08) >> 3 && ft->first.second != 0 ? c.find(m_p(ft->first.first, ft->first.second - 1)) : c.end());
		ar[5] = ((ft->second.second & 0x84) >> 2 && ft->first.second != 0 ? c.find(m_p(ft->first.first + 1, ft->first.second - 1)) : c.end());
		ar[6] = c.find(m_p(ft->first.first - 2, ft->first.second));
		ar[7] = c.find(m_p(ft->first.first - 1, ft->first.second));
		ar[8] = c.find(m_p(ft->first.first + 1, ft->first.second));
		ar[9] = c.find(m_p(ft->first.first + 2, ft->first.second));
		ft->second.second &= 0xFD;
		if (ar[0] != c.end())
			ar[0]->second.second &= 0xFB;
		if (ar[1] != c.end())
			ar[1]->second.second &= 0xF7;
		if (ar[2] != c.end())
			ar[2]->second.second &= 0xEF;
		if (ar[3] != c.end())
			ar[3]->second.second &= 0xDF;
		if (ar[4] != c.end())
			ar[4]->second.second &= 0xBF;
		if (ar[5] != c.end())
			ar[5]->second.second &= 0x7F;
		for (int64 i = 0; i < 10; i++)
		{
			if (ar[i] != c.end())
				perecalc(ar[i]);
		}
		s.erase(it);
		c.erase(ft);
	}
}

void printAns() {
	for (int64 i = 0; i < m; i++)
	{
		ans = (ans + (int64)p[m - 1 - i] * (int64)v[i]) % mod;
	}
	cout << ans << endl;
}

int main() {
#pragma region I/O
	ios_base::sync_with_stdio(false);
#ifdef _DEBUG
	uint TEST_NUM = 0;
	freopen("input.txt", "r", stdin);
#define EOS !cin.eof()
#define P_DEBUG printf("\n           TEST %3d           \n-----////////////////////-----\n\n", ++TEST_NUM)
#else
#define EOS false
#define P_DEBUG
#ifdef IN
	freopen(IN, "r", stdin);
#endif
#ifdef OUT
	freopen(OUT, "w", stdout);
#endif
#endif
	cout.setf(ios::fixed);
	cout.precision(11);
#pragma endregion
	do {
		P_DEBUG;
		init();
		solve();
		printAns();
	} while (EOS);
	return 0;
}


#pragma region headers/definitions
//Author: Romanov Artem
#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS
#pragma region headers
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
#pragma endregion
using namespace std;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef long long int64;
typedef unsigned long long uint64;
#define EPS 1e-12
#define D_INF HUGE_VAL
#define D_NINF (-HUGE_VAL)
#define T_MAX(T) numeric_limits<T>::max()
#define T_MIN(T) numeric_limits<T>::min()
#define _IT ::iterator
#define _RIT ::reverse_iterator
#define _PT ::pointer
#define m_p make_pair
#pragma endregion
//#define IN "input.txt"
//#define OUT "output.txt"

int64 m, mod = 1000000009, ans = 0;
int64 *p;
map< pair< int64, int64 >, pair< int64, uchar > > c;
map< int64, pair< int64, int64 > > s;
vector< int64 > v;

void perecalc(map< pair< int64, int64 >, pair< int64, uchar > >_IT &it)
{
	uchar e = 0x00;
	map< pair< int64, int64 >, pair< int64, uchar > >_IT ar[4];
	ar[0] = c.find(m_p(it->first.first - 2, it->first.second));
	ar[1] = c.find(m_p(it->first.first - 1, it->first.second));
	ar[2] = c.find(m_p(it->first.first + 1, it->first.second));
	ar[3] = c.find(m_p(it->first.first + 2, it->first.second));
	if (ar[0] != c.end() && (ar[0]->second.second & 0x02) >> 1)
		e |= 0x80;
	if (ar[1] != c.end() && (ar[1]->second.second & 0x02) >> 1)
		e |= 0x40;
	if (ar[2] != c.end() && (ar[2]->second.second & 0x02) >> 1)
		e |= 0x20;
	if (ar[3] != c.end() && (ar[3]->second.second & 0x02) >> 1)
		e |= 0x10;
	if (!((it->second.second & 0x80) >> 7 && !((e & 0x80) >> 7 | (e & 0x40) >> 6)) &&
		!((it->second.second & 0x40) >> 6 && !((e & 0x40) >> 6 | (e & 0x20) >> 5)) &&
		!((it->second.second & 0x20) >> 5 && !((e & 0x20) >> 5 | (e & 0x10) >> 4)))
	{
		it->second.second |= 0x01;
		s[it->second.first] = it->first;
	}
	else
	{
		it->second.second &= 0xFE;
		s.erase(it->second.first);
	}
}

void init() {
	cin >> m;
	p = new int64[m];
	p[0] = 1;
	for (int64 i = 0; i < m; i++)
	{
		int64 x, y;
		cin >> x >> y;
		c[m_p(x, y)] = m_p(i, 0x00);
		p[i + 1] = ((int64)p[i] * m) % mod;
	}
	for (map< pair< int64, int64 >, pair< int64, uchar > >_IT it = c.begin(); it != c.end(); ++it)
	{
		uchar e = 0x00;
		if (it->first.second == 0)
			it->second.second |= 0x1C;
		else
		{
			if (c.find(m_p(it->first.first - 1, it->first.second - 1)) != c.end())
				it->second.second |= 0x10;
			if (c.find(m_p(it->first.first, it->first.second - 1)) != c.end())
				it->second.second |= 0x08;
			if (c.find(m_p(it->first.first + 1, it->first.second - 1)) != c.end())
				it->second.second |= 0x04;
		}
		if (c.find(m_p(it->first.first - 1, it->first.second + 1)) != c.end())
			it->second.second |= 0x80;
		if (c.find(m_p(it->first.first, it->first.second + 1)) != c.end())
			it->second.second |= 0x40;
		if (c.find(m_p(it->first.first + 1, it->first.second + 1)) != c.end())
			it->second.second |= 0x20;
		it->second.second |= 0x02;
		if (c.find(m_p(it->first.first - 2, it->first.second)) != c.end())
			e |= 0x80;
		if (c.find(m_p(it->first.first - 1, it->first.second)) != c.end())
			e |= 0x40;
		if (c.find(m_p(it->first.first + 1, it->first.second)) != c.end())
			e |= 0x20;
		if (c.find(m_p(it->first.first + 2, it->first.second)) != c.end())
			e |= 0x10;
		if (!((it->second.second & 0x80) >> 7 && !((e & 0x80) >> 7 | (e & 0x40) >> 6)) &&
			!((it->second.second & 0x40) >> 6 && !((e & 0x40) >> 6 | (e & 0x20) >> 5)) &&
			!((it->second.second & 0x20) >> 5 && !((e & 0x20) >> 5 | (e & 0x10) >> 4)))
		{
			it->second.second |= 0x01;
			s[it->second.first] = it->first;
		}
	}
}

void build() {

}

void update() {

}

void solve() {
	for (int64 i = 0; i < m; i++)
	{
		map< int64, pair< int64, int64 > >_IT it = (i % 2 ? s.begin() : --s.end());
		v.push_back(it->first);
		map< pair< int64, int64 >, pair< int64, uchar > >_IT ft = c.find(it->second);
		map< pair< int64, int64 >, pair< int64, uchar > >_IT ar[10];
		ar[0] = ((ft->second.second & 0x80) >> 7 ? c.find(m_p(ft->first.first - 1, ft->first.second + 1)) : c.end());
		ar[1] = ((ft->second.second & 0x40) >> 6 ? c.find(m_p(ft->first.first, ft->first.second + 1)) : c.end());
		ar[2] = ((ft->second.second & 0x20) >> 5 ? c.find(m_p(ft->first.first + 1, ft->first.second + 1)) : c.end());
		ar[3] = ((ft->second.second & 0x10) >> 4 && ft->first.second != 0 ? c.find(m_p(ft->first.first - 1, ft->first.second - 1)) : c.end());
		ar[4] = ((ft->second.second & 0x08) >> 3 && ft->first.second != 0 ? c.find(m_p(ft->first.first, ft->first.second - 1)) : c.end());
		ar[5] = ((ft->second.second & 0x84) >> 2 && ft->first.second != 0 ? c.find(m_p(ft->first.first + 1, ft->first.second - 1)) : c.end());
		ar[6] = c.find(m_p(ft->first.first - 2, ft->first.second));
		ar[7] = c.find(m_p(ft->first.first - 1, ft->first.second));
		ar[8] = c.find(m_p(ft->first.first + 1, ft->first.second));
		ar[9] = c.find(m_p(ft->first.first + 2, ft->first.second));
		ft->second.second &= 0xFD;
		if (ar[0] != c.end())
			ar[0]->second.second &= 0xFB;
		if (ar[1] != c.end())
			ar[1]->second.second &= 0xF7;
		if (ar[2] != c.end())
			ar[2]->second.second &= 0xEF;
		if (ar[3] != c.end())
			ar[3]->second.second &= 0xDF;
		if (ar[4] != c.end())
			ar[4]->second.second &= 0xBF;
		if (ar[5] != c.end())
			ar[5]->second.second &= 0x7F;
		for (int64 i = 0; i < 10; i++)
		{
			if (ar[i] != c.end())
				perecalc(ar[i]);
		}
		s.erase(it);
		c.erase(ft);
	}
}

void printAns() {
	for (int64 i = 0; i < m; i++)
	{
		ans = (ans + (int64)p[m - 1 - i] * (int64)v[i]) % mod;
	}
	cout << ans << endl;
}

int main() {
#pragma region I/O
	ios_base::sync_with_stdio(false);
#ifdef _DEBUG
	uint TEST_NUM = 0;
	freopen("input.txt", "r", stdin);
#define EOS !cin.eof()
#define P_DEBUG printf("\n           TEST %3d           \n-----////////////////////-----\n\n", ++TEST_NUM)
#else
#define EOS false
#define P_DEBUG
#ifdef IN
	freopen(IN, "r", stdin);
#endif
#ifdef OUT
	freopen(OUT, "w", stdout);
#endif
#endif
	cout.setf(ios::fixed);
	cout.precision(11);
#pragma endregion
	do {
		P_DEBUG;
		init();
		solve();
		printAns();
	} while (EOS);
	return 0;
}


#pragma region headers/definitions
//Author: Romanov Artem
#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS
#pragma region headers
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
#pragma endregion
using namespace std;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef long long int64;
typedef unsigned long long uint64;
#define EPS 1e-12
#define D_INF HUGE_VAL
#define D_NINF (-HUGE_VAL)
#define T_MAX(T) numeric_limits<T>::max()
#define T_MIN(T) numeric_limits<T>::min()
#define _IT ::iterator
#define _RIT ::reverse_iterator
#define _PT ::pointer
#define m_p make_pair
#pragma endregion
//#define IN "input.txt"
//#define OUT "output.txt"

int64 m, mod = 1000000009, ans = 0;
int *p;
map< pair< int, int >, pair< int, uchar > > c;
map< int, pair< int, int > > s;
vector< int > v;

void perecalc(map< pair< int, int >, pair< int, uchar > >_IT &it)
{
	uchar e = 0x00;
	map< pair< int, int >, pair< int, uchar > >_IT ar[4];
	ar[0] = c.find(m_p(it->first.first - 2, it->first.second));
	ar[1] = c.find(m_p(it->first.first - 1, it->first.second));
	ar[2] = c.find(m_p(it->first.first + 1, it->first.second));
	ar[3] = c.find(m_p(it->first.first + 2, it->first.second));
	if (ar[0] != c.end() && (ar[0]->second.second & 0x02) >> 1)
		e |= 0x80;
	if (ar[1] != c.end() && (ar[1]->second.second & 0x02) >> 1)
		e |= 0x40;
	if (ar[2] != c.end() && (ar[2]->second.second & 0x02) >> 1)
		e |= 0x20;
	if (ar[3] != c.end() && (ar[3]->second.second & 0x02) >> 1)
		e |= 0x10;
	if (!((it->second.second & 0x80) >> 7 && !((e & 0x80) >> 7 | (e & 0x40) >> 6)) &&
		!((it->second.second & 0x40) >> 6 && !((e & 0x40) >> 6 | (e & 0x20) >> 5)) &&
		!((it->second.second & 0x20) >> 5 && !((e & 0x20) >> 5 | (e & 0x10) >> 4)))
	{
		it->second.second |= 0x01;
		s[it->second.first] = it->first;
	}
	else
	{
		it->second.second &= 0xFE;
		s.erase(it->second.first);
	}
}

void init() {
	cin >> m;
	p = new int[m];
	p[0] = 1;
	for (int i = 0; i < m; i++)
	{
		int x, y;
		cin >> x >> y;
		c[m_p(x, y)] = m_p(i, 0x00);
		p[i + 1] = ((int64)p[i] * m) % mod;
	}
	for (map< pair< int, int >, pair< int, uchar > >_IT it = c.begin(); it != c.end(); ++it)
	{
		uchar e = 0x00;
		if (it->first.second == 0)
			it->second.second |= 0x1C;
		else
		{
			if (c.find(m_p(it->first.first - 1, it->first.second - 1)) != c.end())
				it->second.second |= 0x10;
			if (c.find(m_p(it->first.first, it->first.second - 1)) != c.end())
				it->second.second |= 0x08;
			if (c.find(m_p(it->first.first + 1, it->first.second - 1)) != c.end())
				it->second.second |= 0x04;
		}
		if (c.find(m_p(it->first.first - 1, it->first.second + 1)) != c.end())
			it->second.second |= 0x80;
		if (c.find(m_p(it->first.first, it->first.second + 1)) != c.end())
			it->second.second |= 0x40;
		if (c.find(m_p(it->first.first + 1, it->first.second + 1)) != c.end())
			it->second.second |= 0x20;
		it->second.second |= 0x02;
		if (c.find(m_p(it->first.first - 2, it->first.second)) != c.end())
			e |= 0x80;
		if (c.find(m_p(it->first.first - 1, it->first.second)) != c.end())
			e |= 0x40;
		if (c.find(m_p(it->first.first + 1, it->first.second)) != c.end())
			e |= 0x20;
		if (c.find(m_p(it->first.first + 2, it->first.second)) != c.end())
			e |= 0x10;
		if (!((it->second.second & 0x80) >> 7 && !((e & 0x80) >> 7 | (e & 0x40) >> 6)) &&
			!((it->second.second & 0x40) >> 6 && !((e & 0x40) >> 6 | (e & 0x20) >> 5)) &&
			!((it->second.second & 0x20) >> 5 && !((e & 0x20) >> 5 | (e & 0x10) >> 4)))
		{
			it->second.second |= 0x01;
			s[it->second.first] = it->first;
		}
	}
}

void build() {

}

void update() {

}

void solve() {
	for (int i = 0; i < m; i++)
	{
		map< int, pair< int, int > >_IT it = (i % 2 ? s.begin() : --s.end());
		v.push_back(it->first);
		map< pair< int, int >, pair< int, uchar > >_IT ft = c.find(it->second);
		map< pair< int, int >, pair< int, uchar > >_IT ar[10];
		ar[0] = ((ft->second.second & 0x80) >> 7 ? c.find(m_p(ft->first.first - 1, ft->first.second + 1)) : c.end());
		ar[1] = ((ft->second.second & 0x40) >> 6 ? c.find(m_p(ft->first.first, ft->first.second + 1)) : c.end());
		ar[2] = ((ft->second.second & 0x20) >> 5 ? c.find(m_p(ft->first.first + 1, ft->first.second + 1)) : c.end());
		ar[3] = ((ft->second.second & 0x10) >> 4 && ft->first.second != 0 ? c.find(m_p(ft->first.first - 1, ft->first.second - 1)) : c.end());
		ar[4] = ((ft->second.second & 0x08) >> 3 && ft->first.second != 0 ? c.find(m_p(ft->first.first, ft->first.second - 1)) : c.end());
		ar[5] = ((ft->second.second & 0x84) >> 2 && ft->first.second != 0 ? c.find(m_p(ft->first.first + 1, ft->first.second - 1)) : c.end());
		ar[6] = c.find(m_p(ft->first.first - 2, ft->first.second));
		ar[7] = c.find(m_p(ft->first.first - 1, ft->first.second));
		ar[8] = c.find(m_p(ft->first.first + 1, ft->first.second));
		ar[9] = c.find(m_p(ft->first.first + 2, ft->first.second));
		ft->second.second &= 0xFD;
		if (ar[0] != c.end())
			ar[0]->second.second &= 0xFB;
		if (ar[1] != c.end())
			ar[1]->second.second &= 0xF7;
		if (ar[2] != c.end())
			ar[2]->second.second &= 0xEF;
		if (ar[3] != c.end())
			ar[3]->second.second &= 0xDF;
		if (ar[4] != c.end())
			ar[4]->second.second &= 0xBF;
		if (ar[5] != c.end())
			ar[5]->second.second &= 0x7F;
		for (int i = 0; i < 10; i++)
		{
			if (ar[i] != c.end())
				perecalc(ar[i]);
		}
		s.erase(it);
		c.erase(ft);
	}
}

void printAns() {
	for (int i = 0; i < m; i++)
	{
		ans = ((int64)ans + (int64)p[m - 1 - i] * (int64)v[i]) % mod;
	}
	cout << ans << endl;
}

int main() {
#pragma region I/O
	ios_base::sync_with_stdio(false);
#ifdef _DEBUG
	uint TEST_NUM = 0;
	freopen("input.txt", "r", stdin);
#define EOS !cin.eof()
#define P_DEBUG printf("\n           TEST %3d           \n-----////////////////////-----\n\n", ++TEST_NUM)
#else
#define EOS false
#define P_DEBUG
#ifdef IN
	freopen(IN, "r", stdin);
#endif
#ifdef OUT
	freopen(OUT, "w", stdout);
#endif
#endif
	cout.setf(ios::fixed);
	cout.precision(11);
#pragma endregion
	do {
		P_DEBUG;
		init();
		solve();
		printAns();
	} while (EOS);
	return 0;
}


//
//  main.cpp
//  D
//
//  Created by luras on 15/6/29.
//  Copyright (c) 2015年 luras. All rights reserved.
//

#define ms(x,y) memset(x,y,sizeof(x))
#define mc(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<list>
#include<set>
#include<algorithm>
using namespace std;
const int N=2e5+100,Z=1e9+9;
const double PI=acos(-1.0);
typedef long long ll;
set<int>s;
map<int,int>mop[N];         //坐标y在前面，因为最多只会堆到n*2的高度

struct point
{
    int x,y,ord;
}a[N];

int n,i,b[N];
ll ans,t;

void judge(int y,int x)
{
    if(mop[y+1][x]&&(mop[y][x-1]&&!mop[y][x+1])) s.erase(mop[y][x-1]);
    if(mop[y+1][x]&&(!mop[y][x-1]&&mop[y][x+1])) s.erase(mop[y][x+1]);
    if(mop[y+1][x-1]&&(mop[y][x-2]&&!mop[y][x-1])) s.erase(mop[y][x-2]);
    if(mop[y+1][x-1]&&(!mop[y][x-2]&&mop[y][x-1])) s.erase(mop[y][x-1]);
    if(mop[y+1][x+1]&&(mop[y][x+2]&&!mop[y][x+1])) s.erase(mop[y][x+2]);
    if(mop[y+1][x+1]&&(!mop[y][x+2]&&mop[y][x+1])) s.erase(mop[y][x+1]);

}

int carry(int y,int x)
{
    //judge(y,x);
    if(s.find(mop[y][x])!=s.end()) return 0;            //已经有了不用加
    if(mop[y+1][x]&&(!mop[y][x-1]&&!mop[y][x+1])) return 0;     //如果拿走了这一块，上面那块没有地方放了，就不加
    if(mop[y+1][x-1]&&(!mop[y][x-2]&&!mop[y][x-1])) return 0; //左上角那一块
    if(mop[y+1][x+1]&&(!mop[y][x+2]&&!mop[y][x+1])) return 0;     //右上角那一块
    return 1;
}

int main()
{
    while(~scanf("%d",&n)){
        s.clear();
        for(i=1;i<=n;i++){
            mop[i].clear();
        }
        for(i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].ord=i;
            mop[a[i].y+1][a[i].x+1]=i;
        }
        for(i=1;i<=n;i++){
            if(carry(a[i].y+1,a[i].x+1)){
                s.insert(i);
            }
        }
        set<int>::iterator it;
        for(i=1;i<=n;i++){
            if(i%2)
                it=--s.end();
            else it=s.begin();
            b[i]=*it;           //b[i]里存储着顺序拿的编号
            s.erase(b[i]);
            t=b[i];
            int xx=a[t].x;
            int yy=a[t].y;
            mop[yy+1][xx+1]=0;

            judge(yy+1,xx+1);

            if(mop[yy][xx+1]&&carry(yy,xx+1)){               //下面这块
                s.insert(mop[yy][xx+1]);
            }
            if(mop[yy][xx]&&carry(yy,xx)){
                s.insert(mop[yy][xx]);
            }
            if(mop[yy][xx+2]&&carry(yy,xx+2)){
                s.insert(mop[yy][xx+2]);
            }
        }
        t=1;
        ll ans=0;
        for(i=n;i>=1;i--){
            ans=(ans+t*(b[i]-1))%Z;
            t=(t*n)%Z;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

/*

 题意:

 类型:

 分析:

 优化:

 trick:

 数据:

 Sample Input
 3
 2 1
 1 0
 0 1

 5
 0 0
 0 1
 0 2
 0 3
 0 4

 10
 -1 2
 -3 0
 5 5
 4 4
 -2 1
 1 1
 3 3
 2 2
 0 0
 -1000000000 0

 10
 -678318184 2
 -678318182 3
 580731357 2
 -678318182 1
 -678318184 1
 -678318183 0
 -678318181 2
 580731357 1
 580731358 0
 -678318183 2

 15
 -491189818 2
 -491189821 6
 -491189823 4
 -491189821 4
 -491189822 5
 -491189819 1
 -491189822 4
 -491189822 7
 -491189821 1
 -491189820 2
 -491189823 3
 -491189817 3
 -491189821 3
 -491189820 0
 -491189822 2

 Sample Output
 19
 2930
 41236677
 41627304
 936629642

 */


//
//  main.cpp
//  D
//
//  Created by luras on 15/6/29.
//  Copyright (c) 2015年 luras. All rights reserved.
//

#define ms(x,y) memset(x,y,sizeof(x))
#define mc(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<list>
#include<set>
#include<algorithm>
using namespace std;
const int N=100,Z=1e9+9;
const double PI=acos(-1.0);
typedef long long ll;
set<int>s;
map<int,int>mop[N];         //坐标y在前面，因为最多只会堆到n*2的高度

struct point
{
    int x,y,ord;
}a[N];

int n,i,t,b[N];
ll ans;

int carry(int y,int x)
{
    if(s.find(mop[y][x])!=s.end()) return 0;            //已经有了不用加
    if(mop[y+1][x]&&(!mop[y][x-1]&&!mop[y][x+1])) return 0;     //如果拿走了这一块，上面那块没有地方放了，就不加
    if(mop[y+1][x-1]&&(!mop[y][x-2]&&!mop[y][x])) return 0; //左上角那一块
    if(mop[y+1][x+1]&&(!mop[y][x]&&!mop[y][x+2])) return 0;     //右上角那一块
    return 1;
}

int main()
{
    while(~scanf("%d",&n)){
        s.clear();
        for(i=1;i<=n;i++){
            mop[i].clear();
        }
        for(i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].ord=i;
            mop[a[i].y+1][a[i].x+1]=i;
        }
        for(i=1;i<=n;i++){
            if(carry(a[i].y+1,a[i].x+1)){
                s.insert(i);
            }
        }
        set<int>::iterator it;
        for(i=1;i<=n;i++){
            if(i%2)
                it=--s.end();
            else it=++s.begin();
            b[i]=*it;           //b[i]里存储着顺序拿的编号
            s.erase(b[i]);
            t=b[i];
            mop[a[t].y+1][a[t].x+1]=0;
            if(carry(a[t].y,a[t].x+1)){               //下面这块
                s.insert(mop[a[t].y][a[t].x+1]);
            }
            if(carry(a[t].y+1,a[t].x+1)){
                s.insert(mop[a[t].y+1][a[t].x+1]);
            }
            if(carry(a[t].y+2,a[t].x+1)){
                s.insert(mop[a[t].y+2][a[t].x+1]);
            }
        }
        t=1;
        ll ans=0;
        for(i=n;i>=1;i--){
            ans=(ans+t*(b[i]-1))%Z;
            t=(t*n)%Z;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

/*

 题意:

 类型:

 分析:

 优化:

 trick:

 数据:

 Sample Input
 3
 2 1
 1 0
 0 1

 5
 0 0
 0 1
 0 2
 0 3
 0 4

 Sample Output

 */


//
//  main.cpp
//  D
//
//  Created by luras on 15/6/29.
//  Copyright (c) 2015年 luras. All rights reserved.
//

#define ms(x,y) memset(x,y,sizeof(x))
#define mc(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<list>
#include<set>
#include<algorithm>
using namespace std;
const int N=100,Z=1e9+9;
const double PI=acos(-1.0);
typedef long long ll;
set<int>s;
map<int,int>mop[N];         //坐标y在前面，因为最多只会堆到n*2的高度

struct point
{
    int x,y,ord;
}a[N];

int n,i,b[N];
ll ans,t;

int carry(int y,int x)
{
    if(s.find(mop[y][x])!=s.end()) return 0;            //已经有了不用加
    if(mop[y+1][x]&&(!mop[y][x-1]&&!mop[y][x+1])) return 0;     //如果拿走了这一块，上面那块没有地方放了，就不加
    if(mop[y+1][x-1]&&(!mop[y][x-2]&&!mop[y][x-1])) return 0; //左上角那一块
    if(mop[y+1][x+1]&&(!mop[y][x+2]&&!mop[y][x+1])) return 0;     //右上角那一块
    return 1;
}

int main()
{
    while(~scanf("%d",&n)){
        s.clear();
        for(i=1;i<=n;i++){
            mop[i].clear();
        }
        for(i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].ord=i;
            mop[a[i].y+1][a[i].x+1]=i;
        }
        for(i=1;i<=n;i++){
            if(carry(a[i].y+1,a[i].x+1)){
                s.insert(i);
            }
        }
        set<int>::iterator it;
        for(i=1;i<=n;i++){
            if(i%2)
                it=--s.end();
            else it=s.begin();
            b[i]=*it;           //b[i]里存储着顺序拿的编号
            s.erase(b[i]);
            t=b[i];
            int xx=a[t].x;
            int yy=a[t].y;
            mop[yy+1][xx+1]=0;
            if(mop[yy][xx+1]&&carry(yy,xx+1)){               //下面这块
                s.insert(mop[yy][xx+1]);
            }
            if(mop[yy][xx]&&carry(yy,xx)){
                s.insert(mop[yy][xx]);
            }
            if(mop[yy][xx+2]&&carry(yy,xx+2)){
                s.insert(mop[yy][xx+2]);
            }
        }
        t=1;
        ll ans=0;
        for(i=n;i>=1;i--){
            ans=(ans+t*(b[i]-1))%Z;
            t=(t*n)%Z;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

/*

 题意:

 类型:

 分析:

 优化:

 trick:

 数据:

 Sample Input
 3
 2 1
 1 0
 0 1

 5
 0 0
 0 1
 0 2
 0 3
 0 4

 10
 -1 2
 -3 0
 5 5
 4 4
 -2 1
 1 1
 3 3
 2 2
 0 0
 -1000000000 0

 Sample Output
 19
 2930
 41236677

 */


//
//  main.cpp
//  D
//
//  Created by luras on 15/6/29.
//  Copyright (c) 2015年 luras. All rights reserved.
//

#define ms(x,y) memset(x,y,sizeof(x))
#define mc(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<list>
#include<set>
#include<algorithm>
using namespace std;
const int N=100,Z=1e9+9;
const double PI=acos(-1.0);
typedef long long ll;
set<int>s;
map<int,int>mop[N];         //坐标y在前面，因为最多只会堆到n*2的高度

struct point
{
    int x,y,ord;
}a[N];

int n,i,b[N];
ll ans,t;

void judge(int y,int x)
{
    if(mop[y+1][x]&&(mop[y][x-1]&&!mop[y][x+1])) s.erase(mop[y][x-1]);
    if(mop[y+1][x]&&(!mop[y][x-1]&&mop[y][x+1])) s.erase(mop[y][x+1]);
    if(mop[y+1][x-1]&&(mop[y][x-2]&&!mop[y][x-1])) s.erase(mop[y][x-2]);
    if(mop[y+1][x-1]&&(!mop[y][x-2]&&mop[y][x-1])) s.erase(mop[y][x-1]);
    if(mop[y+1][x+1]&&(mop[y][x+2]&&!mop[y][x+1])) s.erase(mop[y][x+2]);
    if(mop[y+1][x+1]&&(!mop[y][x+2]&&mop[y][x+1])) s.erase(mop[y][x+1]);

}

int carry(int y,int x)
{
    //judge(y,x);
    if(s.find(mop[y][x])!=s.end()) return 0;            //已经有了不用加
    if(mop[y+1][x]&&(!mop[y][x-1]&&!mop[y][x+1])) return 0;     //如果拿走了这一块，上面那块没有地方放了，就不加
    if(mop[y+1][x-1]&&(!mop[y][x-2]&&!mop[y][x-1])) return 0; //左上角那一块
    if(mop[y+1][x+1]&&(!mop[y][x+2]&&!mop[y][x+1])) return 0;     //右上角那一块
    return 1;
}

int main()
{
    while(~scanf("%d",&n)){
        s.clear();
        for(i=1;i<=n;i++){
            mop[i].clear();
        }
        for(i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].ord=i;
            mop[a[i].y+1][a[i].x+1]=i;
        }
        for(i=1;i<=n;i++){
            if(carry(a[i].y+1,a[i].x+1)){
                s.insert(i);
            }
        }
        set<int>::iterator it;
        for(i=1;i<=n;i++){
            if(i%2)
                it=--s.end();
            else it=s.begin();
            b[i]=*it;           //b[i]里存储着顺序拿的编号
            s.erase(b[i]);
            t=b[i];
            int xx=a[t].x;
            int yy=a[t].y;
            mop[yy+1][xx+1]=0;

            judge(yy+1,xx+1);

            if(mop[yy][xx+1]&&carry(yy,xx+1)){               //下面这块
                s.insert(mop[yy][xx+1]);
            }
            if(mop[yy][xx]&&carry(yy,xx)){
                s.insert(mop[yy][xx]);
            }
            if(mop[yy][xx+2]&&carry(yy,xx+2)){
                s.insert(mop[yy][xx+2]);
            }
        }
        t=1;
        ll ans=0;
        for(i=n;i>=1;i--){
            ans=(ans+t*(b[i]-1))%Z;
            t=(t*n)%Z;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

/*

 题意:

 类型:

 分析:

 优化:

 trick:

 数据:

 Sample Input
 3
 2 1
 1 0
 0 1

 5
 0 0
 0 1
 0 2
 0 3
 0 4

 10
 -1 2
 -3 0
 5 5
 4 4
 -2 1
 1 1
 3 3
 2 2
 0 0
 -1000000000 0

 10
 -678318184 2
 -678318182 3
 580731357 2
 -678318182 1
 -678318184 1
 -678318183 0
 -678318181 2
 580731357 1
 580731358 0
 -678318183 2

 15
 -491189818 2
 -491189821 6
 -491189823 4
 -491189821 4
 -491189822 5
 -491189819 1
 -491189822 4
 -491189822 7
 -491189821 1
 -491189820 2
 -491189823 3
 -491189817 3
 -491189821 3
 -491189820 0
 -491189822 2

 Sample Output
 19
 2930
 41236677
 41627304
 936629642

 */


//
//  main.cpp
//  D
//
//  Created by luras on 15/6/29.
//  Copyright (c) 2015年 luras. All rights reserved.
//

#define ms(x,y) memset(x,y,sizeof(x))
#define mc(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<list>
#include<set>
#include<algorithm>
using namespace std;
const int N=100,Z=1e9+9;
const double PI=acos(-1.0);
typedef long long ll;
set<int>s;
map<int,int>mop[N];         //坐标y在前面，因为最多只会堆到n*2的高度

struct point
{
    int x,y,ord;
}a[N];

int n,i,t,b[N];
ll ans;

int carry(int y,int x)
{
    if(mop[y][x+1]&&(!mop[y-1][x]&&!mop[y+1][x])) return 0;
    if(y-2>=0&&mop[y-1][x+1]&&(!mop[y-2][x]&&!mop[y][x])) return 0;
    if(mop[y+1][x+1]&&(!mop[y][x]&&!mop[y+2][x])) return 0;
    return 1;
}

int main()
{
    while(~scanf("%d",&n)){
        s.clear();
        for(i=1;i<=n;i++){
            mop[i].clear();
        }
        for(i=1;i<=n;i++){
            scanf("%d%d",&a[i].y,&a[i].x);
            a[i].ord=i;
            mop[a[i].y+1][a[i].x+1]=i;
        }
        for(i=1;i<=n;i++){
            if(carry(a[i].y+1,a[i].x+1)){
                s.insert(i);
            }
        }
        set<int>::iterator it;
        for(i=1;i<=n;i++){
            if(i%2)
                it=--s.end();
            else it=++s.begin();
            b[i]=*it;           //b[i]里存储着顺序拿的编号
            s.erase(b[i]);
            t=b[i];
            mop[a[t].y+1][a[t].x+1]=0;
            if(carry(a[t].y,a[t].x)){
                s.insert(mop[a[t].y][a[t].x]);
            }
            if(carry(a[t].y+1,a[t].x)){
                s.insert(mop[a[t].y+1][a[t].x]);
            }
            if(carry(a[t].y+2,a[t].x)){
                s.insert(mop[a[t].y+2][a[t].x]);
            }
        }
        t=1;
        ll ans=0;
        for(i=n;i>=1;i--){
            ans=(ans+t*(b[i]-1))%Z;
            t=(t*n)%Z;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

/*

 题意:

 类型:

 分析:

 优化:

 trick:

 数据:

 Sample Input
 3
 2 1
 1 0
 0 1

 5
 0 0
 0 1
 0 2
 0 3
 0 4

 Sample Output

 */


//
//  main.cpp
//  D
//
//  Created by luras on 15/6/29.
//  Copyright (c) 2015年 luras. All rights reserved.
//

#define ms(x,y) memset(x,y,sizeof(x))
#define mc(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<list>
#include<set>
#include<algorithm>
using namespace std;
const int N=100,Z=1e9+9;
const double PI=acos(-1.0);
typedef long long ll;
set<int>s;
map<int,int>mop[N];         //坐标y在前面，因为最多只会堆到n*2的高度

struct point
{
    int x,y,ord;
}a[N];

int n,i,b[N];
ll ans,t;

int carry(int y,int x)
{
    if(mop[y+1][x]&&(mop[y][x-1]&&!mop[y][x+1])) s.erase(mop[y][x-1]);
    if(mop[y+1][x]&&(!mop[y][x-1]&&mop[y][x+1])) s.erase(mop[y][x+1]);
    if(mop[y+1][x-1]&&(mop[y][x-2]&&!mop[y][x-1])) s.erase(mop[y][x-2]);
    if(mop[y+1][x-1]&&(!mop[y][x-2]&&mop[y][x-1])) s.erase(mop[y][x-1]);
    if(mop[y+1][x+1]&&(mop[y][x+2]&&!mop[y][x+1])) s.erase(mop[y][x+2]);
    if(mop[y+1][x+1]&&(!mop[y][x+2]&&mop[y][x+1])) s.erase(mop[y][x+1]);

    if(s.find(mop[y][x])!=s.end()) return 0;            //已经有了不用加
    if(mop[y+1][x]&&(!mop[y][x-1]&&!mop[y][x+1])) return 0;     //如果拿走了这一块，上面那块没有地方放了，就不加
    if(mop[y+1][x-1]&&(!mop[y][x-2]&&!mop[y][x-1])) return 0; //左上角那一块
    if(mop[y+1][x+1]&&(!mop[y][x+2]&&!mop[y][x+1])) return 0;     //右上角那一块
    return 1;
}

int main()
{
    while(~scanf("%d",&n)){
        s.clear();
        for(i=1;i<=n;i++){
            mop[i].clear();
        }
        for(i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].ord=i;
            mop[a[i].y+1][a[i].x+1]=i;
        }
        for(i=1;i<=n;i++){
            if(carry(a[i].y+1,a[i].x+1)){
                s.insert(i);
            }
        }
        set<int>::iterator it;
        for(i=1;i<=n;i++){
            if(i%2)
                it=--s.end();
            else it=s.begin();
            b[i]=*it;           //b[i]里存储着顺序拿的编号
            s.erase(b[i]);
            t=b[i];
            int xx=a[t].x;
            int yy=a[t].y;
            mop[yy+1][xx+1]=0;
            if(mop[yy][xx+1]&&carry(yy,xx+1)){               //下面这块
                s.insert(mop[yy][xx+1]);
            }
            if(mop[yy][xx]&&carry(yy,xx)){
                s.insert(mop[yy][xx]);
            }
            if(mop[yy][xx+2]&&carry(yy,xx+2)){
                s.insert(mop[yy][xx+2]);
            }
        }
        t=1;
        ll ans=0;
        for(i=n;i>=1;i--){
            ans=(ans+t*(b[i]-1))%Z;
            t=(t*n)%Z;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

/*

 题意:

 类型:

 分析:

 优化:

 trick:

 数据:

 Sample Input
 3
 2 1
 1 0
 0 1

 5
 0 0
 0 1
 0 2
 0 3
 0 4

 10
 -1 2
 -3 0
 5 5
 4 4
 -2 1
 1 1
 3 3
 2 2
 0 0
 -1000000000 0

 10
 -678318184 2
 -678318182 3
 580731357 2
 -678318182 1
 -678318184 1
 -678318183 0
 -678318181 2
 580731357 1
 580731358 0
 -678318183 2

 Sample Output
 19
 2930
 41236677
 41627304

 */


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

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

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


#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 9;
typedef long long ll;
map<pair<int, int>, int>ma;
//map<int,pair<int, int> >ma2;
set<int>s;
int m;
int x[maxn];
int y[maxn];
int cal(int xi, int yi)
{
	int cnt = 0;
	for(int i = -1; i <= 1; i++)
	{
		int dx = xi + i;
		int dy = yi - 1;
		if(ma[make_pair(dx, dy)] > 0) cnt++;
	}
	return cnt;
}
void judge(int xi, int yi)
{
	bool flag = true;
	for(int i = -1; i <= 1; i++)
	{
		int dx = xi + i;
		int dy = yi + 1;
		if(ma[make_pair(dx, dy)] > 0 && cal(dx, dy) == 1) flag = false;
	}
	int kp = ma[make_pair(xi, yi)];
	if(flag)
	{

		if(s.find(kp) == s.end()) s.insert(kp);
	}
	else
	{
		if(s.find(kp) != s.end()) s.erase(kp);

	}
}
bool ok(int xi, int yi)
{
	bool flag1 = false, flag2 = false;
	for(int i = -1; i <= 1; i++)
	{
		for(int j = -1; j <= 1; j++)
		{
			int dx = xi + i;
			int dy = yi + j;
			if(i == j && j == 0) continue;
			if(ma[(make_pair(dx, dy))] > 0)
			{
				flag1 = true;
				if(cal(dx, dy) == 1) flag2 = false;
				else flag2 = true;
			}
		}
	}
	if(flag1 == false || flag2 == true) return true;
	return false;
}
void work()
{
	scanf("%d", &m);
	for(int i = 0; i < m; i++)
	{
		scanf("%d%d", &x[i], &y[i]);
		ma[make_pair(x[i], y[i])] = i + 1;
		//ma2[i + 1] = make_pair(x[i], y[i]);
	}
	for(int i = 0; i < m; i++)
	{
		judge(x[i], y[i]);
	}
	//sort(v.begin(), v.end());
	ll ans = 0;
	int si = s.size();
	for(int i = 0;i < m ; i++)
	{
	//	si = s.size();
	//	if(!si) break;
		int num;
		int p;
		if(i % 2 == 0)
		{
			p = *s.rbegin();
		//	printf("i:%d p:%d\n", i, p);
			num = si - 1;
		}
		else
		{
			p = *s.begin();
			num = 0;
		}

	//	v.erase(num + v.begin());
		s.erase(p);
		ans = (ans * m + p - 1) % mod;
	//	ma[ma2[p]] = 0;
		ma[make_pair(x[p - 1], y[p - 1])] = 0;
		for(int e = -1; e <= 1; e++)
		{
			for(int r = -1; r <= 1; r++)
			{
				int dx = x[p - 1] + e;
				int dy = y[p - 1] + r;
				if(ma[make_pair(dx, dy)] > 0)
				{
					judge(dx, dy);
				}
			}
		}
	}
	printf("%lld\n", ans);
}
int main()
{
	work();
	return 0;
}


#include<bits/stdc++.h>
#define MAXN 100000+1109
#define MOD 1000000009

using namespace std;

priority_queue <int> B;
priority_queue <int> S;

struct Data
{
	long long a;
	int Num;

}a[MAXN];

bool cmp(const Data &aa,const Data &bb)
{
	return aa.a<bb.a;
}

vector <int> f[MAXN];
int Du[MAXN],RD[MAXN];
long long Da[MAXN];

int n;
long long Ans;

bool b[MAXN];

int Find(long long x)
{
	int I;
	I=lower_bound(Da+1,Da+1+n,x)-Da;
	if(Da[I]!=x) return -1;
	return a[I].Num;
}

int main()
{
	scanf("%d",&n);
	long long x,y,z;
	int X;
	for(int i=0;i<n;i++)
	{
		scanf("%I64d%I64d",&x,&y);
		x+=1000000000;
		z=y*2000000001+x;
		a[i+1].a=z;
		a[i+1].Num=i;
	}
	sort(a+1,a+1+n,cmp);

	for(int i=1;i<=n;i++)
		Da[i]=a[i].a;

	for(int i=1;i<=n;i++)
	for(int j=2000000000;j<=2000000002;j++)
		{
			x=Find(a[i].a+j);
			if(x==-1) continue;
			Du[x]++;
			f[x].push_back(a[i].Num);
			RD[a[i].Num]++;
		}
	/*for(int i=0;i<n;i++)
		Duu[i]=Du[i];*/
	for(int i=0;i<n;i++)
		if(RD[i]==0)
		{
			B.push(i);
			S.push(-i);
		}
	for(int Round=1;Round<=n;Round++)
	{
		if(Round&1)
		{
			while(b[B.top()]) B.pop();
			x=B.top();
			Ans=((Ans*n)%MOD+x)%MOD;
			B.pop();
			b[x]=true;
			for(int i=0;i<Du[x];i++)
			{
				X=f[x][i];
				RD[X]--;
				if(RD[X]==0)
				{
					B.push(X);
					S.push(-X);
				}
			}
		}
		else
		{
			while(b[-S.top()]) S.pop();
			x=-S.top();
			Ans=((Ans*n)%MOD+x)%MOD;
			S.pop();
			b[x]=true;
			for(int i=0;i<Du[x];i++)
			{
				X=f[x][i];
				RD[X]--;
				if(RD[X]==0)
				{
					B.push(X);
					S.push(-X);
				}
			}
		}
	}
	printf("%I64d",Ans);
	/*for(int i=0;i<n;i++)
	{
		for(int j=0;j<Du[i];j++)
			printf("%d",f[i][j]);
		printf("\n");
	}*/
	return 0;
}