#include<iostream>
#include<complex>
#include<vector>
#include<cmath>
#include<algorithm>
#include<cstdio>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

#define X real()
#define Y imag()

typedef double D;
typedef complex<D> P;
typedef pair<P, P> L;
typedef vector<P> Pol;

const D INF = 1e40;
const D EPS = 1e-8;

inline int sig(const D &r) {return (r < -EPS) ? -1 : (r > EPS) ? 1 : 0;}
inline bool eq(const D &a, const D &b) {return abs(a - b) < EPS;}
inline bool near(const P &a, const P &b) {return abs(a - b) < EPS;}

// 内積
inline D dot(const P &a, const P &b) {return a.X * b.X + a.Y * b.Y;}
// 外積
inline D det(const P &a, const P &b) {return a.X * b.Y - a.Y * b.X;}

// 線分のベクトル
inline P vec(const L &a) {return a.second - a.first;}

// 線分abに対する点xの位置
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
inline int ccw(const L &s, P p) {
  P a = vec(s);
  p -= s.first;
  D cr = det(a, p);
  if (eq(cr, 0)) {
    if (sig(dot(a, p)) < 0) return BACK;
    if (sig(norm(a) - norm(p)) < 0) return FRONT;
    return ON;
  }
  return (cr > 0) ? LEFT : RIGHT;
}

// 交差判定
inline bool iLSs(const L &a, const L &b) {return sig(det(vec(a), b.first - a.first)) * sig(det(vec(a), b.second - a.first)) < 0;}
inline bool iSSs(const L &a, const L &b) {return ((ccw(a, b.first) | ccw(a, b.second)) & (ccw(b, a.first) | ccw(b, a.second))) == (LEFT | RIGHT);}

// 交点
inline P pLL(const L &a, const L &b) {return a.first + vec(a) * (det(vec(b), b.first - a.first) / det(vec(b), vec(a)));}

// 比較関数
namespace std {
  inline bool operator<(const P &a, const P &b) {return eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X;}
}

// 角の内外判定 角abの内部にあれば正、辺上は0、外部は負
int sAP(P a, P b, P c) {return sig(det(a, c)) - sig(det(b, c)) - sig(det(a, b));}


int main() {
  while (true) {
    int n;
    cin >> n;
    if (n == 0) break;
    Pol pol;
    rep (i, n) {
      P p;
      cin >> p.X >> p.Y;
      pol.push_back(p);
    }
    vector<vector<P> > vvp;
    rep (i, n) {
      vector<P> vp;
      vp.push_back(pol[i]);
      vp.push_back(pol[(i + 1) % n]);
      rep (j, n) rep (k, j) if (i != j && i != k && (i + 1) % n != j && (i + 1) % n != k) {
	L l1 = L(pol[i], pol[(i + 1) % n]);
	L l2 = L(pol[j], pol[k]);
	if (!iLSs(l2, l1)) continue;
	P p = pLL(l1, l2);
	vp.push_back(p);
      }
      sort(vp.begin(), vp.end());
      vvp.push_back(vp);
    }
    vector<vector<bool> > vvb;
    rep (i, n) {
      vector<bool> vb;
      rep (j, n) {
	rep (k, vvp[j].size() - 1) {
	  P p = (vvp[j][k] + vvp[j][k + 1]) / (D)2;
	  L l = L(pol[i], p);
	  if (sAP(pol[(i + 1) % n] - pol[i], pol[(i + n - 1) % n] - pol[i], p - pol[i]) < 0) {
	    vb.push_back(false);
	    continue;;
	  }
	  bool ok = true;
	  rep (m, n) {
	    if (iSSs(l, L(pol[m], pol[(m + 1) % n]))) {
	      ok = false;
	      break;
	    }
	  }
	  vb.push_back(ok);
	}
      }
      vvb.push_back(vb);
    }
    vector<vector<unsigned long long> > flag(n);
    rep (i, n) {
      rep (j, vvb[i].size() / 64 + 1) {
	unsigned long long f = 0;
	rep (k, 64) {
	  if (j * 64 + k < int(vvb[i].size())) {
	    if (vvb[i][j * 64 + k]) f |= 1LL << k;
	  } else {
	    f |= 1LL << k;
	  }
	}
	flag[i].push_back(f);
      }
    }
    int res = 100;
    rep (i, 1 << n) if (__builtin_popcount(i) < res) {
      vector<unsigned long long> bit;
      rep (j, flag[0].size()) bit.push_back(0);
      rep (j, n) if (i & (1 << j)) {
	rep (k, flag[j].size()) {
	  bit[k] |= flag[j][k];
	}
      }
      bool ok = true;
      rep (j, bit.size()) {
	if (~bit[j] != 0) ok = false;
      }
      if (ok) {
	res = __builtin_popcount(i);
      }
    }
    cout << res << endl;
  }
  return 0;
}

Measured memory_bytes: 1304