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

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

using namespace std;

const double EPS=1e-6;

inline int popcount(int x){
	x=((x>>1)&0x55555555)+(x&0x55555555);
	x=((x>>2)&0x33333333)+(x&0x33333333);
	x=((x>>4)+x)&0x0f0f0f0f;
	x+=(x>>8);
	x+=(x>>16);
	return x&0x3f;
}

struct point{
	double x,y;
	point():x(0),y(0){}
	point(double x,double y):x(x),y(y){}
	point &operator+=(const point &a){ x+=a.x; y+=a.y; return *this; }
	point &operator-=(const point &a){ x-=a.x; y-=a.y; return *this; }
	point &operator*=(double c){ x*=c; y*=c; return *this; }
	point &operator/=(double c){ x/=c; y/=c; return *this; }
	point operator+(const point &a)const{ return point(x+a.x,y+a.y); }
	point operator-(const point &a)const{ return point(x-a.x,y-a.y); }
	point operator/(double c)const{ return point(x/c,y/c); }
	point operator-()const{ return point(-x,-y); }
	bool operator< (const point &a)const{ return x+EPS<a.x || abs(x-a.x)<EPS && y+EPS<a.y; }
	bool operator==(const point &a)const{ return abs(x-a.x)<EPS && abs(y-a.y)<EPS; }
	bool operator!=(const point &a)const{ return abs(x-a.x)>EPS || abs(y-a.y)>EPS; }
};

point operator*(double c,const point &a){ return point(c*a.x,c*a.y); }

double dot(const point &a,const point &b){ return a.x*b.x+a.y*b.y; }

double cross(const point &a,const point &b){ return a.x*b.y-a.y*b.x; }

double abs(const point &a){ return sqrt(a.x*a.x+a.y*a.y); }

double abs2(const point &a){ return a.x*a.x+a.y*a.y; }

struct line{
	point a,b;
	line(){}
	line(const point &a,const point &b):a(a),b(b){}
	bool operator==(const line &L)const{ return abs(cross(b-a,L.b-L.a))<EPS && abs(cross(L.a-a,L.b-a))<EPS; }
};

struct segment{
	point a,b;
	segment(){}
	segment(const point &a,const point &b):a(a),b(b){}
	operator line()const{ return line(a,b); }
};

typedef vector<point> polygon;

point proj(const point &p,const line &L){ return L.a+dot(p-L.a,L.b-L.a)/abs2(L.b-L.a)*(L.b-L.a); }

enum{CCW=1,CW=-1,ON=0};
int ccw(const point &a,const point &b,const point &c){
	double rdir=cross(b-a,c-a);
	if(rdir> EPS) return CCW;
	if(rdir<-EPS) return CW;
	return ON;
}

bool intersect(const line &L,const segment &S){
	return cross(L.b-L.a,S.a-L.a)*cross(L.b-L.a,S.b-L.a)<EPS;
}

bool intersect(const segment &S1,const segment &S2){
	if(max(S1.a.x,S1.b.x)+EPS<min(S2.a.x,S2.b.x)
	|| max(S1.a.y,S1.b.y)+EPS<min(S2.a.y,S2.b.y)
	|| max(S2.a.x,S2.b.x)+EPS<min(S1.a.x,S1.b.x)
	|| max(S2.a.y,S2.b.y)+EPS<min(S1.a.y,S1.b.y)) return false;
	return ccw(S1.a,S1.b,S2.a)*ccw(S1.a,S1.b,S2.b)<=0
		&& ccw(S2.a,S2.b,S1.a)*ccw(S2.a,S2.b,S1.b)<=0;
}

bool cover(const segment &S,const point &p){
	return abs(cross(S.a-p,S.b-p))<EPS && dot(S.a-p,S.b-p)<EPS;
}

bool cover(const polygon &F,const point &p){
	int n=F.size();
	bool res=false;
	rep(i,n){
		point v1=F[i]-p,v2=F[(i+1)%n]-p;
		if(v1.y>v2.y) swap(v1,v2);
		if(v1.y<EPS && EPS<v2.y && cross(v1,v2)>EPS) res=!res;
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS) return true;
	}
	return res;
}

point get_intersect(const line &L,const segment &S){
	double a1=cross(S.b-S.a,L.b-L.a);
	double a2=cross(S.b-S.a,S.b-L.a);
	if(abs(a1)<EPS) return S.a;
	return L.a+a2/a1*(L.b-L.a);
}

point get_intersect(const segment &S1,const segment &S2){
	double a1=cross(S1.b-S1.a,S2.b-S2.a);
	double a2=cross(S1.b-S1.a,S1.b-S2.a);
	if(abs(a1)<EPS){
		if(cover(S1,S2.a)) return S2.a;
		if(cover(S1,S2.b)) return S2.b;
		if(cover(S2,S1.a)) return S1.a;
		return S1.b;
	}
	return S2.a+a2/a1*(S2.b-S2.a);
}

bool can_go_straight(const point &s,const point &g,const polygon &F){
	int n=F.size(),m=0;
	point p[16];
	segment S(s,g);
	rep(i,n){
		segment T(F[i],F[(i+1)%n]);
		if(intersect(S,T)) p[m++]=get_intersect(S,T);
	}
	sort(p,p+m);

	rep(i,m-1){
		point c=(p[i]+p[i+1])/2;
		if(!cover(F,c)) return false;
	}
	return true;
}

int main(){
	for(int n;scanf("%d",&n),n;){
		polygon F(n);
		rep(i,n) scanf("%lf%lf",&F[i].x,&F[i].y);

		vector<point> P(F.begin(),F.end());
		rep(i,n) rep(j,i) {
			line L(F[i],F[j]);
			rep(k,n){
				segment S(F[k],F[(k+1)%n]);
				if(intersect(L,S)) P.push_back(get_intersect(L,S));
			}
		}
		sort(P.begin(),P.end());
		P.erase(unique(P.begin(),P.end()),P.end());

		vector<point> on[16];
		rep(i,n){
			segment S(F[i],F[(i+1)%n]);
			rep(j,P.size()) if(cover(S,P[j])) on[i].push_back(P[j]);
			sort(on[i].begin(),on[i].end());
		}

		int ans=n;
		rep(S,1<<n){
			int tmp=popcount(S);
			if(tmp>=ans) continue;

			bool ok=true;
			rep(i,n) rep(j,(int)on[i].size()-1) {
				point c=(on[i][j]+on[i][j+1])/2;
				bool ok2=false;
				rep(k,n) if(S>>k&1 && can_go_straight(c,F[k],F)) { ok2=true; break; }
				if(!ok2){
					ok=false;
					goto END;
				}
			}
			END:

			if(ok) ans=tmp;
		}
		printf("%d\n",ans);
	}

	return 0;
}

Measured memory_bytes: 1124