#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
// ------ Classes ------ //
class Point {
public:
long double px, py;
Point() : px(0), py(0) {};
Point(long double px_, long double py_) : px(px_), py(py_) {};
friend bool operator==(const Point& p1, const Point& p2) { return p1.px == p2.px && p1.py == p2.py; }
friend bool operator!=(const Point& p1, const Point& p2) { return p1.px != p2.px || p1.py != p2.py; }
friend bool operator<(const Point& p1, const Point& p2) { return p1.px < p2.px ? true : (p1.px == p2.px && p1.py < p2.py); }
friend bool operator>(const Point& p1, const Point& p2) { return p1.px > p2.px ? true : (p1.px == p2.px && p1.py > p2.py); }
friend bool operator<=(const Point& p1, const Point& p2) { return !(p1 > p2); }
friend bool operator>=(const Point& p1, const Point& p2) { return !(p1 < p2); }
friend Point operator+(const Point& p1, const Point& p2) { return Point(p1.px + p2.px, p1.py + p2.py); }
friend Point operator-(const Point& p1, const Point& p2) { return Point(p1.px - p2.px, p1.py - p2.py); }
friend Point operator*(const Point& p1, long double d) { return Point(p1.px * d, p1.py + d); }
friend Point operator*(long double d, const Point& p1) { return p1 * d; }
friend Point operator/(const Point& p1, long double d) { return Point(p1.px / d, p1.py / d); }
Point& operator+=(const Point& p1) { px += p1.px; py += p1.py; return *this; }
Point& operator-=(const Point& p1) { px -= p1.px; py -= p1.py; return *this; }
Point& operator*=(long double d) { px *= d; py *= d; return *this; }
Point& operator/=(long double d) { px /= d; py /= d; return *this; }
};
class Segment {
public:
Point p1, p2;
Segment() : p1(Point()), p2(Point()) {};
Segment(Point p1_, Point p2_) : p1(p1_), p2(p2_) {};
Segment(long double p1x, long double p1y, long double p2x, long double p2y) : p1(Point(p1x, p1y)), p2(Point(p2x, p2y)) {};
friend bool operator==(const Segment& s1, const Segment& s2) { return (s1.p1 == s2.p1 && s1.p2 == s2.p2) || (s1.p1 == s2.p2 && s1.p2 == s2.p1); }
friend bool operator!=(const Segment& s1, const Segment& s2) { return !(s1 == s2); }
};
class Line {
public:
Point p1, p2;
Line() : p1(Point()), p2(Point()) {};
Line(Point p1_, Point p2_) : p1(p1_), p2(p2_) {};
Line(long double p1x, long double p1y, long double p2x, long double p2y) : p1(Point(p1x, p1y)), p2(Point(p2x, p2y)) {};
friend bool operator==(const Line& s1, const Line& s2) { return (s1.p1 == s2.p1 && s1.p2 == s2.p2) || (s1.p1 == s2.p2 && s1.p2 == s2.p1); }
friend bool operator!=(const Line& s1, const Line& s2) { return !(s1 == s2); }
};
// ------ Functions ------ //
long double norm(const Point& a) { return a.px * a.px + a.py * a.py; }
long double abs(const Point& a) { return sqrtl(norm(a)); }
long double dot(const Point& a, const Point& b) { return a.px * b.px + a.py * b.py; }
long double crs(const Point& a, const Point& b) { return a.px * b.py - a.py * b.px; }
int ccw(Point p0, Point p1, Point p2) {
Point a = p1 - p0, b = p2 - p0;
if (crs(a, b) > 1e-10) return 1;
if (crs(a, b) < -1e-10) return -1;
if (dot(a, b) < -1e-10) return 2;
if (norm(a) < norm(b)) return -2;
return 0;
}
vector<Point> convex_hull(vector<Point> v) {
if (v.size() < 3) return v;
sort(v.begin(), v.end());
vector<Point> u = { v[0], v[1] }, l = { v[v.size() - 1], v[v.size() - 2] };
for (int i = 2; i < v.size(); i++) {
for (int n = u.size(); n >= 2 && ccw(u[n - 2], u[n - 1], v[i]) >= 0; n--) u.pop_back();
u.push_back(v[i]);
}
for (int i = v.size() - 3; i >= 0; i--) {
for (int n = l.size(); n >= 2 && ccw(l[n - 2], l[n - 1], v[i]) >= 0; n--) l.pop_back();
l.push_back(v[i]);
}
reverse(l.begin(), l.end());
for (int i = u.size() - 2; i >= 1; i--) l.push_back(u[i]);
return l;
}
// ------ Main ------ //
int n; vector<Point> v;
int rec(vector<Point> v1) {
vector<Point> v2 = convex_hull(v1);
sort(v2.begin(), v2.end());
if (v1.size() == v2.size()) return v1.size() < 3 ? v1.size() - 1 : (v1.size() == 3 ? v1.size() : v1.size() * 2 - 3);
vector<Point> v3;
for (int i = 0; i < v1.size(); i++) {
if (!binary_search(v2.begin(), v2.end(), v1[i])) v3.push_back(v1[i]);
}
vector<Point> v4 = convex_hull(v3);
if (v4.size() == 1) return v2.size() * 2;
if (v4.size() == 2) return v2.size() * 2 + 3;
return rec(v3) + v2.size() * 2 + v4.size();
}
int main() {
cin >> n; v.resize(n);
for (int i = 0; i < v.size(); i++) cin >> v[i].px >> v[i].py;
cout << rec(v) << endl;
return 0;
}
I2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxhbGdvcml0aG0+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Ci8vIC0tLS0tLSBDbGFzc2VzIC0tLS0tLSAvLwpjbGFzcyBQb2ludCB7CnB1YmxpYzoKCWxvbmcgZG91YmxlIHB4LCBweTsKCVBvaW50KCkgOiBweCgwKSwgcHkoMCkge307CglQb2ludChsb25nIGRvdWJsZSBweF8sIGxvbmcgZG91YmxlIHB5XykgOiBweChweF8pLCBweShweV8pIHt9OwoJZnJpZW5kIGJvb2wgb3BlcmF0b3I9PShjb25zdCBQb2ludCYgcDEsIGNvbnN0IFBvaW50JiBwMikgeyByZXR1cm4gcDEucHggPT0gcDIucHggJiYgcDEucHkgPT0gcDIucHk7IH0KCWZyaWVuZCBib29sIG9wZXJhdG9yIT0oY29uc3QgUG9pbnQmIHAxLCBjb25zdCBQb2ludCYgcDIpIHsgcmV0dXJuIHAxLnB4ICE9IHAyLnB4IHx8IHAxLnB5ICE9IHAyLnB5OyB9CglmcmllbmQgYm9vbCBvcGVyYXRvcjwoY29uc3QgUG9pbnQmIHAxLCBjb25zdCBQb2ludCYgcDIpIHsgcmV0dXJuIHAxLnB4IDwgcDIucHggPyB0cnVlIDogKHAxLnB4ID09IHAyLnB4ICYmIHAxLnB5IDwgcDIucHkpOyB9CglmcmllbmQgYm9vbCBvcGVyYXRvcj4oY29uc3QgUG9pbnQmIHAxLCBjb25zdCBQb2ludCYgcDIpIHsgcmV0dXJuIHAxLnB4ID4gcDIucHggPyB0cnVlIDogKHAxLnB4ID09IHAyLnB4ICYmIHAxLnB5ID4gcDIucHkpOyB9CglmcmllbmQgYm9vbCBvcGVyYXRvcjw9KGNvbnN0IFBvaW50JiBwMSwgY29uc3QgUG9pbnQmIHAyKSB7IHJldHVybiAhKHAxID4gcDIpOyB9CglmcmllbmQgYm9vbCBvcGVyYXRvcj49KGNvbnN0IFBvaW50JiBwMSwgY29uc3QgUG9pbnQmIHAyKSB7IHJldHVybiAhKHAxIDwgcDIpOyB9CglmcmllbmQgUG9pbnQgb3BlcmF0b3IrKGNvbnN0IFBvaW50JiBwMSwgY29uc3QgUG9pbnQmIHAyKSB7IHJldHVybiBQb2ludChwMS5weCArIHAyLnB4LCBwMS5weSArIHAyLnB5KTsgfQoJZnJpZW5kIFBvaW50IG9wZXJhdG9yLShjb25zdCBQb2ludCYgcDEsIGNvbnN0IFBvaW50JiBwMikgeyByZXR1cm4gUG9pbnQocDEucHggLSBwMi5weCwgcDEucHkgLSBwMi5weSk7IH0KCWZyaWVuZCBQb2ludCBvcGVyYXRvciooY29uc3QgUG9pbnQmIHAxLCBsb25nIGRvdWJsZSBkKSB7IHJldHVybiBQb2ludChwMS5weCAqIGQsIHAxLnB5ICsgZCk7IH0KCWZyaWVuZCBQb2ludCBvcGVyYXRvcioobG9uZyBkb3VibGUgZCwgY29uc3QgUG9pbnQmIHAxKSB7IHJldHVybiBwMSAqIGQ7IH0KCWZyaWVuZCBQb2ludCBvcGVyYXRvci8oY29uc3QgUG9pbnQmIHAxLCBsb25nIGRvdWJsZSBkKSB7IHJldHVybiBQb2ludChwMS5weCAvIGQsIHAxLnB5IC8gZCk7IH0KCVBvaW50JiBvcGVyYXRvcis9KGNvbnN0IFBvaW50JiBwMSkgeyBweCArPSBwMS5weDsgcHkgKz0gcDEucHk7IHJldHVybiAqdGhpczsgfQoJUG9pbnQmIG9wZXJhdG9yLT0oY29uc3QgUG9pbnQmIHAxKSB7IHB4IC09IHAxLnB4OyBweSAtPSBwMS5weTsgcmV0dXJuICp0aGlzOyB9CglQb2ludCYgb3BlcmF0b3IqPShsb25nIGRvdWJsZSBkKSB7IHB4ICo9IGQ7IHB5ICo9IGQ7IHJldHVybiAqdGhpczsgfQoJUG9pbnQmIG9wZXJhdG9yLz0obG9uZyBkb3VibGUgZCkgeyBweCAvPSBkOyBweSAvPSBkOyByZXR1cm4gKnRoaXM7IH0KfTsKY2xhc3MgU2VnbWVudCB7CnB1YmxpYzoKCVBvaW50IHAxLCBwMjsKCVNlZ21lbnQoKSA6IHAxKFBvaW50KCkpLCBwMihQb2ludCgpKSB7fTsKCVNlZ21lbnQoUG9pbnQgcDFfLCBQb2ludCBwMl8pIDogcDEocDFfKSwgcDIocDJfKSB7fTsKCVNlZ21lbnQobG9uZyBkb3VibGUgcDF4LCBsb25nIGRvdWJsZSBwMXksIGxvbmcgZG91YmxlIHAyeCwgbG9uZyBkb3VibGUgcDJ5KSA6IHAxKFBvaW50KHAxeCwgcDF5KSksIHAyKFBvaW50KHAyeCwgcDJ5KSkge307CglmcmllbmQgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFNlZ21lbnQmIHMxLCBjb25zdCBTZWdtZW50JiBzMikgeyByZXR1cm4gKHMxLnAxID09IHMyLnAxICYmIHMxLnAyID09IHMyLnAyKSB8fCAoczEucDEgPT0gczIucDIgJiYgczEucDIgPT0gczIucDEpOyB9CglmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IFNlZ21lbnQmIHMxLCBjb25zdCBTZWdtZW50JiBzMikgeyByZXR1cm4gIShzMSA9PSBzMik7IH0KfTsKY2xhc3MgTGluZSB7CnB1YmxpYzoKCVBvaW50IHAxLCBwMjsKCUxpbmUoKSA6IHAxKFBvaW50KCkpLCBwMihQb2ludCgpKSB7fTsKCUxpbmUoUG9pbnQgcDFfLCBQb2ludCBwMl8pIDogcDEocDFfKSwgcDIocDJfKSB7fTsKCUxpbmUobG9uZyBkb3VibGUgcDF4LCBsb25nIGRvdWJsZSBwMXksIGxvbmcgZG91YmxlIHAyeCwgbG9uZyBkb3VibGUgcDJ5KSA6IHAxKFBvaW50KHAxeCwgcDF5KSksIHAyKFBvaW50KHAyeCwgcDJ5KSkge307CglmcmllbmQgYm9vbCBvcGVyYXRvcj09KGNvbnN0IExpbmUmIHMxLCBjb25zdCBMaW5lJiBzMikgeyByZXR1cm4gKHMxLnAxID09IHMyLnAxICYmIHMxLnAyID09IHMyLnAyKSB8fCAoczEucDEgPT0gczIucDIgJiYgczEucDIgPT0gczIucDEpOyB9CglmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IExpbmUmIHMxLCBjb25zdCBMaW5lJiBzMikgeyByZXR1cm4gIShzMSA9PSBzMik7IH0KfTsKLy8gLS0tLS0tIEZ1bmN0aW9ucyAtLS0tLS0gLy8KbG9uZyBkb3VibGUgbm9ybShjb25zdCBQb2ludCYgYSkgeyByZXR1cm4gYS5weCAqIGEucHggKyBhLnB5ICogYS5weTsgfQpsb25nIGRvdWJsZSBhYnMoY29uc3QgUG9pbnQmIGEpIHsgcmV0dXJuIHNxcnRsKG5vcm0oYSkpOyB9CmxvbmcgZG91YmxlIGRvdChjb25zdCBQb2ludCYgYSwgY29uc3QgUG9pbnQmIGIpIHsgcmV0dXJuIGEucHggKiBiLnB4ICsgYS5weSAqIGIucHk7IH0KbG9uZyBkb3VibGUgY3JzKGNvbnN0IFBvaW50JiBhLCBjb25zdCBQb2ludCYgYikgeyByZXR1cm4gYS5weCAqIGIucHkgLSBhLnB5ICogYi5weDsgfQppbnQgY2N3KFBvaW50IHAwLCBQb2ludCBwMSwgUG9pbnQgcDIpIHsKCVBvaW50IGEgPSBwMSAtIHAwLCBiID0gcDIgLSBwMDsKCWlmIChjcnMoYSwgYikgPiAxZS0xMCkgcmV0dXJuIDE7CglpZiAoY3JzKGEsIGIpIDwgLTFlLTEwKSByZXR1cm4gLTE7CglpZiAoZG90KGEsIGIpIDwgLTFlLTEwKSByZXR1cm4gMjsKCWlmIChub3JtKGEpIDwgbm9ybShiKSkgcmV0dXJuIC0yOwoJcmV0dXJuIDA7Cn0KdmVjdG9yPFBvaW50PiBjb252ZXhfaHVsbCh2ZWN0b3I8UG9pbnQ+IHYpIHsKCWlmICh2LnNpemUoKSA8IDMpIHJldHVybiB2OwoJc29ydCh2LmJlZ2luKCksIHYuZW5kKCkpOwoJdmVjdG9yPFBvaW50PiB1ID0geyB2WzBdLCB2WzFdIH0sIGwgPSB7IHZbdi5zaXplKCkgLSAxXSwgdlt2LnNpemUoKSAtIDJdIH07Cglmb3IgKGludCBpID0gMjsgaSA8IHYuc2l6ZSgpOyBpKyspIHsKCQlmb3IgKGludCBuID0gdS5zaXplKCk7IG4gPj0gMiAmJiBjY3codVtuIC0gMl0sIHVbbiAtIDFdLCB2W2ldKSA+PSAwOyBuLS0pIHUucG9wX2JhY2soKTsKCQl1LnB1c2hfYmFjayh2W2ldKTsKCX0KCWZvciAoaW50IGkgPSB2LnNpemUoKSAtIDM7IGkgPj0gMDsgaS0tKSB7CgkJZm9yIChpbnQgbiA9IGwuc2l6ZSgpOyBuID49IDIgJiYgY2N3KGxbbiAtIDJdLCBsW24gLSAxXSwgdltpXSkgPj0gMDsgbi0tKSBsLnBvcF9iYWNrKCk7CgkJbC5wdXNoX2JhY2sodltpXSk7Cgl9CglyZXZlcnNlKGwuYmVnaW4oKSwgbC5lbmQoKSk7Cglmb3IgKGludCBpID0gdS5zaXplKCkgLSAyOyBpID49IDE7IGktLSkgbC5wdXNoX2JhY2sodVtpXSk7CglyZXR1cm4gbDsKfQovLyAtLS0tLS0gTWFpbiAtLS0tLS0gLy8KaW50IG47IHZlY3RvcjxQb2ludD4gdjsKaW50IHJlYyh2ZWN0b3I8UG9pbnQ+IHYxKSB7Cgl2ZWN0b3I8UG9pbnQ+IHYyID0gY29udmV4X2h1bGwodjEpOwoJc29ydCh2Mi5iZWdpbigpLCB2Mi5lbmQoKSk7CglpZiAodjEuc2l6ZSgpID09IHYyLnNpemUoKSkgcmV0dXJuIHYxLnNpemUoKSA8IDMgPyB2MS5zaXplKCkgLSAxIDogKHYxLnNpemUoKSA9PSAzID8gdjEuc2l6ZSgpIDogdjEuc2l6ZSgpICogMiAtIDMpOwoJdmVjdG9yPFBvaW50PiB2MzsKCWZvciAoaW50IGkgPSAwOyBpIDwgdjEuc2l6ZSgpOyBpKyspIHsKCQlpZiAoIWJpbmFyeV9zZWFyY2godjIuYmVnaW4oKSwgdjIuZW5kKCksIHYxW2ldKSkgdjMucHVzaF9iYWNrKHYxW2ldKTsKCX0KCXZlY3RvcjxQb2ludD4gdjQgPSBjb252ZXhfaHVsbCh2Myk7CglpZiAodjQuc2l6ZSgpID09IDEpIHJldHVybiB2Mi5zaXplKCkgKiAyOwoJaWYgKHY0LnNpemUoKSA9PSAyKSByZXR1cm4gdjIuc2l6ZSgpICogMiArIDM7CglyZXR1cm4gcmVjKHYzKSArIHYyLnNpemUoKSAqIDIgKyB2NC5zaXplKCk7Cn0KaW50IG1haW4oKSB7CgljaW4gPj4gbjsgdi5yZXNpemUobik7Cglmb3IgKGludCBpID0gMDsgaSA8IHYuc2l6ZSgpOyBpKyspIGNpbiA+PiB2W2ldLnB4ID4+IHZbaV0ucHk7Cgljb3V0IDw8IHJlYyh2KSA8PCBlbmRsOwoJcmV0dXJuIDA7Cn0=