#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
struct Point {
double x,y;
bool operator== (const Point&p) const { return x==p.x && y==p.y; }
};
double perimeter(vector<Point> P)
{
double r = 0;
for(int i = 1;i < P.size(); i++)
r += sqrt(pow(P[i].x - P[i-1].x, 2) + pow(P[i].y - P[i-1].y, 2));
return r;
}
int orientation(Point p, Point q, Point r)
{
int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
if (val == 0)
return 0;
return (val > 0) ? 1 : 2;
}
int find_leftmost_point(vector<Point> points, int n)
{
int l = 0;
for (int i = 1; i < n; i++)
if (points[i].x < points[l].x)
l = i;
return l;
}
vector<Point> convexHull(vector<Point> points, int base, vector<Point> &hull)
{
int p, q;
p = base;
q = (p+1) % points.size();
if (points.size() <= 3)
{
return hull;
}
if(q == base)
{
return hull;
}
else
{
for (int i = 0; i < points.size(); i++)
{
if (orientation(points[p], points[i], points[q]) == 2)
{
q = i;
}
}
auto srch=find(hull.begin(), hull.end(), points[q]);
if (srch!=hull.end()) {
cout << "ALREADY IN"<<endl;
return hull;
}
cout<<points[q].x<<","<<points[q].y<<endl;
hull.push_back(points[q]);
return convexHull(points, q, hull);
}
}
int main()
{
vector<Point> hull(20);
int n,x,y;
cin >> n;
vector<Point> ps;
Point p;
// Point p1,p2,q1,q2;
while(cin >> x >> y)
{
p.x = x;
p.y = y;
ps.push_back(p);
}
int base = find_leftmost_point(ps, n);
hull.push_back(ps[base]);
vector<Point> po = convexHull(ps, base, hull);
cout << perimeter(po) << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDxhbGdvcml0aG0+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOyAKCnN0cnVjdCBQb2ludCB7Cglkb3VibGUgeCx5OyAKCWJvb2wgb3BlcmF0b3I9PSAoY29uc3QgUG9pbnQmcCkgY29uc3QgeyByZXR1cm4geD09cC54ICYmIHk9PXAueTsgfSAKfTsKCmRvdWJsZSBwZXJpbWV0ZXIodmVjdG9yPFBvaW50PiBQKQp7CiAgICBkb3VibGUgciA9IDA7CiAgICBmb3IoaW50IGkgPSAxO2kgPCBQLnNpemUoKTsgaSsrKQogICAgICAgIHIgKz0gc3FydChwb3coUFtpXS54IC0gUFtpLTFdLngsIDIpICsgcG93KFBbaV0ueSAtIFBbaS0xXS55LCAyKSk7CiAgICByZXR1cm4gcjsKfQppbnQgb3JpZW50YXRpb24oUG9pbnQgcCwgUG9pbnQgcSwgUG9pbnQgcikKewogICAgaW50IHZhbCA9IChxLnkgLSBwLnkpICogKHIueCAtIHEueCkgLSAocS54IC0gcC54KSAqIChyLnkgLSBxLnkpOwoKICAgIGlmICh2YWwgPT0gMCkgCiAgICAgICAgcmV0dXJuIDA7CiAgICByZXR1cm4gKHZhbCA+IDApID8gMSA6IDI7Cn0KCmludCBmaW5kX2xlZnRtb3N0X3BvaW50KHZlY3RvcjxQb2ludD4gcG9pbnRzLCBpbnQgbikKewogICAgaW50IGwgPSAwOwogICAgZm9yIChpbnQgaSA9IDE7IGkgPCBuOyBpKyspCiAgICAgICAgaWYgKHBvaW50c1tpXS54IDwgcG9pbnRzW2xdLngpCiAgICAgICAgICAgIGwgPSBpOwogICAgcmV0dXJuIGw7Cgp9Cgp2ZWN0b3I8UG9pbnQ+IGNvbnZleEh1bGwodmVjdG9yPFBvaW50PiBwb2ludHMsIGludCBiYXNlLCB2ZWN0b3I8UG9pbnQ+ICZodWxsKQp7CiAgICBpbnQgcCwgcTsKCiAgICBwID0gYmFzZTsgICAKICAgIHEgPSAocCsxKSAlIHBvaW50cy5zaXplKCk7CiAgICBpZiAocG9pbnRzLnNpemUoKSA8PSAzKSAKICAgIHsKICAgICAgICByZXR1cm4gaHVsbDsKICAgIH0KICAgIGlmKHEgPT0gYmFzZSkgIAogICAgewogICAgICAgIHJldHVybiBodWxsOwogICAgfQogICAgZWxzZQogICAgeyAgIAogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcG9pbnRzLnNpemUoKTsgaSsrKQogICAgICAgIHsgICAKICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uKHBvaW50c1twXSwgcG9pbnRzW2ldLCBwb2ludHNbcV0pID09IDIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHEgPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGF1dG8gc3JjaD1maW5kKGh1bGwuYmVnaW4oKSwgaHVsbC5lbmQoKSwgcG9pbnRzW3FdKTsgCiAgICAgICAgaWYgKHNyY2ghPWh1bGwuZW5kKCkpIHsKICAgICAgICAJY291dCA8PCAiQUxSRUFEWSBJTiI8PGVuZGw7IAogICAgICAgIAlyZXR1cm4gaHVsbDsKICAgICAgICB9CiAgICAgICAgY291dDw8cG9pbnRzW3FdLng8PCIsIjw8cG9pbnRzW3FdLnk8PGVuZGw7CiAgICAgICAgaHVsbC5wdXNoX2JhY2socG9pbnRzW3FdKTsKICAgICAgICByZXR1cm4gY29udmV4SHVsbChwb2ludHMsIHEsIGh1bGwpOwogICAgfQp9CgoKaW50IG1haW4oKQp7CiAgICB2ZWN0b3I8UG9pbnQ+IGh1bGwoMjApOwogICAgaW50IG4seCx5OwogICAgY2luID4+IG47CiAgICB2ZWN0b3I8UG9pbnQ+IHBzOwogICAgUG9pbnQgcDsKLy8gIFBvaW50IHAxLHAyLHExLHEyOwoKICAgIHdoaWxlKGNpbiA+PiB4ID4+IHkpCiAgICB7ICAgCiAgICAgICAgcC54ID0geDsKICAgICAgICBwLnkgPSB5OwogICAgICAgIHBzLnB1c2hfYmFjayhwKTsKICAgIH0KICAgIGludCBiYXNlID0gZmluZF9sZWZ0bW9zdF9wb2ludChwcywgbik7CiAgICBodWxsLnB1c2hfYmFjayhwc1tiYXNlXSk7CiAgICB2ZWN0b3I8UG9pbnQ+IHBvID0gY29udmV4SHVsbChwcywgYmFzZSwgaHVsbCk7CiAgICBjb3V0IDw8IHBlcmltZXRlcihwbykgPDwgZW5kbDsKICAgIHJldHVybiAwOwp9Cg==