#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-8;
int sign(double a) {
  if (a > EPS) return +1;
  if (a < -EPS) return -1;
  return 0;
}
double dot(complex<double> a, complex<double> b) { return real(conj(a) * b); }
double cross(complex<double> a, complex<double> b) { return imag(conj(a) * b); }
int ccw(complex<double> a, complex<double> b, complex<double> c) {
  b -= a;
  c -= a;
  double len = abs(b) * abs(c);
  if (cross(b, c) > +len * EPS) return +1;
  if (cross(b, c) < -len * EPS) return -1;
  if (dot(b, c) < 0) return +2;
  if (norm(b) < norm(c)) return -2;
  return 0;
}
struct Line : public vector<complex<double>> {
  Line() {}
  Line(const complex<double>& a, const complex<double>& b) {
    push_back(a);
    push_back(b);
  }
  complex<double> vector() const { return back() - front(); }
};
typedef vector<complex<double>> Polygon;
complex<double> crosspointLL(Line l, Line m) {
  double A = cross(l.vector(), m.vector());
  double B = cross(l.vector(), l[1] - m[0]);
  if (sign(A) == 0 && sign(B) == 0) return m[0];
  if (sign(A) == 0) assert(false);
  return m[0] + m.vector() * B / A;
}
bool intersectSP(Line s, complex<double> p) {
  return ccw(s[0], s[1], p) == 0 && abs(s[0] - p) > EPS && abs(s[1] - p) > EPS;
}
bool equalLL(Line l, Line m) {
  return sign(cross(l.vector(), m[0] - l[0])) == 0;
}
bool intersectLS(Line l, Line s) {
  return sign(cross(l.vector(), s[0] - l[0]) *
              cross(l.vector(), s[1] - l[0])) <= 0;
}
bool intersectSS(Line s, Line t) {
  bool f = ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
           ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
  if (!f) return false;
  complex<double> cp = crosspointLL(s, t);
  return intersectSP(s, cp) && intersectSP(t, cp);
}
complex<double> curr(const Polygon& P, int x) { return P[x]; }
complex<double> next(const Polygon& P, int x) { return P[(x + 1) % P.size()]; }
enum { OUT, ON, IN };
int contains(const Polygon& P, const complex<double>& p) {
  bool in = false;
  for (int i = 0; i < P.size(); i++) {
    complex<double> a = curr(P, i) - p;
    complex<double> b = next(P, i) - p;
    if (a.imag() > b.imag()) swap(a, b);
    if (a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) {
      in = !in;
    }
    if (sign(cross(a, b)) == 0 && sign(dot(a, b)) <= 0) return ON;
  }
  return in ? IN : OUT;
}
bool arrivable(complex<double> bp, complex<double> tp,
               const vector<Line>& poly_line, const Polygon& P) {
  if (contains(P, 0.5 * (bp + tp)) == OUT) return false;
  Line cat(bp, tp);
  for (int k = 0; k < poly_line.size(); k++) {
    Line pol = poly_line[k];
    if (equalLL(cat, pol)) continue;
    if (intersectSS(cat, pol)) return false;
  }
  return true;
}
int main() {
  int N;
  while (cin >> N && N) {
    Polygon P(N);
    for (int i = 0; i < N; i++) {
      double x, y;
      cin >> x >> y;
      P[i] = complex<double>(x, y);
    }
    vector<Line> poly_line(N);
    for (int i = 0; i < N; i++) {
      poly_line[i] = Line(P[i], P[(i + 1) % P.size()]);
    }
    vector<complex<double>> cand_point = P;
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++) {
        if (i == j) continue;
        complex<double> bp = P[i], ep = P[j];
        Line cat(bp, ep);
        bool is_cross = false;
        complex<double> cross_p;
        Line cross_l;
        int cross_idx;
        for (int k = 0; k < N; k++) {
          Line pol = poly_line[k];
          if (equalLL(cat, pol)) continue;
          if (!intersectLS(cat, pol)) continue;
          complex<double> cp = crosspointLL(cat, pol);
          if (!intersectSP(pol, cp)) continue;
          if (ccw(cat[0], cat[1], cp) != -2) continue;
          if (!is_cross) {
            is_cross = true;
            cross_p = cp;
            cross_l = pol;
            cross_idx = k;
          } else if (abs(cross_p - cat[0]) > abs(cp - cat[0])) {
            cross_p = cp;
            cross_l = pol;
            cross_idx = k;
          }
        }
        if (is_cross) {
          cand_point.push_back(cross_p + cross_l.vector() * EPS);
          cand_point.push_back(cross_p - cross_l.vector() * EPS);
        } else {
        }
      }
    vector<vector<bool>> is_arrivable(N,
                                      vector<bool>(cand_point.size(), false));
    for (int i = 0; i < N; i++)
      for (int j = 0; j < cand_point.size(); j++) {
        complex<double> bp = P[i], tp = cand_point[j];
        is_arrivable[i][j] = arrivable(bp, tp, poly_line, P);
        if (i == 0 && !is_arrivable[i][j]) {
        }
      }
    int ans = N;
    for (int s = 1; s < (1 << N); s++) {
      int bits = __builtin_popcount(s);
      if (bits >= ans) continue;
      vector<bool> ok(cand_point.size(), false);
      for (int i = 0; i < N; i++)
        if (s >> i & 1)
          for (int j = 0; j < cand_point.size(); j++)
            ok[j] = ok[j] || is_arrivable[i][j];
      bool is_answer = true;
      for (int i = 0; i < cand_point.size(); i++)
        if (!ok[i]) {
          is_answer = false;
          break;
        }
      if (is_answer) {
        ans = bits;
      }
    }
    cout << ans << endl;
  }
  return 0;
}
