#include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <utility>
#include <algorithm>
#include <cmath>
#include <bitset>
using namespace std;

#define MAX_PART 512

const double EPS = 1e-10;
const double INF = 1e12;
#define LE(n,m) ((n) < (m) + EPS)
#define GE(n,m) ((n) + EPS > (m))
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : VP{
    L(const P& a, const P& b){ resize(2); at(0)=a; at(1)=b; }
    L(){ resize(2); }
};
namespace std{
    bool operator < (const P& a, const P& b){
        return (a.X!=b.X) ? a.X<b.X : a.Y<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) <-EPS) return -1; //cw
    if(dot(b,c) < EPS) return +2; //c-a-b
    if(norm(b) < norm(c)) return -2; //a-b-c
    return 0; //a-c-b
}
bool intersectSP(const L& s, const P& p){
    return abs(s[0]-p) +abs(s[1]-p) -abs(s[1]-s[0]) < EPS;
}
bool intersectSS(const L& s, const L& t){
    for(int i=0; i<2; i++){
        for(int j=0; j<2; j++){
            if(s[i]==t[j]) return true;
        }
    }
    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 );
}
bool intersectLS(const L& l, const L& s){
    return cross(l[1]-l[0], s[0]-l[0])*
        cross(l[1]-l[0], s[1]-l[0]) < EPS;
}
P crosspointLL(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]);
    return m[0] + B /A *(m[1]-m[0]);
}

bool isParallel(const P &a, const P &b){
    return abs(cross(a,b)) < EPS;
}
bool isParallel(const L &a, const L &b){
    return isParallel(a[1]-a[0], b[1]-b[0]);
}

bool in_poly(const P &p, const VP &poly){
    int n = poly.size();
    int cn=0;
    for(int i=0; i<n; i++){
        if(intersectSP(L(poly[i], poly[(i+1)%n]), p)){
            return true;
        }
    }
    L ray(p, p+P(INF, 0));
    for(int i=0; i<n; i++){
        if((poly[i].Y <= p.Y && poly[(i+1)%n].Y > p.Y) ||
           (poly[i].Y > p.Y && poly[(i+1)%n].Y <= p.Y)){
            if(intersectSS(ray, L(poly[i],poly[(i+1)%n]))){
                cn++;
            }
        }
    }
    return cn%2 != 0;
}

bool isVisible(const L &l, const VP &poly){
    int n = poly.size();
    VP cp;
    for(int i=0; i<n; i++){
        L edge(poly[i], poly[(i+1)%n]);
        if(!isParallel(l, edge) && intersectSS(l, edge)){
            cp.push_back(crosspointLL(l, edge));
        }
    }
    sort(cp.begin(), cp.end());
    
    bool ret = true;
    for(int i=0; i<(int)cp.size()-1; i++){
        if(!in_poly((cp[i]+cp[i+1])/2.0, poly)){
            ret = false;
            break;
        }
    }
    return ret;
}

int bitcount(int n){
    n = (n & 0x55555555) + (n >> 1 & 0x55555555);
    n = (n & 0x33333333) + (n >> 2 & 0x33333333);
    n = (n & 0x0f0f0f0f) + (n >> 4 & 0x0f0f0f0f);
    n = (n & 0x00ff00ff) + (n >> 8 & 0x00ff00ff);
    return (n & 0x0000ffff) + (n >>16 & 0x0000ffff);
}


int main(){
    while(1){
        int n;
        cin >> n;
        if(n==0) break;
    
        VP poly(n);
        for(int i=0; i<n; i++){
            int x,y;
            cin >> x >> y;
            poly[i] = P(x,y);
        }

        //visible graph of vertices
        vector<vector<bool> > vvis(n, vector<bool>(n, false));
        for(int i=0; i<n; i++){
            vvis[i][i] = true;
            for(int j=i+1; j<n; j++){
                L ray(poly[i], poly[j]);
                if(isVisible(ray, poly)){
                    vvis[i][j] = vvis[j][i] = true;
                }
            }
        }

        //vis[i][j]=L(p1, p2);
        //from ith vertex, between p1 and p2 is visible
        vector<vector<L> > vis(n, vector<L>(n));
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                vis[i][j][0] = max(poly[j],poly[(j+1)%n]);
                vis[i][j][1] = min(poly[j],poly[(j+1)%n]);
            }
        }
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                L edge(poly[j], poly[(j+1)%n]);
                if(vvis[i][j] && vvis[i][(j+1)%n]){
                    vis[i][j][0] = min(edge[0], edge[1]);
                    vis[i][j][1] = max(edge[0], edge[1]);
                    continue;
                }
            
                for(int k=0; k<n; k++){
                    if(i==k || !vvis[i][k]) continue;
                    L ray(poly[i], poly[k]);
                    if(isParallel(ray, edge) || !intersectLS(ray, edge)) continue;                
                    P target = crosspointLL(ray, edge);
                    if(abs(poly[i]-target) < abs(poly[k]-target)) continue;
                    if(isVisible(L(poly[k], target), poly)){
                        vis[i][j][0] = min(vis[i][j][0], target);
                        vis[i][j][1] = max(vis[i][j][1], target);
                    }
                }
            }
        }

        vector<vector<P> > cut(n);
        for(int i=0; i<n; i++){ //edge
            for(int j=0; j<n; j++){
                cut[i].push_back(vis[j][i][0]);
                cut[i].push_back(vis[j][i][1]);
            }
            sort(cut[i].begin(), cut[i].end());
            cut[i].erase(unique(cut[i].begin(), cut[i].end()), cut[i].end());
        }
        
        vector<bitset<MAX_PART> > cover(n);
        int offset=0;
        for(int i=0; i<n; i++){ //edge
            for(int j=0; j<n; j++){ //vertex
                if(vis[j][i][0] < vis[j][i][1]){                    
                    int s=0,e=0;
                    for(int k=0; k<(int)cut[i].size(); k++){
                        if(vis[j][i][0] == cut[i][k]){
                            s = k;
                        }
                        if(vis[j][i][1] == cut[i][k]){
                            e = k;
                            break;

                        }
                    }
                    for(int k=s; k<e; k++){
                        cover[j][offset+k] = 1;
                    }
                }
            }
            offset += cut[i].size() -1;
        }
        
        bitset<MAX_PART> allbits;
        for(int i=0; i<offset; i++) allbits[i]=1;

        //brute force
        int ans = (n+1)/2; //obvious upper bound
        for(int i=0; i<(1<<n); i++){
            if(bitcount(i) > ans) continue;
            bitset<MAX_PART> tmp;
            for(int j=0; j<n; j++){
                if((i&(1<<j)) != 0){
                    tmp |= cover[j];
                }
            }
            if(tmp == allbits){
                ans = bitcount(i);
            }
        }
        cout << ans << endl;
    }
    return 0;
}

Measured memory_bytes: 3196