#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;
inline double dot(const complex<double> &a, const complex<double> &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}
inline double cross(const complex<double> &a, const complex<double> &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}
inline int cmp(double a, double b) {
  const double diff = a - b;
  if (fabs(diff) < EPS) return 0;
  return diff < 0 ? -1 : 1;
}
bool intersectSS(const complex<double> &pa, const complex<double> &pb,
                 const complex<double> &qa, const complex<double> &qb) {
  if (cmp(cross(pb - pa, qa - pa) * cross(pb - pa, qb - pa), 0) >= 0)
    return false;
  if (cmp(cross(qb - qa, pa - qa) * cross(qb - qa, pb - qa), 0) >= 0)
    return false;
  return true;
}
bool intersectLS(const complex<double> &pa, const complex<double> &pb,
                 const complex<double> &qa, const complex<double> &qb) {
  return cmp(cross(pb - pa, qa - pa) * cross(pb - pa, qb - pa), 0) < 0;
}
complex<double> intersection(const complex<double> &pa,
                             const complex<double> &pb,
                             const complex<double> &qa,
                             const complex<double> &qb) {
  const double A = cross(pb - pa, qb - qa);
  const double B = cross(pb - pa, pb - qa);
  if (cmp(A, 0) == 0 && cmp(B, 0) == 0) return qa;
  return qa + B / A * (qb - qa);
}
bool in_polygon(const complex<double> &p,
                const vector<complex<double>> &polygon) {
  const int N = polygon.size();
  int cnt = 0;
  for (int i = 0; i < N; ++i) {
    const int ni = (i + 1) % N;
    complex<double> va = polygon[i] - p;
    complex<double> vb = polygon[ni] - p;
    if (va.imag() > vb.imag()) swap(va, vb);
    if (cmp(va.imag(), 0) <= 0 && cmp(0, vb.imag()) < 0) {
      if (cmp(cross(va, vb), 0) < 0) ++cnt;
    }
    if (cmp(cross(va, vb), 0) == 0 && cmp(dot(va, vb), 0) <= 0) return true;
  }
  return cnt % 2 == 1;
}
bool can_see(const complex<double> &pa, const complex<double> &pb,
             const vector<complex<double>> &polygon) {
  const int N = polygon.size();
  if (abs(pa - pb) < EPS) return true;
  vector<complex<double>> ps;
  for (int i = 0; i < N; ++i) {
    const int ni = (i + 1) % N;
    if (abs(polygon[i] - pb) < EPS) continue;
    if (intersectSS(pa, pb, polygon[i], polygon[ni])) return false;
    if (cmp(cross(pb - pa, polygon[i] - pa), 0) == 0 &&
        cmp(dot(pa - polygon[i], pb - polygon[i]), 0) <= 0) {
      ps.push_back(polygon[i]);
    }
  }
  ps.push_back(pa);
  ps.push_back(pb);
  sort(ps.begin(), ps.end(),
       [pa](const complex<double> &p1, const complex<double> &p2) {
         return norm(pa - p1) < norm(pa - p2);
       });
  for (int i = 0; i + 1 < ps.size(); ++i) {
    if (!in_polygon((ps[i] + ps[i + 1]) * 0.5, polygon)) return false;
  }
  return true;
}
bool solve() {
  int N;
  cin >> N;
  if (!N) return false;
  vector<complex<double>> polygon(N);
  for (int i = 0; i < N; ++i) {
    double x, y;
    cin >> x >> y;
    polygon[i] = complex<double>(x, y);
  }
  vector<complex<double>> new_polygon;
  for (int i = 0; i < N; ++i) {
    const complex<double> pa = polygon[i];
    const complex<double> pb = polygon[(i + 1) % N];
    new_polygon.push_back(pa);
    vector<complex<double>> buf;
    for (int j = 0; j < N; ++j) {
      const complex<double> pj = polygon[j];
      for (int k = 0; k < j; ++k) {
        const complex<double> pk = polygon[k];
        if (!intersectLS(pj, pk, pa, pb)) continue;
        const complex<double> ip = intersection(pj, pk, pa, pb);
        buf.push_back(ip);
      }
    }
    sort(buf.begin(), buf.end(),
         [pa](const complex<double> &a, const complex<double> &b) {
           return norm(pa - a) < norm(pa - b);
         });
    new_polygon.insert(new_polygon.end(), buf.begin(), buf.end());
  }
  const int M = new_polygon.size();
  vector<vector<bool>> visible_mask(N, vector<bool>(M, false));
  for (int j = 0; j < N; ++j) {
    const complex<double> p = polygon[j];
    for (int i = 0; i < M; ++i) {
      const int ni = (i + 1) % M;
      if (can_see(p, new_polygon[i], polygon) &&
          can_see(p, new_polygon[ni], polygon)) {
        visible_mask[j][i] = true;
      }
    }
  }
  int ans = N;
  for (int pat = 0; pat < (1 << N); ++pat) {
    int popcnt = 0;
    vector<bool> mask(M, false);
    for (int i = 0; i < N; ++i) {
      if (pat & (1 << i)) {
        ++popcnt;
        for (int j = 0; j < M; ++j) {
          mask[j] = mask[j] | visible_mask[i][j];
        }
      }
    }
    if (all_of(mask.begin(), mask.end(), [](bool b) { return b; })) {
      ans = min(ans, popcnt);
    }
  }
  cout << ans << endl;
  return true;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  while (solve())
    ;
  return 0;
}
