#include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define pb push_back
#define dbg(...) do{cerr<<__LINE__<<": ";dbgprint(#__VA_ARGS__, __VA_ARGS__);}while(0);

using namespace std;

namespace std{template<class S,class T>struct hash<pair<S,T>>{size_t operator()(const pair<S,T>&p)const{return ((size_t)1e9+7)*hash<S>()(p.first)+hash<T>()(p.second);}};template<class T>struct hash<vector<T>>{size_t operator()(const vector<T> &v)const{size_t h=0;for(auto i : v)h=h*((size_t)1e9+7)+hash<T>()(i)+1;return h;}};}
template<class T>ostream& operator<<(ostream &os, const vector<T> &v){os<<"[ ";rep(i,v.size())os<<v[i]<<(i==v.size()-1?" ]":", ");return os;}template<class T>ostream& operator<<(ostream &os,const set<T> &v){os<<"{ "; for(const auto &i:v)os<<i<<", ";return os<<"}";}
template<class T,class U>ostream& operator<<(ostream &os,const map<T,U> &v){os<<"{";for(const auto &i:v)os<<" "<<i.first<<": "<<i.second<<",";return os<<"}";}template<class T,class U>ostream& operator<<(ostream &os,const pair<T,U> &p){return os<<"("<<p.first<<", "<<p.second<<")";}
void dbgprint(const string &fmt){cerr<<endl;}template<class H,class... T>void dbgprint(const string &fmt,const H &h,const T&... r){cerr<<fmt.substr(0,fmt.find(","))<<"= "<<h<<" ";dbgprint(fmt.substr(fmt.find(",")+1),r...);}
typedef long long ll;typedef vector<int> vi;typedef pair<int,int> pi;const double EPS = 1e-8, INF = 1e12, PI = acos(-1.0);
typedef complex<double> P;
namespace std{
	bool operator<(const P& a, const P& b){
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
inline double cross(const P& a, const P& b){ return imag(conj(a)*b); }
inline double dot(const P& a, const P& b){ return real(conj(a)*b); }
struct L : public vector<P>{
	L(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
};
typedef vector<P> G;
inline int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if(cross(b, c) >  EPS)   return +1;      // counter clockwise
	if(cross(b, c) < -EPS)   return -1;      // clockwise
	if(dot(b, c)   < -EPS)   return +2;      // c--a--b on line
	if(norm(b)+EPS <norm(c)) return -2;      // a--b--c on line
	return 0;                                   // c is between a and b (inclusive)
}
bool intersectLS(const L &l, const L &s) {
  return cross(l[1]-l[0], s[0]-l[0])*       // s[0] is left of l
         cross(l[1]-l[0], s[1]-l[0]) < EPS; // s[1] is right of l
}
bool intersectSS(const L &s, const L &t) {
  return 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;
}
P crosspoint(const L &l, const L &m) {
	double A = cross(l[1] - l[0], m[1] - m[0]);
	double B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
	if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
	return m[0] + B / A * (m[1] - m[0]);
}
G convex_hull(G ps) {
	int n = ps.size(), k = 0;
	sort(ps.begin(), ps.end());
	G ch(2*n);
	for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
		while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
	for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
		while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
	ch.resize(k-1);
	return ch;
}
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
double area2(const G& g) {
	double A = 0;
	for (int i = 0; i < g.size(); ++i) 
		A += cross(curr(g, i), next(g, i));
	return A;
}
enum { OUT, ON, IN };
int contains(const G& g, const P& p) {
	bool in = false;
	for (int i = 0; i < g.size(); ++i) {
		P a = curr(g,i) - p, b = next(g,i) - p;
		if (imag(a) > imag(b) + EPS) swap(a, b);
		if (imag(a) < EPS && EPS < imag(b))
		if (cross(a, b) < -EPS) in = !in;
		if (abs(cross(a, b)) < EPS && dot(a, b) < EPS) return ON;
	}
	return in ? IN : OUT;
}

int main(){
	cin.tie(0); cin.sync_with_stdio(0);
	int n;
	while(cin >> n, n){
		G ps;
		rep(i, n){ int x, y; cin >> x >> y; ps.emplace_back(x, y); }
		//各辺を任意の二頂点を結ぶ直線との交点で分割
		vector<G> points;
		rep(i, n){
			G pts = { ps[i], ps[(i + 1) % n] };
			L e(ps[i], ps[(i + 1) % n]);
			rep(j, n) rep(k, j){
				L l(ps[j], ps[k]);
				if(!intersectLS(l, e)) continue;
				pts.pb(crosspoint(l, e));
			}
			sort(all(pts), [&](P a, P b){
				return abs(ps[i] - a) < abs(ps[i] - b);
			});
			//近い点は消す
			rep(j, (int)pts.size() - 1) if(abs(pts[j] - pts[j + 1]) < EPS){
				pts.erase(pts.begin() + j);
				j--;
			}
			//中点を足す
			int sz = (int)pts.size() - 1;
			rep(j, sz) pts.pb((pts[j] + pts[j + 1]) / 2.0);
			sort(all(pts), [&](P a, P b){
				return abs(ps[i] - a) < abs(ps[i] - b);
			});
			swap(pts[1], pts.back());
			points.pb(pts);
		}
		//rep(i, n) dbg(i, points[i]);
		
		vector<vi> flags;
		for(const auto &pts : points){
			vi fs;
			for(const P &p : pts){
				int f = 0;
				rep(i, n){
					L l(p, ps[i]);
					G crs = {l[0], l[1]};
					
					//辺と交差してたらダメ
					rep(j, n){
						L e(ps[j], ps[(j + 1) % n]);
						if(intersectSS(l, e)) goto NG;
					}
					
					//外に出てたらダメ
					rep(j, n) if(ccw(l[0], ps[j], l[1]) == -2) crs.pb(ps[j]);
					sort(all(crs), [&](P a, P b){
						return abs(l[0] - a) < abs(l[0] - b);
					});
					rep(j, (int)crs.size()-1){
						if(contains(ps, (crs[j] + crs[j+1]) / 2.0) == OUT){
							/*
							dbg(crs[j], crs[j+1]);
							dbg((crs[j] + crs[j+1]) / 2.0);
							*/
							goto NG;
						}
					}
					f |= 1 << i;
					NG:;
				}
				fs.pb(f);
			}
			flags.pb(fs);
		}
		
		int ans = (n + 1) / 2;
		rep(mask, 1 << n){
			int sz = __builtin_popcount(mask);
			if(sz >= ans) continue;
			
			for(const vi fs : flags) for(int f : fs) if(!(f & mask)) goto NEXT;
			
			ans = min(ans, sz);
			NEXT:;
		}
		cout << ans << endl;
	}
	return 0;
}


Measured memory_bytes: 3304