import java.awt.geom.*;
import java.util.*;
import java.awt.*;
import java.io.*;

// http://icpcres.ecs.baylor.edu/onlinejudge/external/6/681.pdf

class PolyHullArea {
    public static void main(String[] args) throws IOException {
        new PolyHullArea().run();
    }

    public void run() throws IOException {
        ArrayList<Point2D.Double> hull, pts = new ArrayList<Point2D.Double>();
        Scanner cin = new Scanner(System.in);

        int datasets = cin.nextInt();
        for(int dataset=0; dataset < datasets; ++dataset) {
            pts.clear();
            int N = cin.nextInt();

            for(int i = 0; i < N; ++i) {
                double px = cin.nextDouble();
                double py = cin.nextDouble();
                if(i != N-1) // ignore last (dup) point
                    pts.add(new Point2D.Double(px,py));
            }

            hull = convexHull(pts);
            System.out.println("After sorting, convex hull is:");
            for(Point2D.Double pt : hull) {
                System.out.println("\t" + pt.toString());
            }


            if(dataset != datasets -1)
                cin.nextInt(); // eat -1 delimiter
        }
    }

    private class PtCmp implements Comparator<Point2D.Double> {
        public int compare(Point2D.Double a, Point2D.Double b) {
            if(a.y < b.y) return -1;
            if(a.y > b.y) return 1;
            if(a.x < b.x) return -1;
            if(a.x > b.x) return 1;
            return 0;
        }
    }

    static final int CCW_LEFT = -1;
    static final int SORT_DIRECTION = CCW_LEFT;

    private class AngleCmp implements Comparator<Point2D.Double> {
        Point2D.Double p;
        AngleCmp(Point2D.Double pt) { p = pt; }
        public int compare(Point2D.Double a, Point2D.Double b) {
            return SORT_DIRECTION * ccw(p, a, b);
        }
    }

    // 1 means clockwise (right turn)
    public int ccw( Point2D.Double a, Point2D.Double b, Point2D.Double c) {
        return Line2D.relativeCCW(a.x, a.y, b.x, b.y, c.x, c.y);
    }

    public ArrayList<Point2D.Double> convexHull(ArrayList<Point2D.Double> l) {
        Point2D.Double p, last, next2last;

        p = Collections.min(l, new PtCmp()); // find pivot

        l.remove(p); // remove pivot from sort
        Collections.sort(l, new AngleCmp(p));
            System.out.println("After sorting points:");
            for(Point2D.Double pt : l) {
                System.out.println("\t" + pt.toString());
            }


        Stack<Point2D.Double> stack = new Stack<Point2D.Double>();
        stack.push(p); // add pivot back in the game
        stack.push(l.get(0));
        for(int i = 1; i < l.size(); ++i) {
            boolean done = false;
            while(!done && stack.size() > 1) {
                last = stack.pop();
                next2last = stack.peek();
                stack.push(last); // get top 2 elements, without disturbing stack

                if(ccw(next2last, l.get(i), last) != SORT_DIRECTION)
                    stack.pop();
                else done = true;
            }
            stack.push(l.get(i));
        }

        return new ArrayList<Point2D.Double>(stack);
    }
}
