#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;
inline int sgn(double x) {
    if (x>eps) return 1;
    if (x<-eps) return -1;
    return 0;
}
inline double add(double a,double b) {
    if (abs(a+b)<eps*(abs(a)+abs(b))) return 0;
    return a+b;
}
struct P {
    double x,y;
    P(){}
    P(double x,double y):x(x),y(y){}
    P operator+(P p) {
        return P(add(x,p.x),add(y,p.y));
    }
    P operator-(P p) {
        return P(add(x,-p.x),add(y,-p.y));
    }
    P operator*(double d) {
        return P(x*d,y*d);
    }
    bool operator==(const P &rhs)const{
        return add(x,-rhs.x)==0&&add(y,-rhs.y)==0;
    }
    bool operator<(const P &rhs)const{
        return x<rhs.x;
    }
    inline double dot(P p) {
        return add(x*p.x,y*p.y);
    }
    inline double det(P p) {
        return add(x*p.y,-y*p.x);
    }
} p[45];
bool isparallel(P p1,P p2,P q1,P q2) {
    return (p1-p2).det(q1-q2)==0;
}
bool on_line(P p1,P p2,P q) {
    return (p1-q).det(p2-q)==0&&(p1-q).dot(p2-q)<=0;
}
bool on_seg(P p1,P p2,P q) {
    return (p1-q).det(p2-q)==0&&(p1-q).dot(p2-q)<0;
}
P intersection(P p1,P p2,P q1,P q2) {
    return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));
}
int n,res,id[45];
long long cover[45],super[45];
vector<long long> G[45];
vector<P> vec;
inline bool contains(P s) {
    int cnt=0;
    for (int i=0;i<n;++i) {
        P a=p[i],b=p[i+1];
        if (on_line(a,b,s)) return true;
        if (a.y>b.y) swap(a,b);
        int x=sgn((a-s).det(b-s));
        int y=sgn(b.y-s.y);
        int z=sgn(s.y-a.y);
        if (x>0&&y>=0&&z>0) ++cnt;
    }
    return cnt&1;
}
inline bool check(P s,P t) {
    vec.clear();
    for (int i=0;i<n;++i)
        if (!isparallel(s,t,p[i],p[i+1])) {
            P o=intersection(s,t,p[i],p[i+1]);
            if (on_seg(s,t,o)&&on_seg(p[i],p[i+1],o)) return false;
            if (on_seg(s,t,o)&&on_line(p[i],p[i+1],o)) vec.push_back(o);
        }
    vec.push_back(s);
    vec.push_back(t);
    sort(vec.begin(),vec.end());
    vec.erase(unique(vec.begin(),vec.end()),vec.end());
    for (int i=0;i+1<(int)vec.size();++i) {
        if (vec[i]==vec[i+1]) continue;
        P t=P((vec[i].x+vec[i+1].x)/2,(vec[i].y+vec[i+1].y)/2);
        if (!contains(t)) return false;
    }
    return true;
}
void dfs(long long mask,int x,int cnt) {
    if (x==n) {
        res=cnt;
        return;
    }
    int u=id[x];
    if ((mask>>u)&1) {
        dfs(mask,x+1,cnt);
        return;
    }
    int best=cnt;
    long long tmp=mask;
    for (int i=0;i<n;++i)
        if (!(tmp>>i&1)) {
            tmp|=super[i];
            ++best;
        }
    if (best>res) return;
    for (int i=0;i<(int)G[u].size();++i) dfs(mask|G[u][i],x+1,cnt+1);
}
inline int cnt(long long x) {
    int ret=0;
    while (x) {
        ++ret;
        x-=x&-x;
    }
    return ret;
}
inline bool cmp1(long long x,long long y) {
    return cnt(x)<cnt(y);
}
inline bool cmp2(int x,int y) {
    return G[x].size()<G[y].size();
}
int main()
{
    scanf("%d",&n);
    for (int i=0;i<n;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
    p[n].x=p[0].x,p[n].y=p[0].y;
    for (int i=0;i<n;++i)
        for (int j=i+2;j<n;++j) {
            if ((j+1)%n==i) continue;
            if (check(p[i],p[j])) {
                cover[i]|=1LL<<j;
                cover[j]|=1LL<<i;
            }
        }
    for (int i=0;i<n;++i) {
        cover[i]|=1LL<<i;
        cover[i]|=1LL<<((i+1)%n);
        cover[i]|=1LL<<((i+n-1)%n);
    }
    for (int i=0;i<n;++i)
        for (int j=0;j<n;++j)
            if (cover[i]>>j&1) {
                G[i].push_back(cover[j]);
                super[i]|=cover[j];
            }
    for (int i=0;i<n;++i) {
        sort(G[i].begin(),G[i].end(),cmp1);
        id[i]=i;
    }
    sort(id,id+n,cmp2);
    res=n;
    dfs(0LL,0,0);
    printf("%d\n",res);
    return 0;
}



Measured memory_bytes: 3316