1. 

/**
 * FWP, Ausgewählte Probleme aus dem ACM Programming Contest
 * Problem:     11612 - Sultan and Khairun Shundori
 * Link:        http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=78&problem=2659
 *
 *
 * Method :     Geometry (ad hoc)
 * Status :     Accepted
 * Runtime:     0.964
 *
 * @author      Evgeni Pavlidis
 * @version     1.0, 30/10/2010
 */

import java.io.*;
import java.util.*;


class Point implements Comparable<Point>
{
    int x,y,number;
    double crossProduct;

    Point(int number, int x, int y)
    {
        this.x = x;
        this.y = y;
        this.number = number;
    }

    public int compareTo(Point o)
    {
        if(o.y > y)
            return -1;

        if(o.y == y)
            return 0;

        return 1;
    }

    public String toString()
    {
        return String.format("{%d}_(%d,%d)", number, x, y);
    }

    public int hashCode()
    {
        return (x << 16) & y;
    }
}   

class Main
{
    static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static int nextInt() throws IOException
    {
        st.nextToken();
        return (int)st.nval;
    }

    static double crossProduct(Point m, Point a, Point b)
    {    return (a.x - m.x)*(b.y - m.y) - (b.x - m.x)*(a.y - m.y);    }

    static final double EPSILON = 1e-20;

    public static void main(String...args) throws Exception
    {
        StringBuffer output = new StringBuffer();
        
        int n, startPos = 0;
        // lower left and upper right points
        Point left, right;
        Point home, p;

        // indicate if we have points upward/below the separation line
        boolean up, down;

        // container for the points
        Set<Point> set = new HashSet<Point>();

        // set of points that lie above the line between lower-left most
        // and upper-right most points - the key is the x coordinate
        Map<Integer, Set<Point>> upper = new HashMap<Integer, Set<Point>>();
        // set of points that lie below and on the line
        Map<Integer, Set<Point>> lower = new HashMap<Integer, Set<Point>>();

        // save the x coordinates to inspect
        TreeSet<Integer> sweep = new TreeSet<Integer>();

        // save the loop series (from left to right)
        Point[] series = new Point[1000];

        while(true)
        {
            set.clear();
            lower.clear();
            upper.clear();
            sweep.clear();

            up = down = false;

            n = nextInt();
            if(n == 0)
                break;

            left = right = home = new Point(0, nextInt(), nextInt());

            set.add(home);
            sweep.add(home.x);
            upper.put(home.x, new TreeSet<Point>());
            lower.put(home.x, new TreeSet<Point>());

            // init all structures and find lower-left and uppper-right points
            for(int i = 1; i < n; i++)
            {
                p = new Point(i, nextInt(), nextInt());

                if(p.x < left.x || (p.x == left.x && p.y < left.y))
                    left = p;

                if(p.x > right.x || (p.x == right.x && p.y > right.y))
                    right = p;

                if(!upper.containsKey(p.x))
                    upper.put(p.x, new TreeSet<Point>());

                if(!lower.containsKey(p.x))
                    lower.put(p.x, new TreeSet<Point>());

                sweep.add(p.x);
                set.add(p);
            }

            // check where each point lies
            double test;
            for(Point point: set)
            {
                point.crossProduct = crossProduct(left, right, point);
                if(point.crossProduct - EPSILON > 0)
                    up = true;

                if(point.crossProduct + EPSILON < 0)
                    down = true;
            }
        

            if(!up && !down) // all points lie on a line
            {
                output.append("no solution\n");
                continue;
            }


            
            // divide set of point into two groups: above and below the line
            for(Point point: set)
                if(Math.abs(point.crossProduct) < EPSILON)
                {
                    if(!up) // build two groups to be able to make a loop
                        upper.get(point.x).add(point);
                    else
                        lower.get(point.x).add(point);
                }
                else if(point.crossProduct - EPSILON > 0)
                    upper.get(point.x).add(point);
                else
                    lower.get(point.x).add(point);
            
            //System.out.println(upper);
            //System.out.println(lower);


            // build loop series
            int pos = 0;
            for(int x: sweep)
                for(Point point: upper.get(x))
                {   
                    if(point == home)
                        startPos = pos;

                    series[pos++] = point;
                }

            for(int x: sweep.descendingSet())
                for(Point point: ((TreeSet<Point>)lower.get(x)).descendingSet())
                {
                    if(point == home)
                        startPos = pos;

                    series[pos++] = point;
                }


            if(series[startPos].number != 0 ||  n != pos)
                throw new RuntimeException();

            pos = startPos;
            for(int i = 0; i < n; i++, pos = ((pos+1) % n) )
                output.append(series[pos].number + " ");
            output.append("0\n");
        }

        System.out.print(output);
    }
}