Problem:
Convex Hull

Find the convex hull of a given set of points P. In other words, find the smallest convex polygon containing all the points of P. Here, in a convex polygon, all interior angles are less than or equal to 180 degrees.

Please note that you should find all the points of P on both corner and boundary of the convex polygon.

Input

n
x1 y1
x2 y2
:
xn yn

The first integer n is the number of points in P. The coordinate of the i-th point pi is given by two integers xi and yi.

Output

In the first line, print the number of points on the corner/boundary of the convex polygon. In the following lines, print x y coordinates of the set of points.
The coordinates should be given in the order of counter-clockwise visit of them starting from the point in P with the minimum y-coordinate, or the leftmost such point in case of a tie.

Constraints

3 ≤ n ≤ 100000

-10000 ≤ xi, yi ≤ 10000

No point in the P will occur more than once.

Sample Input 1

7
2 1
0 0
1 2
2 2
4 2
1 3
3 3

Sample Output 1

5
0 0
2 1
4 2
3 3
1 3

Sample Input 2

4
0 0
2 2
0 2
0 1

Sample Output 2

4
0 0
2 2
0 2
0 1

Solution in JavaScript (judge verdict: Wrong Answer)

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    };
};

function swap(arr, min_idx) {
    var temp = arr[0];
    arr[0] = arr[min_idx];
    arr[min_idx] = temp;
    return arr;
}

function find_bot(arr, size) {
    //find min point
    var min = arr[0].y;
    var min_idx = 0;
    for ( var i = 0; i < size; i++) {
        if (arr[i].y < min || (arr[i].y == min && arr[i].x < arr[min_idx].x)) {
            min_idx = i;
            min = arr[i].y;
        };
    };
    //swap to 0
    return swap(arr, min_idx);
};

var file = require('fs').readFileSync('/dev/stdin', 'utf8');
var input = file.split("\n");
var size = parseInt(input[0]);
var points = []
for (var i = 1; i < size+1; i++) {
    point = input[i].split(" ");
    x = parseInt(point[0]);
    y = parseInt(point[1]);
    points.push(new Point(x, y));
}
points = find_bot(points, size);
var base_p = points[0];
var sorted_arr = [base_p].concat(points.slice(1).sort(function (p1, p2) {
    //var cross_prod = (vecx * new_vecy - vecy * new_vecx);
    var cross_prod = ((p1.x - base_p.x) * (p2.y - p1.y) - (p1.y - base_p.y) * (p2.x - p1.x));
    //var cross_prod = (p1.y * base_p.y - p2.x * p1.x) - (p1.x * base_p.x - p2.y * p1.y);
    if (cross_prod == 0) {
        return p1.y <= p2.y ? -1 : 1;
    }
    return cross_prod > 0 ? -1 : 1;
}));
convex_hull = sorted_arr.slice(0,2);
var new_vecx, new_vecy, vecx = 0, vecy = 0;
for (var i = 2; i <= size; i++) {
//     convex_hull.push(sorted_arr[i]);
//     // var cross_prod = 0;
//     // while(cross_prod < 0 && convex_hull.length >= 3){
//     //     new_vecx = points[-1].x - points[-2].x;
//     //     new_vecy = points[-1].y - points[-2].y;
//     //     vecx = points[-2].x - points[-3].x;
//     //     vecy = points[-2].y - points[-3].y;
//     //     cross_prod = (vecx * new_vecy - vecy * new_vecx);
//     //     if (cross_prod > 0) {
//     //         convex_hull.pop();
//     //     }
//     // }
}

// for(var i = 0; i < convex_hull.length; i++){
//     console.log(`${convex_hull[i].x} ${convex_hull[i].y}`);
// }