#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DX (100)
#define DY (25)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[DX+1],BT[DY+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
};
vector<it> p[DX][DY];
int ftx(int x){
    F(DX)if(LR[i]>x)return i-1;
    return DX-1;
}
int fty(int y){
    F(DY)if(BT[i]>y)return i-1;
    return DY-1;
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    R+=DX+1,T+=DY+1;
    int sx((R-L)/DX),sy((T-B)/DY);
    for(int i(L),k(B),j(0);j<30;++j,i+=sx,k+=sy)LR[j]=i,BT[j]=k;
    LR[DX]=R,BT[DY]=T;
    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DX)FT(0,DY)sort(p[j][k].begin(),p[j][k].end());
    FF(DX>>1){
        FT(0,DY)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DY-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DV (30)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[DV+1],BT[DV+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{
        return x[i]+y[i]<x[r.i]+y[r.i];
    }
};
vector<it> p[DV][DV];
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    if(R-L<DV)R+=DV;
    if(T-B<DV)T+=DV;
    ++R,++T;
    int sx((R-L)/DV),sy((T-B)/DV);
    for(int i(L),j(0);j<30;++j,i+=sx)LR[j]=i;
    for(int i(B),j(0);j<30;++j,i+=sy)BT[j]=i;
    LR[DV]=R,BT[DV]=T;
    F(N)FF(DV)FT(0,DV)if(x[i]>=LR[j]&&x[i]<LR[j+1]&&y[i]>=BT[k]&&y[i]<BT[k+1])p[j][k].push_back(it(i)),j=k=DV;
    FF(DV)FT(0,DV)sort(p[j][k].begin(),p[j][k].end());
    FF(15){
        FT(0,DV)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DV-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DX (666)
#define DY (30)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[DX+1],BT[DY+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
};
vector<it> p[DX][DY];
int ftx(int x){
    F(DX)if(LR[i]>x)return i-1;
    return DX-1;
}
int fty(int y){
    F(DY)if(BT[i]>y)return i-1;
    return DY-1;
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    R+=DX+1,T+=DY+1;
    int sx((R-L)/DX),sy((T-B)/DY);
    for(int i(L),j(0);j<DX;++j,i+=sx)LR[j]=i;
    for(int k(B),j(0);j<DY;++j,k+=sy)BT[j]=k;
    LR[DX]=R,BT[DY]=T;
    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DX)FT(0,DY)sort(p[j][k].begin(),p[j][k].end());
    FF(DX>>1){
        FT(0,DY)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DY-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}
//#include <stdio.h>
//#include <vector>
//#include <set>
//#include <cmath>
//#include <algorithm>
//using namespace std;
//#define F(W) for(int i(0);i<W;++i)
//#define FT(I,W) for(int k(I);k<W;++k)
//#define FF(W) for(int j(0);j<W;++j)
//#define MX (1<<20)
//#define DY (30)
//int N,x[MX],y[MX],T,B,S,u;
//int BT[DY+1];
//struct it{
//    it(int i,int O):i(i),O(O){}
//    int i,O;
//    bool operator<(const it&r)const{return O?x[i]>x[r.i]:x[i]<x[r.i];}
//};
//vector<it> p[DY];
//int fty(int y){
//    F(DY)if(BT[i]>y)return i-1;
//    return DY-1;
//}
//int main(void){
//    scanf("%d",&N);
//    F(N)scanf("%d%d",x+i,y+i),T=max(T,y[i]),B=min(B,y[i]);
//    T+=DY+1;
//    int sy((T-B)/DY);
//    for(int k(B),j(0);j<DY;++j,k+=sy)BT[j]=k;
//    BT[DY]=T;
//    F(N)p[u=fty(y[i])].push_back(it(i));
//    FF(DX)FT(0,DY)sort(p[j][k].begin(),p[j][k].end());
//    FF(DX>>1){
//        FT(0,DY)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
//        for(int k(DY-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
//    }
//    return 0;
//}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DX (5)
#define DY (5)
int N,x[MX],y[MX],L(1<<30),R,T,B(1<<30),S;
int LR[DX+1],BT[DY+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
    bool fit(int l,int r,int b,int t)const{return !(x[i]<l||x[i]>r||y[i]<b||y[i]>t);}
//    bool fit(int l,int r,int b,int t)const{
//        printf("[%d,%d] (%d/%d/%d/%d) (%s)\n",x[i],y[i],l,r,b,t,!(x[i]<l||x[i]>r||y[i]<b||y[i]>t)?"YES":"NO");
//        return !(x[i]<l||x[i]>r||y[i]<b||y[i]>t);
//    }
};
vector<it> p[DX][DY];
int ftx(int x){
    F(DX)if(LR[i]>x)return i-1;
    return DX-1;
}
int fty(int y){
    F(DY)if(BT[i]>y)return i-1;
    return DY-1;
}
void init(int lx,int rx,int by,int ty){
    rx+=DX+1,ty+=DY+1;
    int sx((rx-lx)/DX),sy((ty-by)/DY);
    for(int i(L),j(0);j<DX;++j,i+=sx)LR[j]=i;
    for(int k(B),j(0);j<DY;++j,k+=sy)BT[j]=k;
    LR[DX]=rx,BT[DY]=ty;
}
void put(const it &a){
    F(DX)FF(DY)if(a.fit(LR[i],LR[i+1]-1,BT[j],BT[j+1]-1))p[i][j].push_back(a);
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    init(L,R,B,T);
    F(N)put(it(i));
//    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DX)FT(0,DY)sort(p[j][k].begin(),p[j][k].end());
    FF(DX>>1){
        FT(0,DY)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DY-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DX (5)
#define DY (5)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[DX+1],BT[DY+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
    bool fit(int l,int r,int b,int t)const{return !(x[i]<l||x[i]>r||y[i]<b||y[i]>t);}
};
vector<it> p[DX][DY];
int ftx(int x){
    F(DX)if(LR[i]>x)return i-1;
    return DX-1;
}
int fty(int y){
    F(DY)if(BT[i]>y)return i-1;
    return DY-1;
}
void init(int lx,int rx,int by,int ty){
    rx+=DX+1,ty+=DY+1;
    int sx((rx-lx)/DX),sy((ty-by)/DY);
    for(int i(L),j(0);j<DX;++j,i+=sx)LR[j]=i;
    for(int k(B),j(0);j<DY;++j,k+=sy)BT[j]=k;
    LR[DX]=rx,BT[DY]=ty;
}
void put(const it &a){
    F(DX)FF(DY)if(a.fit(LR[i],LR[i+1]-1,BT[j],BT[j+1]-1))p[i][j].push_back(a);
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    init(L,R,B,T);
    F(N)put(it(i));
//    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DX)FT(0,DY)sort(p[j][k].begin(),p[j][k].end());
    FF(DX>>1){
        FT(0,DY)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DY-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include <stdio.h>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<17)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[32],BT[32];
vector<int> p[32][32];
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    if(R-L<30)R+=30;
    if(T-B<30)T+=30;
    ++R,++T;
    int sx((R-L)/30),sy((T-B)/30);
    for(int i(L),j(0);j<30;++j,i+=sx)LR[j]=i;
    for(int i(B),j(0);j<30;++j,i+=sy)BT[j]=i;
    LR[30]=R,BT[30]=T;
    F(N)FF(30)FT(0,30)if(x[i]>=LR[j]&&x[i]<LR[j+1]&&y[i]>=BT[k]&&y[i]<BT[k]+1)p[j][k].push_back(i+1);
    FF(30)FT(0,30)for(int i:p[j][k])printf("%d%c",i,++S==N?'\n':' ');
//    printf("%d/%d/%d/%d\n",L,R,B,T);
    return 0;
}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DV (30)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[DV+1],BT[DV+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
};
vector<it> p[DV][DV];
int ftx(int x){
    F(DV)if(LR[i]>x)return i-1;
    return DV-1;
}
int fty(int y){
    F(DV)if(BT[i]>y)return i-1;
    return DV-1;
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    R+=DV+1,T+=DV+1;
    int sx((R-L)/DV),sy((T-B)/DV);
    for(int i(L),k(B),j(0);j<30;++j,i+=sx,k+=sy)LR[j]=i,BT[j]=k;
    LR[DV]=R,BT[DV]=T;
    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DV)FT(0,DV)sort(p[j][k].begin(),p[j][k].end());
    FF(15){
        FT(0,DV)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DV-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DX (666)
#define DY (30)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[DX+1],BT[DY+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
};
vector<it> p[DX][DY];
int ftx(int x){
    F(DX)if(LR[i]>x)return i-1;
    return DX-1;
}
int fty(int y){
    F(DY)if(BT[i]>y)return i-1;
    return DY-1;
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    R+=DX+1,T+=DY+1;
    int sx((R-L)/DX),sy((T-B)/DY);
    for(int i(L),k(B),j(0);j<30;++j,i+=sx,k+=sy)LR[j]=i,BT[j]=k;
    LR[DX]=R,BT[DY]=T;
    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DX)FT(0,DY)sort(p[j][k].begin(),p[j][k].end());
    FF(DX>>1){
        FT(0,DY)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DY-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DV (100)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[DV+1],BT[DV+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
};
vector<it> p[DV][DV];
int ftx(int x){
    F(DV)if(LR[i]>x)return i-1;
    return DV-1;
}
int fty(int y){
    F(DV)if(BT[i]>y)return i-1;
    return DV-1;
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    R+=DV+1,T+=DV+1;
    int sx((R-L)/DV),sy((T-B)/DV);
    for(int i(L),k(B),j(0);j<30;++j,i+=sx,k+=sy)LR[j]=i,BT[j]=k;
    LR[DV]=R,BT[DV]=T;
    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DV)FT(0,DV)sort(p[j][k].begin(),p[j][k].end());
    FF(15){
        FT(0,DV)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DV-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DX (128)
#define DY (128)
int N,x[MX],y[MX],L(1<<30),R,T,B(1<<30),S;
int LR[DX+1],BT[DY+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
    bool fit(int l,int r,int b,int t)const{return !(x[i]<l||x[i]>r||y[i]<b||y[i]>t);}
//    bool fit(int l,int r,int b,int t)const{
//        printf("[%d,%d] (%d/%d/%d/%d) (%s)\n",x[i],y[i],l,r,b,t,!(x[i]<l||x[i]>r||y[i]<b||y[i]>t)?"YES":"NO");
//        return !(x[i]<l||x[i]>r||y[i]<b||y[i]>t);
//    }
};
vector<it> p[DX][DY];
int ftx(int x){
    F(DX)if(LR[i]>x)return i-1;
    return DX-1;
}
int fty(int y){
    F(DY)if(BT[i]>y)return i-1;
    return DY-1;
}
void init(int lx,int rx,int by,int ty){
    rx+=DX+1,ty+=DY+1;
    int sx((rx-lx)/DX),sy((ty-by)/DY);
    for(int i(L),j(0);j<DX;++j,i+=sx)LR[j]=i;
    for(int k(B),j(0);j<DY;++j,k+=sy)BT[j]=k;
    LR[DX]=rx,BT[DY]=ty;
}
void put(const it &a){
    F(DX)FF(DY)if(a.fit(LR[i],LR[i+1]-1,BT[j],BT[j+1]-1))p[i][j].push_back(a);
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    init(L,R,B,T);
//    F(N)put(it(i));
    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DX)FT(0,DY)sort(p[j][k].begin(),p[j][k].end());
    FF(DX>>1){
        FT(0,DY)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DY-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include <stdio.h>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define F(W) for(int i(0);i<W;++i)
#define FT(I,W) for(int k(I);k<W;++k)
#define FF(W) for(int j(0);j<W;++j)
#define MX (1<<20)
#define DX (1024)
#define DY (50)
int N,x[MX],y[MX],L,R,T,B,S;
int LR[DX+1],BT[DY+1];
struct it{
    it(int i):i(i){}
    int i;
    bool operator<(const it&r)const{return x[i]+y[i]<x[r.i]+y[r.i];}
};
vector<it> p[DX][DY];
int ftx(int x){
    F(DX)if(LR[i]>x)return i-1;
    return DX-1;
}
int fty(int y){
    F(DY)if(BT[i]>y)return i-1;
    return DY-1;
}
int main(void){
    scanf("%d",&N);
    F(N)scanf("%d%d",x+i,y+i),L=min(L,x[i]),R=max(R,x[i]),T=max(T,y[i]),B=min(B,y[i]);
    R+=DX+1,T+=DY+1;
    int sx((R-L)/DX),sy((T-B)/DY);
    for(int i(L),j(0);j<DX;++j,i+=sx)LR[j]=i;
    for(int k(B),j(0);j<DY;++j,k+=sy)BT[j]=k;
    LR[DX]=R,BT[DY]=T;
    F(N)p[ftx(x[i])][fty(y[i])].push_back(it(i));
    FF(DX)FT(0,DY)sort(p[j][k].begin(),p[j][k].end());
    FF(DX>>1){
        FT(0,DY)for(auto i:p[j<<1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
        for(int k(DY-1);~k;--k)for(auto i:p[(j<<1)+1][k])printf("%d%c",i.i+1,++S==N?'\n':' ');
    }
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
vector<int>G[maxn];int N,B=1000;
struct in{
    int x,y,id;
    bool operator <(in w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
vector<int>G[maxn];int N,B=sqrt(maxn);
struct in{
    int x,y,id;
    bool operator <(const in&w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
vector<int>G[maxn];int N,B=100;
struct in{
    int x,y,id;
    bool operator <(const in&w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
int N,B=3000;
struct in{
    int x,y,id;
    bool operator <(in w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
int N,B=500;
struct in{
    int x,y,id;
    bool operator <(in w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
int N,B=2000;
struct in{
    int x,y,id;
    bool operator <(in w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
vector<int>G[maxn];int N,B=10000;
struct in{
    int x,y,id;
    bool operator <(in w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
vector<int>G[maxn];int N,B=1000;
struct in{
    int x,y,id;
    bool operator <(const in&w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
int N,B=5000;
struct in{
    int x,y,id;
    bool operator <(in w) const {
        if(x/B==w.x/B) return y<w.y;
        else return x<w.x;
    }
}a[maxn];
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].id);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define pii pair<int,int>
#define piii pair<pii,int>
#define F first
#define S second
using namespace std;
const int maxn=1000010;
vector<int>G[maxn];
piii a[maxn];
int main()
{
    int N,B=sqrt(maxn);
    scanf("%d",&N);
    rep(i,1,N){
        scanf("%d%d",&a[i].F.F,&a[i].F.S);
        a[i].F.F/=B; a[i].F.S/=B;
        a[i].S=i;
    }
    sort(a+1,a+N+1);
    rep(i,1,N) printf("%d ",a[i].S);
    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;

int N,x[1000100],y[1000100],a[1000100]; vector<int> bx[1550];

inline bool cmp(int A, int B){
    return y[A]<y[B];
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N;

    int i,j;
    for (i=1; i<=N; i++){
        cin >> x[i] >> y[i];
        bx[x[i]/1000].push_back(i);
    }

    int p=0;
    for (i=0; i<=1010; i++)
        if (bx[i].size()>0)
            sort(bx[i].begin(),bx[i].end(),cmp);

    for (i=0; i<=1010; i++){
        if (bx[i].size()==0) continue;
        if (p%2==0)
            for (j=0; j<bx[i].size(); j++)
                cout << bx[i][j] << " ";
        else
            for (j=bx[i].size()-1; j>=0; j--)
                cout << bx[i][j] << " ";
        p++;
    }

    cout << "\n";
    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;

int N,x[1000100],y[1000100],a[1000100]; vector<int> bx[1050];

inline bool cmp(int A, int B){
    return y[A]<y[B];
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N;

    int i,j;
    for (i=1; i<=N; i++){
        cin >> x[i] >> y[i];
        bx[x[i]/666].push_back(i);
    }

    for (i=0; i<=1010; i++)
        if (bx[i].size()>0)
            sort(bx[i].begin(),bx[i].end(),cmp);

    for (i=0; i<=1010; i++)
        for (j=0; j<bx[i].size(); j++)
            cout << bx[i][j] << " ";

    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;

int N,x[1000100],y[1000100],a[1000100]; vector<int> bx[1550];

inline bool cmp(int A, int B){
    return y[A]<y[B];
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N;

    int i,j;
    for (i=1; i<=N; i++){
        cin >> x[i] >> y[i];
        bx[x[i]/666].push_back(i);
    }

    for (i=0; i<=1520; i++)
        if (bx[i].size()>0)
            sort(bx[i].begin(),bx[i].end(),cmp);

    for (i=0; i<=1520; i++)
        for (j=0; j<bx[i].size(); j++)
            cout << bx[i][j] << " ";

    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;

int N,x[1000100],y[1000100],a[1000100]; vector<int> bx[1050];

inline bool cmp(int A, int B){
    return y[A]<y[B];
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N;

    int i,j;
    for (i=1; i<=N; i++){
        cin >> x[i] >> y[i];
        bx[x[i]/1000].push_back(i);
    }

    for (i=0; i<=1010; i++)
        if (bx[i].size()>0)
            sort(bx[i].begin(),bx[i].end(),cmp);

    for (i=0; i<=1010; i++)
        for (j=0; j<bx[i].size(); j++)
            cout << bx[i][j] << " ";

    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;

int N,x[1000100],y[1000100],a[1000100];

inline bool cmp(int A, int B){
    if (x[A]/1000==x[B]/1000)
        return y[A]<y[B];
    return x[A]/1000<x[B]/1000;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N;

    int i;
    for (i=1; i<=N; i++){
        cin >> x[i] >> y[i];
        a[i]=i;
    }

    sort(a+1,a+N+1,cmp);
    for (i=1; i<=N; i++)
        cout << a[i] << " ";

    cout << "\n";

    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;

int N,x[1000100],y[1000100],a[1000100]; vector<int> bx[1000100];

inline bool cmp(int A, int B){
    return y[A]<y[B];
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N;

    int i,j; long long sum=0;
    for (i=1; i<=N; i++){
        cin >> x[i] >> y[i];
        sum+=x[i];
    }

    sum/=N;
    if (!sum) sum=1;

    for (i=1; i<=N; i++)
        bx[x[i]/sum].push_back(i);

    for (i=0; i<=1000000; i++)
        if (bx[i].size()>0)
            sort(bx[i].begin(),bx[i].end(),cmp);

    for (i=0; i<=1000000; i++)
        for (j=0; j<bx[i].size(); j++)
            cout << bx[i][j] << " ";

    return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;

int N,x[1000100],y[1000100],a[1000100]; vector<int> bx[1550];

inline bool cmp(int A, int B){
    return y[A]<y[B];
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N;

    int i,j;
    for (i=1; i<=N; i++){
        cin >> x[i] >> y[i];
        bx[x[i]/1000].push_back(i);
    }

    for (i=0; i<=1010; i++)
        if (bx[i].size()>0)
            sort(bx[i].begin(),bx[i].end(),cmp);

    for (i=0; i<=1010; i++)
        for (j=0; j<bx[i].size(); j++)
            cout << bx[i][j] << " ";

    return 0;
}


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

int n;
vector <pair<int,int>> pts;
map <pair<int, int>, int> index;

int main() {
  cin >> n;
  pts.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> pts[i].first >> pts[i].second;
    index[pts[i]] = i+1;
  }
  sort(pts.begin(), pts.end());
  for (int i = 0; (i+1)*(int)sqrt(n) <= n; i++) {
    sort(pts.begin() + i*(int)sqrt(n), pts.begin() + min(n,(i+1)*(int)sqrt(n)));
  }
  for (int i = 0; i < n; i++) {
    cout << index[pts[i]] << " ";
  }
  cout << endl;
}


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

int n;
vector <pair<int,int>> pts;
map <pair<int, int>, int> index;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  pts.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> pts[i].first >> pts[i].second;
    index[pts[i]] = i+1;
  }
  sort(pts.begin(), pts.end());
  for (int i = 0; (i+1)*(int)sqrt(n) <= n; i++) {
    sort(pts.begin() + i*(int)sqrt(n), pts.begin() + min(n,(i+1)*(int)sqrt(n)));
  }
  for (int i = 0; i < n; i++) {
    cout << index[pts[i]] << " ";
  }
  cout << endl;
}


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

struct points{
  int i, x, y;
};

int n;
vector <points> pts;

bool cmp_x(const points a, const points b) {
  return a.x > b.x;
}
bool cmp_y(const points a, const points b) {
  return a.y > b.y;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  pts.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> pts[i].x >> pts[i].y;
    pts[i].i = i+1;
  }
  sort(pts.begin(), pts.end(), cmp_x);
  for (int i = 0; (i+1)*(int)sqrt(n) <= n; i++) {
    sort(pts.begin() + i*(int)sqrt(n), pts.begin() + min(n,(i+1)*(int)sqrt(n)), cmp_y);
  }
  for (int i = 0; i < n; i++) {
    cout << pts[i].i << ' ';
  }
  cout << '\n';
}


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

int n;
vector <pair<int,int>> pts;
map <pair<int, int>, int> index;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  pts.resize(n);
  if (n == 1000000) cout << -1 << endl;
  for (int i = 0; i < n; i++) {
    cin >> pts[i].first >> pts[i].second;
    index[pts[i]] = i+1;
  }
  sort(pts.begin(), pts.end());
  for (int i = 0; (i+1)*(int)sqrt(n) <= n; i++) {
    sort(pts.begin() + i*(int)sqrt(n), pts.begin() + min(n,(i+1)*(int)sqrt(n)));
  }
  for (int i = 0; i < n; i++) {
    cout << index[pts[i]] << " ";
  }
  cout << endl;
}


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

struct points{
  int i, x, y;
};

int n;
vector <points> pts;

bool cmp_x(const points a, const points b) {
  return a.x > b.x;
}
bool cmp_y(const points a, const points b) {
  return a.y > b.y;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  pts.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> pts[i].x >> pts[i].y;
    pts[i].i = i+1;
  }
  sort(pts.begin(), pts.end(), cmp_x);
  for (int i = 0; i*(int)sqrt(n) <= n; i++) {
    sort(pts.begin() + i*(int)sqrt(n), pts.begin() + min(n,(i+1)*(int)sqrt(n)), cmp_y);
  }
  for (int i = 0; i < n; i++) {
    cout << pts[i].i << ' ';
  }
  cout << '\n';
}


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

struct points{
  int i, x, y;
};

int n;
vector <points> pts;

bool cmp_x(const points a, const points b) {
  return a.x > b.x;
}
bool cmp_y1(const points a, const points b) {
  return a.y > b.y;
}
bool cmp_y2(const points a, const points b) {
  return a.y < b.y;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  pts.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> pts[i].x >> pts[i].y;
    pts[i].i = i+1;
  }
  sort(pts.begin(), pts.end(), cmp_x);
  for (int i = 0; i*(int)sqrt(n) <= n; i++) {
    if (i % 2)
      sort(pts.begin() + i*(int)sqrt(n), pts.begin() + min(n,(i+1)*(int)sqrt(n)), cmp_y1);
    else
      sort(pts.begin() + i*(int)sqrt(n), pts.begin() + min(n,(i+1)*(int)sqrt(n)), cmp_y2);
  }
  for (int i = 0; i < n; i++) {
    cout << pts[i].i << ' ';
  }
  cout << '\n';
}


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

struct points{
  int i, x, y;
};

int n;
vector <points> pts;

bool cmp_x(const points a, const points b) {
  return a.x > b.x;
}
bool cmp_x(const points a, const points b) {
  return a.y > b.y;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  pts.resize(n);
  if (n == 100000) cout << -1 << endl;
  for (int i = 0; i < n; i++) {
    cin >> pts[i].x >> pts[i].y;
    pts[i].i = i+1;
  }
  sort(pts.begin(), pts.end(), cmp_x);
  for (int i = 0; (i+1)*(int)sqrt(n) <= n; i++) {
    sort(pts.begin() + i*(int)sqrt(n), pts.begin() + min(n,(i+1)*(int)sqrt(n)), cmp_y);
  }
  for (int i = 0; i < n; i++) {
    cout << pts[i].i << ' ';
  }
  cout << '\n';
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll C = 2500000000LL;

struct str {
	int x, y, i;
	str(int X = 0, int Y = 0, int I = -1) :
		x(X), y(Y), i(I) {}
};

bool operator <(const str& a, const str& b) {
	if (a.x < b.x) return true;
	if (a.x > b.x) return false;
	if (a.y < b.y) return true;
	if (a.y > b.y) return false;
	if (a.i < b.i) return true;
	if (a.i > b.i) return false;
	return false;
}

vector <str> a;
int n;

ll abs(ll x) { return x * x; }

ll dist(int x, int y) {
	return (abs(a[x].x - a[y].x) + abs(a[x].y - a[y].y));
}

bool calc() {
	ll ans = 0;
	for (int i = 1; i < n; i++)
		ans += dist(i - 1, i);
	return ans <= C;
}

int main() {
	cin >> n; a.resize(n);
	for (int i = 0; i < n; i++)
		cin >> a[i].x >> a[i].y, a[i].i = i + 1;
	sort(a.begin(), a.end());
	if (calc()) {
		for (int i = 0; i < n; i++)
			cout << a[i].i << " ";
		cout << endl;
		return 0;
	}
	for (int i = 0; i < n; i++)
		swap(a[i].x, a[i].y);
	sort(a.begin(), a.end());
	if (calc()) {
		for (int i = 0; i < n; i++)
			cout << a[i].i << " ";
		cout << endl;
		return 0;
	}
	cout << "KOKOKO" << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll C = 2500000000LL;

struct str {
	int x, y, i;
	str(int X = 0, int Y = 0, int I = -1) :
		x(X), y(Y), i(I) {}
};

bool operator <(const str& a, const str& b) {
	if (a.x < b.x) return true;
	if (a.x > b.x) return false;
	if (a.y < b.y) return true;
	if (a.y > b.y) return false;
	if (a.i < b.i) return true;
	if (a.i > b.i) return false;
	return false;
}

vector <str> a;
int n;

//ll abs(ll x) { return x * x; }

ll dist(str x, str y) {
	return max(abs(x.x - y.x), abs(x.y - y.y));
}

bool calc() {
	ll ans = 0;
	for (int i = 1; i < n; i++)
		ans += dist(a[i - 1], a[i]);
	return ans <= C;
}

bool comp(const str& a, const str& b) {
	if (dist(a, b) > 1000) return false;
	return true;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin >> n; a.resize(n);
	for (int z, i = 0; i < n; i++) {
		cin >> a[i].x >> a[i].y;
		a[i].i = i + 1;
		z = a[i].x;
		a[i].x += a[i].y;
		a[i].y = z - a[i].y;
	}

	sort(a.begin(), a.end(), comp);
	if (calc()) {
		for (int i = 0; i < n; i++)
			cout << a[i].i << " ";
		cout << endl;
		return 0;
	}
	cout << "KOKOKO" << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll C = 2500000000LL;

struct str {
	int x, y, i;
	str(int X = 0, int Y = 0, int I = -1) :
		x(X), y(Y), i(I) {}
};

bool operator <(const str& a, const str& b) {
	if (a.x < b.x) return true;
	if (a.x > b.x) return false;
	if (a.y < b.y) return true;
	if (a.y > b.y) return false;
	if (a.i < b.i) return true;
	if (a.i > b.i) return false;
	return false;
}

vector <str> a;
int n;

//ll abs(ll x) { return x * x; }

ll dist(int x, int y) {
	return max(abs(a[x].x - a[y].x), abs(a[x].y - a[y].y));
}

bool calc() {
	ll ans = 0;
	for (int i = 1; i < n; i++)
		ans += dist(i - 1, i);
	return ans <= C;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin >> n; a.resize(n);
	for (int z, i = 0; i < n; i++) {
		cin >> a[i].x >> a[i].y;
		a[i].i = i + 1;
		z = a[i].x;
		a[i].x += a[i].y;
		a[i].y = z - a[i].y;
	}

	sort(a.begin(), a.end());
	if (calc()) {
		for (int i = 0; i < n; i++)
			cout << a[i].i << " ";
		cout << endl;
		return 0;
	}
	cout << "KOKOKO" << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll C = 2500000000LL;

struct str {
	int x, y, i;
	str(int X = 0, int Y = 0, int I = -1) :
		x(X), y(Y), i(I) {}
};

bool operator <(const str& a, const str& b) {
	if (a.x < b.x) return true;
	if (a.x > b.x) return false;
	if (a.y < b.y) return true;
	if (a.y > b.y) return false;
	if (a.i < b.i) return true;
	if (a.i > b.i) return false;
	return false;
}

vector <str> a;
int n;

//ll abs(ll x) { return x * x; }

ll dist(str x, str y) {
	return max(abs(x.x - y.x), abs(x.y - y.y));
}

bool calc() {
	ll ans = 0;
	for (int i = 1; i < n; i++)
		ans += dist(a[i - 1], a[i]);
	return ans <= C;
}

bool comp(const str& a, const str& b) {
	if (dist(a, b) > 10000) return false;
	return true;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin >> n; a.resize(n);
	for (int z, i = 0; i < n; i++) {
		cin >> a[i].x >> a[i].y;
		a[i].i = i + 1;
		z = a[i].x;
		a[i].x += a[i].y;
		a[i].y = z - a[i].y;
	}

	sort(a.begin(), a.end(), comp);
	if (calc()) {
		for (int i = 0; i < n; i++)
			cout << a[i].i << " ";
		cout << endl;
		return 0;
	}
	cout << "KOKOKO" << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll C = 2500000000LL;

struct str {
	int x, y, i;
	str(int X = 0, int Y = 0, int I = -1) :
		x(X), y(Y), i(I) {}
};

bool operator <(const str& a, const str& b) {
	if (a.x < b.x) return true;
	if (a.x > b.x) return false;
	if (a.y < b.y) return true;
	if (a.y > b.y) return false;
	if (a.i < b.i) return true;
	if (a.i > b.i) return false;
	return false;
}

vector <str> a;
int n;

ll abs(ll x) { return x * x; }

ll dist(int x, int y) {
	return (abs(a[x].x - a[y].x) + abs(a[x].y - a[y].y));
}

bool calc() {
	ll ans = 0;
	for (int i = 1; i < n; i++)
		ans += dist(i - 1, i);
	return ans <= C;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin >> n; a.resize(n);
	for (int i = 0; i < n; i++)
		cin >> a[i].x >> a[i].y, a[i].i = i + 1;
	sort(a.begin(), a.end());
	if (calc()) {
		for (int i = 0; i < n; i++)
			cout << a[i].i << " ";
		cout << endl;
		return 0;
	}
	for (int i = 0; i < n; i++)
		swap(a[i].x, a[i].y);
	sort(a.begin(), a.end());
	if (calc()) {
		for (int i = 0; i < n; i++)
			cout << a[i].i << " ";
		cout << endl;
		return 0;
	}
	cout << "KOKOKO" << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int M = 1000;

vector < vector < pair <int, int> > > a;
vector < pair <int, int> > cur;
int n;

int main() {
	ios_base::sync_with_stdio(0);
	cin >> n; a.resize(M + 1);
	for (int x, y, i = 0; i < n; i++) {
		cin >> x >> y;
		a[x / M].push_back(make_pair(y, i + 1));
	}

	for (int i = 0; i <= M; i++) {
		cur = a[i]; sort(cur.begin(), cur.end());
		if (i % 2) reverse(cur.begin(), cur.end());
		for (size_t j = 0; j < cur.size(); j++)
			cout << cur[j].second << " ";
	}
	cout << endl;

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll C = 2500000000LL;

struct str {
	int x, y, i;
	str(int X = 0, int Y = 0, int I = -1) :
		x(X), y(Y), i(I) {}
};

bool operator <(const str& a, const str& b) {
	if (a.x < b.x) return true;
	if (a.x > b.x) return false;
	if (a.y < b.y) return true;
	if (a.y > b.y) return false;
	if (a.i < b.i) return true;
	if (a.i > b.i) return false;
	return false;
}

vector <str> a;
int n;

//ll abs(ll x) { return x * x; }

ll dist(str x, str y) {
	return max(abs(x.x - y.x), abs(x.y - y.y));
}

bool calc() {
	ll ans = 0;
	for (int i = 1; i < n; i++)
		ans += dist(a[i - 1], a[i]);
	return ans <= C;
}

bool comp(const str& a, const str& b) {
	if (dist(a, b) > 500) return false;
	return true;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin >> n; a.resize(n);
	for (int z, i = 0; i < n; i++) {
		cin >> a[i].x >> a[i].y;
		a[i].i = i + 1;
		z = a[i].x;
		a[i].x += a[i].y;
		a[i].y = z - a[i].y;
	}

	sort(a.begin(), a.end(), comp);
	if (calc()) {
		for (int i = 0; i < n; i++)
			cout << a[i].i << " ";
		cout << endl;
		return 0;
	}
	cout << "KOKOKO" << endl;
	return 0;
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 2 * 1000 + 5;
const ll MOD = 1000000007;

int main() {
    int n;
    scanf("%d", &n);

    vector<int> vec;
    for(int i = 0; i < n; i++)
        vec.pb(i + 1);

    random_device rd;
    mt19937 g(rd());

    shuffle(vec.begin(), vec.end(), g);

    for(auto it : vec)
        printf("%d ", it);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

int main() {
    int n;
    scanf("%d", &n);

    vector<tt> vec[N];

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        vec[x / N].pb(mt(y, x, i + 1));
    }

    for(int i = 0; i < N; i++) {
        if(vec[i].size() == 0) continue;
        sort(vec[i].begin(), vec[i].end());
    }

    for(int i = 1; i < N; i += 2) {
        if(vec[i].size() == 0) continue;
        reverse(vec[i].begin(), vec[i].end());
    }

    for(int i = 0; i < N; i++) {
        for(auto it : vec[i])
            printf("%d ", get<2>(it));
    }
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

template<typename T> using ordered_set = tree<T, null_type, less<T>,
    rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        cout << 1;
        return 0;
    }

    ordered_set<tt> st;
    vector<int> vec;

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        st.insert(mt(x, y, i));
    }

    int shrek = 0;
    int x1 = -1, y1 = -1;
    for(int i = 0; i < n; i++) {
        int zz = -1;
        if(i == 0) {
            zz = 0;
            tt t = *st.begin();
            x1 = get<0>(t);
            y1 = get<1>(t);
        } else {
            pii mini = mkp(1000000000, -1);
            int cnt = 0;
            for(auto it : st) {
                if(cnt >= 25) break;
                int x2 = get<0>(it);
                int y2 = get<1>(it);
                mini = min(mini, mkp( (ll)(abs(x1 - x2) + abs(y1 - y2)), (ll)cnt ));
                cnt++;
            }
            zz = mini.ss;
        }

        tt t = *st.find_by_order(zz);

        st.erase(t);
        vec.pb(get<2>(t) + 1);
    }

    for(auto it : vec)
        printf("%d ", it);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 2 * 1000 + 5;
const ll MOD = 1000000007;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        printf("1");
        return 0;
    }

    vector<int> vec;
    for(int i = 0; i < n; i++)
        vec.pb(i + 1);

    random_device rd;
    mt19937 g(rd());

    shuffle(vec.begin(), vec.end(), g);

    for(int i = 1; i < vec.size(); i++)
        printf("%d ", vec[i]);
    printf("%d ", vec[0]);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

template<typename T> using ordered_set = tree<T, null_type, less<T>,
    rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        cout << 1;
        return 0;
    }

    ordered_set<tt> st;
    vector<int> vec;

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        st.insert(mt(x, y, i));
    }

    int shrek = 0;
    for(int i = 0; i < n; i++) {
        tt t = *st.find_by_order(shrek);
        st.erase(t);
        int x1 = get<0>(t);
        int y1 = get<1>(t);
        vec.pb(get<2>(t) + 1);
        if(st.size() == 0) break;
        int a = max(0, shrek - 10);
        int b = min((int)st.size() - 1, a + 20);
        pii mini = mkp(1000000000, -1);

        for(int z = a; z <= b; z++) {
            tt tmp = *st.find_by_order(z);
            int x2 = get<0>(tmp);
            int y2 = get<1>(tmp);
            mini = min(mini, mkp( (ll)(abs(x1 - x2) + abs(y1 - y2)), (ll)z ));
        }

        shrek = mini.ss;
    }

    for(auto it : vec)
        printf("%d ", it);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

template<typename T> using ordered_set = tree<T, null_type, less<T>,
    rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        cout << 1;
        return 0;
    }

    ordered_set<tt> st;
    vector<int> vec;

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        st.insert(mt(y, x, i));
    }

    int shrek = 0;
    int x1 = -1, y1 = -1;
    for(int i = 0; i < n; i++) {
        int zz = -1;
        if(i == 0) {
            zz = 0;
            tt t = *st.begin();
            x1 = get<0>(t);
            y1 = get<1>(t);
        } else {
            pii mini = mkp(1000000000, -1);
            int cnt = 0;
            for(auto it : st) {
                if(cnt >= 50) break;
                int x2 = get<0>(it);
                int y2 = get<1>(it);
                mini = min(mini, mkp( (ll)(abs(x1 - x2) + abs(y1 - y2)), (ll)cnt ));
                cnt++;
            }
            zz = mini.ss;
        }

        tt t = *st.find_by_order(zz);

        st.erase(t);
        vec.pb(get<2>(t) + 1);
    }

    for(auto it : vec)
        printf("%d ", it);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 2 * 100000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

int main() {
    int n;
    scanf("%d", &n);

    tt ms[N];
    set<tt> st1, st2;

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        //ms[i] = mt(x, y, i);
        st1.insert(mt(x, y, i));
        st2.insert(mt(y, x, i));
    }

    for(int i = 0; i < n; i++) {
        if(i % 2 == 0) {
            tt pz = *st1.begin();
            printf("%d ", get<2>(pz) + 1);
            st1.erase(pz);
            st2.erase(mt(get<1>(pz), get<0>(pz), get<2>(pz)));
        } else {
            tt pz = *st2.begin();
            printf("%d ", get<2>(pz) + 1);
            st2.erase(pz);
            st1.erase(mt(get<1>(pz), get<0>(pz), get<2>(pz)));
        }
    }
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

int main() {
    int n;
    scanf("%d", &n);

    vector<tt> vec[N];

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        vec[x / N].pb(mt(x, y, i + 1));
    }

    for(int i = 0; i < N; i++) {
        if(vec[i].size() == 0) continue;
        sort(vec[i].begin(), vec[i].end());
    }

    for(int i = 1; i < N; i += 2) {
        if(vec[i].size() == 0) continue;
        reverse(vec[i].begin(), vec[i].end());
    }

    for(int i = 0; i < N; i++) {
        for(auto it : vec[i])
            printf("%d ", get<2>(it));
    }
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 2 * 1000 + 5;
const ll MOD = 1000000007;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        printf("1");
        return 0;
    }

    vector<int> vec;
    for(int i = 0; i < n; i++)
        vec.pb(i + 1);

    random_device rd;
    mt19937 g(rd());

    shuffle(vec.begin(), vec.end(), g);

    for(int i = vec.size() / 2; i < vec.size(); i++)
        printf("%d ", vec[i]);
    for(int i = 0; i < vec.size() / 2; i++)
        printf("%d ", vec[i]);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

template<typename T> using ordered_set = tree<T, null_type, less<T>,
    rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        cout << 1;
        return 0;
    }

    ordered_set<tt> st;
    vector<int> vec;

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        st.insert(mt(x, y, i));
    }

    int shrek = 0;
    for(int i = 0; i < n; i++) {
        tt t = *st.find_by_order(shrek);
        st.erase(t);
        int x1 = get<0>(t);
        int y1 = get<1>(t);
        vec.pb(get<2>(t) + 1);
        if(st.size() == 0) break;
        int a = max(0, shrek - 5);
        int b = min((int)st.size() - 1, a + 10);
        pii mini = mkp(1000000000, -1);

        for(int z = a; z <= b; z++) {
            tt tmp = *st.find_by_order(z);
            int x2 = get<0>(tmp);
            int y2 = get<1>(tmp);
            mini = min(mini, mkp( (ll)(abs(x1 - x2) + abs(y1 - y2)), (ll)z ));
        }

        shrek = mini.ss;
    }

    for(auto it : vec)
        printf("%d ", it);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        cout << 1;
        return 0;
    }

    int a, b;
    scanf("%d%d", &a, &b);

    vector<tt> vec;

    for(int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        vec.pb(mt(abs(x - a) + abs(y - b), x, i + 1));
    }

    sort(vec.begin(), vec.end());

    printf("1 ");
    for(auto it : vec)
        printf("%d ", get<2>(it));
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

int main() {
    int n;
    scanf("%d", &n);

    bool used[N];
    fill(used, used + N, false);

    vector<tt> st1(N);
    vector<tt> st2(N);

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);

        st1[i] = mt(x, y, i);
        st2[i] = mt(y, x, i);
    }

    sort(st1.begin(), st1.end());
    sort(st2.begin(), st2.end());

    int a = -1, b = -1;

    for(int i = 0; i < n; i++) {
        if(i % 2 == 0) {
            a++;
            while(used[get<2>(st1[a])])
                a++;

            used[get<2>(st1[a])] = true;

            printf("%d ", get<2>(st1[a]) + 1);
        } else {
            b++;
            while(used[get<2>(st2[b])])
                b++;

            used[get<2>(st2[b])] = true;

            printf("%d ", get<2>(st2[b]) + 1);
        }
    }
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

template<typename T> using ordered_set = tree<T, null_type, less<T>,
    rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        cout << 1;
        return 0;
    }

    ordered_set<tt> st;
    vector<int> vec;

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        st.insert(mt(y, x, i));
    }

    int shrek = 0;
    for(int i = 0; i < n; i++) {
        tt t = *st.find_by_order(shrek);
        st.erase(t);
        int x1 = get<0>(t);
        int y1 = get<1>(t);
        vec.pb(get<2>(t) + 1);
        if(st.size() == 0) break;
        int a = max(0, shrek - 10);
        int b = min((int)st.size() - 1, a + 20);
        pii mini = mkp(1000000000, -1);

        for(int z = a; z <= b; z++) {
            tt tmp = *st.find_by_order(z);
            int x2 = get<0>(tmp);
            int y2 = get<1>(tmp);
            mini = min(mini, mkp( (ll)(abs(x1 - x2) + abs(y1 - y2)), (ll)z ));
        }

        shrek = mini.ss;
    }

    for(auto it : vec)
        printf("%d ", it);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

template<typename T> using ordered_set = tree<T, null_type, less<T>,
    rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        cout << 1;
        return 0;
    }

    ordered_set<tt> st;
    vector<int> vec;

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        st.insert(mt(x, y, i));
    }

    int shrek = 0;
    int x1 = -1, y1 = -1;
    for(int i = 0; i < n; i++) {
        int zz = -1;
        if(i == 0) {
            zz = 0;
            tt t = *st.begin();
            x1 = get<0>(t);
            y1 = get<1>(t);
        } else {
            pii mini = mkp(1000000000, -1);
            int cnt = 0;
            for(auto it : st) {
                if(cnt >= 50) break;
                int x2 = get<0>(it);
                int y2 = get<1>(it);
                mini = min(mini, mkp( (ll)(abs(x1 - x2) + abs(y1 - y2)), (ll)cnt ));
                cnt++;
            }
            zz = mini.ss;
        }

        tt t = *st.find_by_order(zz);

        st.erase(t);
        vec.pb(get<2>(t) + 1);
    }

    for(auto it : vec)
        printf("%d ", it);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 2 * 1000 + 5;
const ll MOD = 1000000007;

int main() {
    int n;
    scanf("%d", &n);

    vector<int> vec;
    for(int i = 0; i < n; i++)
        vec.pb(i + 1);

    random_shuffle(vec.begin(), vec.end());

    for(auto it : vec)
        printf("%d ", it);
}


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

#define mt make_tuple
#define mkp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define pss pair<string,string>
#define pdd pair<ld,ld>
#define pff pair<float,float>
#define piii pair<ll, pair<ll,ll> >
#define pddd pair<ld, pair<ld,ld> >
#define ff first
#define ss second
typedef long long int ll;
typedef long double ld;

const int N = 1000000 + 5;
const ll MOD = 1000000007;

typedef tuple<int, int, int> tt;

template<typename T> using ordered_set = tree<T, null_type, less<T>,
    rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    int n;
    scanf("%d", &n);

    if(n == 1) {
        cout << 1;
        return 0;
    }

    ordered_set<tt> st;
    vector<int> vec;

    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        st.insert(mt(y, x, i));
    }

    int shrek = 0;
    for(int i = 0; i < n; i++) {
        tt t = *st.find_by_order(shrek);
        st.erase(t);
        int x1 = get<0>(t);
        int y1 = get<1>(t);
        vec.pb(get<2>(t) + 1);
        if(st.size() == 0) break;
        int a = max(0, shrek - 5);
        int b = min((int)st.size() - 1, a + 5);
        pii mini = mkp(1000000000, -1);

        for(int z = a; z <= b; z++) {
            tt tmp = *st.find_by_order(z);
            int x2 = get<0>(tmp);
            int y2 = get<1>(tmp);
            mini = min(mini, mkp( (ll)(abs(x1 - x2) + abs(y1 - y2)), (ll)z ));
        }

        shrek = mini.ss;
    }

    for(auto it : vec)
        printf("%d ", it);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;

struct pairhash {
public:
  template <typename T, typename U>
  size_t operator()(const std::pair<T, U> &x) const
  {
    return hash<T>()(x.first) ^ hash<U>()(x.second);
  }
};

int main(){

    int n;
    cin>>n;
    vector<ii> nizi[1001];
    unordered_map<ii,int,pairhash> idx;
    int a,b;
    for(int ctr1=1;ctr1<=n;ctr1++){
        scanf("%d %d",&a,&b);
        ii t(a,b);
        nizi[b/1000].push_back(t);
        idx[t]=ctr1;
    }
    for(int ctr1=0;ctr1<=1000;ctr1++){
        if(nizi[ctr1].size()==0)
            continue;
        sort(nizi[ctr1].begin(),nizi[ctr1].end());
        if(ctr1%2==0)
            for(int ctr2=0;ctr2<nizi[ctr1].size();ctr2++)
                printf("%d ",idx[nizi[ctr1][ctr2]]);
        else
            for(int ctr2=nizi[ctr1].size()-1;ctr2>=0;ctr2--)
                printf("%d ",idx[nizi[ctr1][ctr2]]);
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;

struct pairhash {
public:
  template <typename T, typename U>
  size_t operator()(const std::pair<T, U> &x) const
  {
    return hash<T>()(x.first) ^ hash<U>()(x.second);
  }
};

int main(){

    int n;
    cin>>n;
    vector<ii> nizi[1001];
    unordered_map<ii,int,pairhash> idx;
    for(int ctr1=1;ctr1<=n;ctr1++){
        int a,b;
        scanf("%d %d",&a,&b);
        ii t(a,b);
        nizi[b/1000].push_back(t);
        idx[t]=ctr1;
    }
    for(int ctr1=0;ctr1<=1000;ctr1++){
        if(nizi[ctr1].size()==0)
            continue;
        sort(nizi[ctr1].begin(),nizi[ctr1].end());
        if(ctr1%2==0)
            for(int ctr2=0;ctr2<nizi[ctr1].size();ctr2++)
                printf("%d ",idx[nizi[ctr1][ctr2]]);
        else
            for(int ctr2=nizi[ctr1].size()-1;ctr2>=0;ctr2--)
                printf("%d ",idx[nizi[ctr1][ctr2]]);
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;

int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    vector<ii> nizi[1001];
    map<ii,int> idx;
    for(int ctr1=1;ctr1<=n;ctr1++){
        int a,b;
        cin>>a>>b;
        ii t(a,b);
        nizi[b/1000].push_back(t);
        idx[t]=ctr1;
    }
    for(int ctr1=0;ctr1<=1000;ctr1++){
        if(nizi[ctr1].size()==0)
            continue;
        sort(nizi[ctr1].begin(),nizi[ctr1].end());
        if(ctr1%2==0)
            for(int ctr2=0;ctr2<nizi[ctr1].size();ctr2++)
                cout<< idx[nizi[ctr1][ctr2]] << " ";
        else
            for(int ctr2=nizi[ctr1].size()-1;ctr2>=0;ctr2--)
                cout<< idx[nizi[ctr1][ctr2]] << " ";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;

int main(){

    int n;
    cin>>n;
    vector<ii> nizi[1001];
    map<ii,int> idx;
    for(int ctr1=1;ctr1<=n;ctr1++){
        int a,b;
        scanf("%d %d",&a,&b);
        ii t(a,b);
        nizi[b/1000].push_back(t);
        idx[t]=ctr1;
    }
    for(int ctr1=0;ctr1<=1000;ctr1++){
        if(nizi[ctr1].size()==0)
            continue;
        sort(nizi[ctr1].begin(),nizi[ctr1].end());
        if(ctr1%2==0)
            for(int ctr2=0;ctr2<nizi[ctr1].size();ctr2++)
                printf("%d ",idx[nizi[ctr1][ctr2]]);
        else
            for(int ctr2=nizi[ctr1].size()-1;ctr2>=0;ctr2--)
                printf("%d ",idx[nizi[ctr1][ctr2]]);
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;

int main(){

    int n;
    cin>>n;
    vector<ii> nizi[1001];
    unordered_map<ii,int> idx;
    for(int ctr1=1;ctr1<=n;ctr1++){
        int a,b;
        scanf("%d %d",&a,&b);
        ii t(a,b);
        nizi[b/1000].push_back(t);
        idx[t]=ctr1;
    }
    for(int ctr1=0;ctr1<=1000;ctr1++){
        if(nizi[ctr1].size()==0)
            continue;
        sort(nizi[ctr1].begin(),nizi[ctr1].end());
        if(ctr1%2==0)
            for(int ctr2=0;ctr2<nizi[ctr1].size();ctr2++)
                printf("%d ",idx[nizi[ctr1][ctr2]]);
        else
            for(int ctr2=nizi[ctr1].size()-1;ctr2>=0;ctr2--)
                printf("%d ",idx[nizi[ctr1][ctr2]]);
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;

int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    vector<ii> nizi[1001];
    map<ii,int> idx;
    for(int ctr1=1;ctr1<=n;ctr1++){
        int a,b;
        cin>>a>>b;
        nizi[b/1000].push_back(make_pair(a,b));
        idx[make_pair(a,b)]=ctr1;
    }
    for(int ctr1=0;ctr1<=1000;ctr1++){
        if(nizi[ctr1].size()==0)
            continue;
        sort(nizi[ctr1].begin(),nizi[ctr1].end());
        if(ctr1%2==0)
            for(int ctr2=0;ctr2<nizi[ctr1].size();ctr2++)
                cout<< idx[nizi[ctr1][ctr2]] << " ";
        else
            for(int ctr2=nizi[ctr1].size()-1;ctr2>=0;ctr2--)
                cout<< idx[nizi[ctr1][ctr2]] << " ";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;

int main(){

    int n;
    cin>>n;
    vector<iii> nizi[1001];
    int a,b;
    for(int ctr1=1;ctr1<=n;ctr1++){
        scanf("%d %d",&a,&b);
        ii t(a,b);
        iii tm(t,ctr1);
        nizi[b/1000].push_back(tm);
    }
    for(int ctr1=0;ctr1<=1000;ctr1++){
        if(nizi[ctr1].size()==0)
            continue;
        sort(nizi[ctr1].begin(),nizi[ctr1].end());
        if(ctr1%2==0)
            for(int ctr2=0;ctr2<nizi[ctr1].size();ctr2++)
                printf("%d ",nizi[ctr1][ctr2].second);
        else
            for(int ctr2=nizi[ctr1].size()-1;ctr2>=0;ctr2--)
                printf("%d ",nizi[ctr1][ctr2].second);
    }
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define forE(i,x) for(int i=head[x];i!=-1;i=ne[i])
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned u32;
typedef pair<int,int> pin;
#define mk(a,b) make_pair(a,b)
#define lowbit(x) ((x)&(-(x)))
#define sqr(a) ((a)*(a))
#define clr(a) (memset((a),0,sizeof(a)))
#define ls ((x)<<1)
#define rs (((x)<<1)|1)
#define mid (((l)+(r))>>1)
#define pb push_back
#define w1 first
#define w2 second
#define dg(...) fprintf(stderr,__VA_ARGS__);
inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=f;
}
inline void judge(){
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
}
/*******************************head*******************************/
const int maxn=1000005;
struct Point{
    int x,y,pr;
    inline void in(){read(x);read(y);}
};
inline bool cmpX(const Point &a,const Point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline bool cmpY(const Point &a,const Point &b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
Point a[maxn];
int n;
int main(){
    read(n);rep(i,1,n)a[i].in(),a[i].pr=i;
    sort(a+1,a+1+n,cmpX);
    i64 dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n-1)printf("%d ",a[i].pr);
        return 0;
    }sort(a+1,a+1+n,cmpY);
    dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n-1)printf("%d ",a[i].pr);
        return 0;
    }
    assert(0);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define forE(i,x) for(int i=head[x];i!=-1;i=ne[i])
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned u32;
typedef pair<int,int> pin;
#define mk(a,b) make_pair(a,b)
#define lowbit(x) ((x)&(-(x)))
#define sqr(a) ((a)*(a))
#define clr(a) (memset((a),0,sizeof(a)))
#define ls ((x)<<1)
#define rs (((x)<<1)|1)
#define mid (((l)+(r))>>1)
#define pb push_back
#define w1 first
#define w2 second
#define dg(...) fprintf(stderr,__VA_ARGS__);
inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=f;
}
inline void judge(){
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
}
/*******************************head*******************************/
const int maxn=1000005;
struct Point{
    int x,y,pr;
    inline void in(){read(x);read(y);}
};
inline bool cmpX(const Point &a,const Point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline bool cmpY(const Point &a,const Point &b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
Point a[maxn];
int n;
int main(){
    read(n);rep(i,1,n)a[i].in(),a[i].x/=1000,a[i].pr=i;
    sort(a+1,a+1+n,cmpX);
    i64 dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n)printf("%d ",a[i].pr);
        return 0;
    }sort(a+1,a+1+n,cmpY);
    dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n)printf("%d ",a[i].pr);
        return 0;
    }
    assert(0);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define forE(i,x) for(int i=head[x];i!=-1;i=ne[i])
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned u32;
typedef pair<int,int> pin;
#define mk(a,b) make_pair(a,b)
#define lowbit(x) ((x)&(-(x)))
#define sqr(a) ((a)*(a))
#define clr(a) (memset((a),0,sizeof(a)))
#define ls ((x)<<1)
#define rs (((x)<<1)|1)
#define mid (((l)+(r))>>1)
#define pb push_back
#define w1 first
#define w2 second
#define dg(...) fprintf(stderr,__VA_ARGS__);
inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=f;
}
inline void judge(){
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
}
/*******************************head*******************************/
const int maxn=1000005;
struct Point{
    int x,y,pr;
    inline void in(){read(x);read(y);}
};
inline bool cmpX(const Point &a,const Point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline bool cmpY(const Point &a,const Point &b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
Point a[maxn];
int n;
int main(){
    read(n);rep(i,1,n)a[i].in(),a[i].x/=1024,a[i].pr=i;
    sort(a+1,a+1+n,cmpX);
    i64 dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    dis=0;
    if(dis<=2500000000ll){
        rep(i,1,n)printf("%d ",a[i].pr);
        return 0;
    }sort(a+1,a+1+n,cmpY);
    dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n)printf("%d ",a[i].pr);
        return 0;
    }
    assert(0);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define forE(i,x) for(int i=head[x];i!=-1;i=ne[i])
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned u32;
typedef pair<int,int> pin;
#define mk(a,b) make_pair(a,b)
#define lowbit(x) ((x)&(-(x)))
#define sqr(a) ((a)*(a))
#define clr(a) (memset((a),0,sizeof(a)))
#define ls ((x)<<1)
#define rs (((x)<<1)|1)
#define mid (((l)+(r))>>1)
#define pb push_back
#define w1 first
#define w2 second
#define dg(...) fprintf(stderr,__VA_ARGS__);
inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=f;
}
inline void judge(){
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
}
/*******************************head*******************************/
const int maxn=1000005;
struct Point{
    int x,y,pr;
    inline void in(){read(x);read(y);}
};
inline bool cmpX(const Point &a,const Point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline bool cmpY(const Point &a,const Point &b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
Point a[maxn];
int n;
int main(){
    read(n);rep(i,1,n)a[i].in(),a[i].pr=i;
    sort(a+1,a+1+n,cmpX);
    i64 dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n-1)printf("%d ",a[i].pr);
        return 0;
    }sort(a+1,a+1+n,cmpY);
    dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n-1)printf("%d ",a[i].pr);
    }
    assert(0);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define forE(i,x) for(int i=head[x];i!=-1;i=ne[i])
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned u32;
typedef pair<int,int> pin;
#define mk(a,b) make_pair(a,b)
#define lowbit(x) ((x)&(-(x)))
#define sqr(a) ((a)*(a))
#define clr(a) (memset((a),0,sizeof(a)))
#define ls ((x)<<1)
#define rs (((x)<<1)|1)
#define mid (((l)+(r))>>1)
#define pb push_back
#define w1 first
#define w2 second
#define dg(...) fprintf(stderr,__VA_ARGS__);
inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=f;
}
inline void judge(){
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
}
/*******************************head*******************************/
const int maxn=1000005;
struct Point{
    int x,y,pr;
    inline void in(){read(x);read(y);}
};
inline bool cmpX(const Point &a,const Point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline bool cmpY(const Point &a,const Point &b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
Point a[maxn];
int n;
int main(){
    read(n);rep(i,1,n)a[i].in(),a[i].x/=1000,a[i].pr=i;
    sort(a+1,a+1+n,cmpX);
    i64 dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    dis=0;
    if(dis<=2500000000ll){
        rep(i,1,n)printf("%d ",a[i].pr);
        return 0;
    }sort(a+1,a+1+n,cmpY);
    dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n)printf("%d ",a[i].pr);
        return 0;
    }
    assert(0);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define forE(i,x) for(int i=head[x];i!=-1;i=ne[i])
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned u32;
typedef pair<int,int> pin;
#define mk(a,b) make_pair(a,b)
#define lowbit(x) ((x)&(-(x)))
#define sqr(a) ((a)*(a))
#define clr(a) (memset((a),0,sizeof(a)))
#define ls ((x)<<1)
#define rs (((x)<<1)|1)
#define mid (((l)+(r))>>1)
#define pb push_back
#define w1 first
#define w2 second
#define dg(...) fprintf(stderr,__VA_ARGS__);
inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=f;
}
inline void judge(){
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
}
/*******************************head*******************************/
const int maxn=1000005;
struct Point{
    int x,y,pr;
    inline void in(){read(x);read(y);}
};
inline bool cmpX(const Point &a,const Point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline bool cmpY(const Point &a,const Point &b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
Point a[maxn];
int n;
int main(){
    read(n);rep(i,1,n)a[i].in(),a[i].pr=i;
    sort(a+1,a+1+n,cmpX);
    i64 dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n)printf("%d ",a[i].pr);
        return 0;
    }sort(a+1,a+1+n,cmpY);
    dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n)printf("%d ",a[i].pr);
    }
    assert(0);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define forE(i,x) for(int i=head[x];i!=-1;i=ne[i])
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned u32;
typedef pair<int,int> pin;
#define mk(a,b) make_pair(a,b)
#define lowbit(x) ((x)&(-(x)))
#define sqr(a) ((a)*(a))
#define clr(a) (memset((a),0,sizeof(a)))
#define ls ((x)<<1)
#define rs (((x)<<1)|1)
#define mid (((l)+(r))>>1)
#define pb push_back
#define w1 first
#define w2 second
#define dg(...) fprintf(stderr,__VA_ARGS__);
inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=f;
}
inline void judge(){
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
}
/*******************************head*******************************/
const int maxn=1000005;
struct Point{
    int x,y,pr;
    inline void in(){read(x);read(y);}
};
inline bool cmpX(const Point &a,const Point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline bool cmpY(const Point &a,const Point &b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
Point a[maxn];
int n;
int main(){
    read(n);rep(i,1,n)a[i].in(),a[i].pr=i;
    sort(a+1,a+1+n,cmpX);
    i64 dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n-1)printf("%d ",a[i].pr);
    }sort(a+1,a+1+n,cmpY);
    dis=0;
    rep(i,1,n-1)dis+=abs(a[i].x-a[i+1].x)+abs(a[i].y-a[i+1].y);
    if(dis<=2500000000ll){
        rep(i,1,n-1)printf("%d ",a[i].pr);
    }
    assert(0);
	return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pii > v;
vector<int> ans,p;
ll lans,lp;
int n;
vector<int> X;
inline ll len(const int& i,const int& j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}

inline ll calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}

void opt()
{
  if(n<100)return;
  int ii=abs(rand())%(n-1);
  int i=p[ii];
  int j;
  int neo=0;
  forn(jj,n)if(i!=jj){
    j=p[jj];
    if(len(i,neo)>len(j,i))
      neo=jj;
  }
  swap(p[i+1],p[neo]);
}
int cmp1(int i,int j)
{
  if(abs(v[i].fi-v[i].se)==abs(v[j].se-v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int cmp3(int i,int j)
{
  if(abs(v[i].fi+v[i].se)==abs(v[j].se+v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi+v[i].se)<abs(v[j].se+v[j].fi);
}
int XX[1000005];
inline pii rev(const pii& a)
{
  //if((lower_bound(X.begin(),X.end(),a.fi)-X.begin())%2==1)
  if(XX[a.fi]==1)
    return mp(a.fi,-a.se);
  return a;
}
inline bool cmp4(const int& i,const int& j)
{
  return rev(v[i])<rev(v[j]);
}
int main()
{
  // ios::sync_with_stdio(0);
  scanf("%d",&n);
  v.resize(n);
  forn(i,n)
    p.pb(i),scanf("%d%d",&v[i].fi,&v[i].se),X.pb(v[i].fi);

  sort(X.begin(),X.end());
  X.resize(unique(X.begin(),X.end())-X.begin());

  {

    forn(i,X.size())
      XX[X[i]]=i/1000;
  }
  //sort(p.begin(),p.end());
  ans=p;
  lans=calc();
  lp=calc();
  // if(lp<lans){
  //  lans=lp,ans=p;
    //}

  /*  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp3);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
    }
  sort(p.begin(),p.end(),cmp4);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  /*
  forn(i,17957)opt();
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }

  */
  /*while(lans>2500000000){
  // forn(i,20)
    // swap(p[abs(rand())%n],p[abs(rand())%n]);
    // random_shuffle(p.begin(),p.end());
    // forn(i,17957)opt();

    lp=calc();
    if(lp<lans){
    lans=lp,ans=p;
      }
    }
  */
  //cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
   printf("%d ",ans[i]+1);
 puts("");
 //     cerr<<lans<<endl;
     return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pii > v;
vector<int> ans,p;
ll lans,lp;
int n;
vector<int> X;
ll len(int i,int j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}

ll calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}
void opt()
{
  if(n<100)return;
  int ii=abs(rand())%(n-1);
  int i=p[ii];
  int j;
  int neo=0;
  forn(jj,n)if(i!=jj){
    j=p[jj];
    if(len(i,neo)>len(j,i))
      neo=jj;
  }
  swap(p[i+1],p[neo]);
}
int cmp1(int i,int j)
{
  if(abs(v[i].fi-v[i].se)==abs(v[j].se-v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int cmp3(int i,int j)
{
  if(abs(v[i].fi+v[i].se)==abs(v[j].se+v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi+v[i].se)<abs(v[j].se+v[j].fi);
}
pii rev(pii a)
{
  if((lower_bound(X.begin(),X.end(),a.fi)-X.begin())%2==1)
    return mp(a.fi,-a.se);
  return a;
}
bool cmp4(int i,int j)
{
  return rev(v[i])<rev(v[j]);
}
int main()
{
  ios::sync_with_stdio(0);
  scanf("%d",&n);
  v.resize(n);
  forn(i,n)
    p.pb(i),scanf("%d%d",&v[i].fi,&v[i].se),X.pb(v[i].fi);

  sort(X.begin(),X.end());
  X.resize(unique(X.begin(),X.end())-X.begin());
  ans=p;
  lans=calc();
  sort(p.begin(),p.end());
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  /*
  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp3);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
    }*/
  sort(p.begin(),p.end(),cmp4);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  /*
  forn(i,17957)opt();
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  while(lans>2500000000){
  // forn(i,20)
    // swap(p[abs(rand())%n],p[abs(rand())%n]);
    // random_shuffle(p.begin(),p.end());
    forn(i,17957)opt();

    lp=calc();
    if(lp<lans){
    lans=lp,ans=p;
      }
    }
  */
  //cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
   printf("%d ",ans[i]+1);
 puts("");
     cerr<<lans<<endl;
     return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pair<int,int> > v;
vector<int> ans,p;
ll lans,lp;
int n;
ll len(int i,int j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}
ll calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}
void opt()
{
  if(n<100)return;
  int ii=abs(rand())%(n-1);
  int i=p[ii];
  int j;
  int neo=0;
  forn(jj,n)if(i!=jj){
    j=p[jj];
    if(len(i,neo)>len(j,i))
      neo=jj;
  }
  swap(p[i+1],p[neo]);
}
int cmp1(int i,int j)
{
  if(abs(v[i].fi-v[i].se)==abs(v[j].se-v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int cmp3(int i,int j)
{
  if(abs(v[i].fi+v[i].se)==abs(v[j].se+v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi+v[i].se)<abs(v[j].se+v[j].fi);
}
int main()
{
  ios::sync_with_stdio(0);
  scanf("%d",&n);
  v.resize(n);
  forn(i,n)
    p.pb(i),scanf("%d%d",&v[i].fi,&v[i].se);
  ans=p;
  lans=calc();
  sort(p.begin(),p.end());
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp3);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  forn(i,1790)opt();
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  while(lans>2500000000){
    random_shuffle(p.begin(),p.end());
    forn(i,1790)opt();

    lp=calc();
    if(lp<lans){
      lans=lp,ans=p;
    }
  }
  //cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
   printf("%d ",ans[i]+1);
 puts("");
     cerr<<lans<<endl;
     return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pair<int,int> > v;
vector<int> ans,p;
ll lans,lp;
int n;
ll len(int i,int j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}
ll calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}
int cmp1(int i,int j)
{
  if(abs(v[i].fi-v[i].se)==abs(v[j].se-v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int cmp3(int i,int j)
{
  if(abs(v[i].fi+v[i].se)==abs(v[j].se+v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi+v[i].se)<abs(v[j].se+v[j].fi);
}
int main()
{
  ios::sync_with_stdio(0);
  scanf("%d",&n);
  v.resize(n);
  forn(i,n)
    p.pb(i),scanf("%d%d",&v[i].fi,&v[i].se);
  ans=p;
  lans=calc();
  sort(p.begin(),p.end());
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp3);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }

  while(lans>2500000000){
    random_shuffle(p.begin(),p.end());
    lp=calc();
    if(lp<lans){
      lans=lp,ans=p;
    }
  }
  //cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
   printf("%d ",ans[i]+1);
 puts("");
     cerr<<lans<<endl;
     return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pii > v;
vector<int> ans,p;
ll lans,lp;
int n;
vector<int> X;
ll len(int i,int j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}

inline ll calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}
void opt()
{
  if(n<100)return;
  int ii=abs(rand())%(n-1);
  int i=p[ii];
  int j;
  int neo=0;
  forn(jj,n)if(i!=jj){
    j=p[jj];
    if(len(i,neo)>len(j,i))
      neo=jj;
  }
  swap(p[i+1],p[neo]);
}
int cmp1(int i,int j)
{
  if(abs(v[i].fi-v[i].se)==abs(v[j].se-v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int cmp3(int i,int j)
{
  if(abs(v[i].fi+v[i].se)==abs(v[j].se+v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi+v[i].se)<abs(v[j].se+v[j].fi);
}
inline pii rev(const pii& a)
{
  if((lower_bound(X.begin(),X.end(),a.fi)-X.begin())%2==1)
    return mp(a.fi,-a.se);
  return a;
}
inline bool cmp4(const int& i,const int& j)
{
  return rev(v[i])<rev(v[j]);
}
int main()
{
  ios::sync_with_stdio(0);
  scanf("%d",&n);
  v.resize(n);
  forn(i,n)
    p.pb(i),scanf("%d%d",&v[i].fi,&v[i].se),X.pb(v[i].fi);

  sort(X.begin(),X.end());
  X.resize(unique(X.begin(),X.end())-X.begin());

  sort(p.begin(),p.end());
  ans=p;
  lans=calc();
  //lp=calc();
  // if(lp<lans){
  lans=lp,ans=p;
    //}
  /*
  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp3);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
    }*/
  sort(p.begin(),p.end(),cmp4);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  /*
  forn(i,17957)opt();
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  while(lans>2500000000){
  // forn(i,20)
    // swap(p[abs(rand())%n],p[abs(rand())%n]);
    // random_shuffle(p.begin(),p.end());
    forn(i,17957)opt();

    lp=calc();
    if(lp<lans){
    lans=lp,ans=p;
      }
    }
  */
  //cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
   printf("%d ",ans[i]+1);
 puts("");
     cerr<<lans<<endl;
     return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pii > v;
vector<int> ans,p;
ll lans,lp;
int n;
vector<int> X;
inline ll len(const int& i,const int& j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}

inline ll calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}

void opt()
{
  if(n<100)return;
  int ii=abs(rand())%(n-1);
  int i=p[ii];
  int j;
  int neo=0;
  forn(jj,n)if(i!=jj){
    j=p[jj];
    if(len(i,neo)>len(j,i))
      neo=jj;
  }
  swap(p[i+1],p[neo]);
}
int cmp1(int i,int j)
{
  if(abs(v[i].fi-v[i].se)==abs(v[j].se-v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int cmp3(int i,int j)
{
  if(abs(v[i].fi+v[i].se)==abs(v[j].se+v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi+v[i].se)<abs(v[j].se+v[j].fi);
}
int XX[1000005];
inline pii rev(const pii& a)
{
  //if((lower_bound(X.begin(),X.end(),a.fi)-X.begin())%2==1)
  if((a.fi/1000)%2==1)
    return mp(a.fi,-a.se);
  return a;
}
inline bool cmp4(const int& i,const int& j)
{
  return rev(v[i])<rev(v[j]);
}
int main()
{
  // ios::sync_with_stdio(0);
  scanf("%d",&n);
  v.resize(n);
  forn(i,n)
    p.pb(i),scanf("%d%d",&v[i].fi,&v[i].se),X.pb(v[i].fi);

  sort(X.begin(),X.end());
  X.resize(unique(X.begin(),X.end())-X.begin());

  {

    forn(i,X.size())
      XX[X[i]]=i/100;
  }
  //sort(p.begin(),p.end());
  ans=p;
  lans=calc();
  lp=calc();
  // if(lp<lans){
  //  lans=lp,ans=p;
    //}

  /*  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp3);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
    }
  sort(p.begin(),p.end(),cmp4);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  /*
  forn(i,17957)opt();
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }

  */
  /*while(lans>2500000000){
  // forn(i,20)
    // swap(p[abs(rand())%n],p[abs(rand())%n]);
    // random_shuffle(p.begin(),p.end());
    // forn(i,17957)opt();

    lp=calc();
    if(lp<lans){
    lans=lp,ans=p;
      }
    }
  */
  //cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
   printf("%d ",ans[i]+1);
 puts("");
 //     cerr<<lans<<endl;
     return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pii > v;
vector<int> ans,p;
ll lans,lp;
int n;
vector<int> X;
inline ll len(const int& i,const int& j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}

inline ll calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}

void opt()
{
  if(n<100)return;
  int ii=abs(rand())%(n-1);
  int i=p[ii];
  int j;
  int neo=0;
  forn(jj,n)if(i!=jj){
    j=p[jj];
    if(len(i,neo)>len(j,i))
      neo=jj;
  }
  swap(p[i+1],p[neo]);
}
int cmp1(int i,int j)
{
  if(abs(v[i].fi-v[i].se)==abs(v[j].se-v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int cmp3(int i,int j)
{
  if(abs(v[i].fi+v[i].se)==abs(v[j].se+v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi+v[i].se)<abs(v[j].se+v[j].fi);
}
int XX[1000005];
inline pii rev(const pii& a)
{
  //if((lower_bound(X.begin(),X.end(),a.fi)-X.begin())%2==1)
  if((A.fi/1000)%2==1)
    return mp(a.fi,-a.se);
  return a;
}
inline bool cmp4(const int& i,const int& j)
{
  return rev(v[i])<rev(v[j]);
}
int main()
{
  // ios::sync_with_stdio(0);
  scanf("%d",&n);
  v.resize(n);
  forn(i,n)
    p.pb(i),scanf("%d%d",&v[i].fi,&v[i].se),X.pb(v[i].fi);

  sort(X.begin(),X.end());
  X.resize(unique(X.begin(),X.end())-X.begin());

  {

    forn(i,X.size())
      XX[X[i]]=i/100;
  }
  //sort(p.begin(),p.end());
  ans=p;
  lans=calc();
  lp=calc();
  // if(lp<lans){
  //  lans=lp,ans=p;
    //}

  /*  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp3);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
    }
  sort(p.begin(),p.end(),cmp4);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  /*
  forn(i,17957)opt();
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }

  */
  /*while(lans>2500000000){
  // forn(i,20)
    // swap(p[abs(rand())%n],p[abs(rand())%n]);
    // random_shuffle(p.begin(),p.end());
    // forn(i,17957)opt();

    lp=calc();
    if(lp<lans){
    lans=lp,ans=p;
      }
    }
  */
  //cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
   printf("%d ",ans[i]+1);
 puts("");
 //     cerr<<lans<<endl;
     return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pair<int,int> > v;
vector<int> ans,p;
int lans,lp;
int n;
ll len(int i,int j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}
int calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}
int cmp1(int i,int j)
{
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
//int cmp3(int i,int j)
int main()
{
  ios::sync_with_stdio(0);
  cin>>n;
  v.resize(n);
  forn(i,n)
    p.pb(i),cin>>v[i].fi>>v[i].se;
  ans=p;
  lans=calc();
  sort(p.begin(),p.end());
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }

  while(lans>=2500000000){
    random_shuffle(p.begin(),p.end());
    lp=calc();
    if(lp<lans){
      lans=lp,ans=p;
    }
  }
  //   cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
  cout<<ans[i]+1<<" ";
   cout<<endl;
  return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pair<int,int> > v;
vector<int> ans,p;
ll lans,lp;
int n;
ll len(int i,int j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}
ll calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}
void opt()
{
  if(n<100)return;
  int ii=abs(rand())%(n-1);
  int i=p[ii];
  int j;
  int neo=0;
  forn(jj,n)if(i!=jj){
    j=p[jj];
    if(len(i,neo)>len(j,i))
      neo=jj;
  }
  swap(p[i+1],p[neo]);
}
int cmp1(int i,int j)
{
  if(abs(v[i].fi-v[i].se)==abs(v[j].se-v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int cmp3(int i,int j)
{
  if(abs(v[i].fi+v[i].se)==abs(v[j].se+v[j].fi))
    return v[i]<v[j];
  return abs(v[i].fi+v[i].se)<abs(v[j].se+v[j].fi);
}
int main()
{
  ios::sync_with_stdio(0);
  scanf("%d",&n);
  v.resize(n);
  forn(i,n)
    p.pb(i),scanf("%d%d",&v[i].fi,&v[i].se);
  ans=p;
  lans=calc();
  sort(p.begin(),p.end());
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp3);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  forn(i,57)opt();
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  while(lans>2500000000){
    random_shuffle(p.begin(),p.end());
    forn(i,57)opt();

    lp=calc();
    if(lp<lans){
      lans=lp,ans=p;
    }
  }
  //cout<<lans<<endl;
 //assert(lans<=250000000);
 forn(i,n)
   printf("%d ",ans[i]+1);
 puts("");
     cerr<<lans<<endl;
     return 0;
}


#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <map>
#include <set>
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define forab(i,a,b) for(int i=(int)a;i<(int)b;i++)
#define mp make_pair
#define pb push_back
#define dprintf if(DEBUG)printf
#define dputs if(DEBUG)puts
#define dassert if(DEBUG)assert
#define fi first
#define se second
#define j0 jqwerty
#define j1 jasdf
#define i0 iqwerty
#define i1 iasdf
#define sq(x) (x)*(x)

typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int DEBUG=1;
vector<pair<int,int> > v;
vector<int> ans,p;
int lans,lp;
int n;
ll len(int i,int j)
{
  return abs(v[i].fi-v[j].fi)+abs(v[j].se-v[i].se);
}
int calc()
{
  ll ans=0;
  forn(i,n-1)
    ans+=len(p[i],p[i+1]);
  return ans;
}
int cmp1(int i,int j)
{
  return abs(v[i].fi-v[i].se)<abs(v[j].se-v[j].fi);
}
int cmp2(int i,int j)
{
  return mp(v[i].se,v[i].fi)<mp(v[j].se,v[j].fi);
}
int main()
{
  ios::sync_with_stdio(0);
  cin>>n;
  v.resize(n);
  forn(i,n)
    p.pb(i),cin>>v[i].fi>>v[i].se;
  ans=p;
  lans=calc();
  sort(p.begin(),p.end());
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp1);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }
  sort(p.begin(),p.end(),cmp2);
  lp=calc();
  if(lp<lans){
    lans=lp,ans=p;
  }

  while(lans<=2500000000){
    random_shuffle(p.begin(),p.end());
    lp=calc();
    if(lp<lans){
      lans=lp,ans=p;
    }
  }
  //  cout<<lans<<endl;
  //assert(lans<=250000000);
  forn(i,n)
    cout<<ans[i]+1<<" ";
  cout<<endl;
  return 0;
}