#include <bits/stdc++.h>
using namespace std;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "[";
  for (__typeof((t).begin()) it = (t).begin(); it != (t).end(); it++) {
    if (it != t.begin()) os << ",";
    os << *it;
  }
  os << "]";
  return os;
}
template <class T>
ostream &operator<<(ostream &os, const set<T> &t) {
  os << "{";
  for (__typeof((t).begin()) it = (t).begin(); it != (t).end(); it++) {
    if (it != t.begin()) os << ",";
    os << *it;
  }
  os << "}";
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}
template <class S, class T>
pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) {
  return pair<S, T>(s.first + t.first, s.second + t.second);
}
template <class S, class T>
pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) {
  return pair<S, T>(s.first - t.first, s.second - t.second);
}
namespace geom {
enum { TRUE = 1, FALSE = 0, BORDER = -1 };
const double INF = 1e8;
const double EPS = 1e-12;
const double PI = 3.1415926535897932384626;
inline int sig(const double &x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
inline int less(const double &x, const double &y) {
  return sig(x - y) ? x < y : BORDER;
}
inline double norm(const complex<double> &p) {
  return p.real() * p.real() + p.imag() * p.imag();
}
inline double inp(const complex<double> &a, const complex<double> &b) {
  return (conj(a) * b).real();
}
inline double outp(const complex<double> &a, const complex<double> &b) {
  return (conj(a) * b).imag();
}
inline complex<double> unit(const complex<double> &p) { return p / abs(p); }
inline complex<double> proj(const complex<double> &s,
                            const complex<double> &t) {
  return t * inp(s, t) / norm(t);
}
inline int ccw(const complex<double> &s, const complex<double> &t,
               const complex<double> &p, int adv = 0) {
  int res = sig(outp(t - s, p - s));
  if (res || !adv) return res;
  if (sig(inp(t - s, p - s)) < 0) return -2;
  if (sig(inp(s - t, p - t)) < 0) return 2;
  return 0;
}
struct L : public vector<complex<double>> {
  L(const complex<double> &p1, const complex<double> &p2) {
    this->push_back(p1);
    this->push_back(p2);
  }
  L() {}
  complex<double> dir() const { return ((*this)[1]) - ((*this)[0]); }
  int online(const complex<double> &p) const {
    return !sig(outp(p - ((*this)[0]), dir()));
  }
};
struct S : public L {
  S(const complex<double> &p1, const complex<double> &p2) : L(p1, p2) {}
  S() {}
  int online(const complex<double> &p) const {
    if (!sig(norm(p - ((*this)[0]))) || !sig(norm(p - ((*this)[1]))))
      return BORDER;
    return !sig(abs(((*this)[0]) - p) + abs(((*this)[1]) - p) -
                abs(((*this)[0]) - ((*this)[1])));
  }
};
struct C : public complex<double> {
  C() {}
  C(const complex<double> &p, const double r) : complex<double>(p), r(r) {}
  double r;
  int inside(const complex<double> &p) const {
    return less(norm(p - (*this)), r * r);
  }
};
struct F : public C {
  double s, t;
  F(const C &c, double ss, double tt) : C(c), s(ss), t(tt) {
    if (PI < s) s -= 2 * PI;
    if (PI < t) t -= 2 * PI;
  }
  int inside(const complex<double> &p) const {
    complex<double> v = p - (*this);
    if (!sig(norm(v))) return BORDER;
    double a = arg(v);
    if (t < s) {
      if ((!less(s, a) && !less(a, t)) || !less(norm(v), r * r)) return FALSE;
      return less(s, a) | less(a, t) | less(norm(v), r * r);
    } else {
      if (!less(s, a) || !less(a, t) || !less(norm(v), r * r)) return FALSE;
      return less(s, a) | less(a, t) | less(norm(v), r * r);
    }
  }
};
complex<double> crosspoint(const L &l, const L &m);
struct G : public vector<complex<double>> {
  G(size_type size = 0) : vector(size) {}
  S edge(int i) const {
    return S(((*this)[i]), ((*this)[i + 1 == size() ? 0 : i + 1]));
  }
  int contains(const complex<double> &p) const {
    double sum = .0;
    for (int i = 0; i < (int)(size()); i++) {
      if (S(((*this)[i]), ((*this)[(i + 1) % size()])).online(p)) return BORDER;
      sum += arg((((*this)[i]) - p) / (((*this)[(i + 1) % size()]) - p));
    }
    return !!sig(sum);
  }
  double area() const {
    double sum = 0;
    for (int i = 0; i < (int)(size()); i++)
      sum += outp(((*this)[i]), ((*this)[(i + 1) % size()]));
    return abs(sum / 2.);
  }
  G convex_hull(bool online = false) {
    if (size() < 2) return *this;
    sort((*this).begin(), (*this).end());
    G r;
    r.resize((int)size() * 2);
    int k = 0;
    for (int i = 0; i < size(); r[k++] = ((*this)[i++]))
      while (k > 1 && ccw(r[k - 2], r[k - 1], ((*this)[i])) < 1 - online) k--;
    int t = k;
    for (int i = (int)size() - 1; i >= 0; r[k++] = ((*this)[i--]))
      while (k > t && ccw(r[k - 2], r[k - 1], ((*this)[i])) < 1 - online) k--;
    r.resize(k - 1);
    return r;
  }
  G cut(const L &l) const {
    G g;
    for (int i = 0; i < (int)(size()); i++) {
      const S &s = edge(i);
      if (ccw(l[0], l[1], s[0], 0) >= 0) g.push_back(s[0]);
      if (ccw(l[0], l[1], s[0], 0) * ccw(l[0], l[1], s[1], 0) < 0)
        g.push_back(crosspoint(s, l));
    }
    return g;
  }
  G Voronoi(const vector<complex<double>> &p, const int t) const {
    G g = *this;
    for (int i = 0; i < (int)(p.size()); i++)
      if (i != t) {
        const complex<double> m = (p[t] + p[i]) * 0.5;
        g = g.cut(L(m, m + (p[i] - p[t]) * complex<double>(0, 1)));
      }
    return g;
  }
};
inline complex<double> proj(const complex<double> &s, const L &t) {
  return t[0] + proj(s - t[0], t[1] - t[0]);
}
inline complex<double> reflect(const complex<double> &s, const L &t) {
  return 2. * proj(s, t) - s;
}
inline S reflect(const S &s, const L &t) {
  return S(reflect(s[0], t), reflect(s[1], t));
}
int intersect(const S &s, const S &t) {
  const int p = ccw(t[0], t[1], s[0], 1) * ccw(t[0], t[1], s[1], 1);
  const int q = ccw(s[0], s[1], t[0], 1) * ccw(s[0], s[1], t[1], 1);
  return (p > 0 || q > 0) ? FALSE : (!p || !q) ? BORDER : TRUE;
}
int intersect(const S &s, const L &l) {
  if (l.online(s[0]) || l.online(s[1])) return BORDER;
  return (sig(outp(l.dir(), s[0] - l[0])) * sig(outp(l.dir(), s[1] - l[0])) <=
          0);
}
double dist2(const L &l, const complex<double> &p) {
  return norm(outp(l.dir(), p - l[0])) / norm(l.dir());
}
double dist2(const S &s, const complex<double> &p) {
  if (inp(p - s[0], s.dir()) < EPS) return norm(p - s[0]);
  if (inp(p - s[1], -s.dir()) < EPS) return norm(p - s[1]);
  return dist2((const L &)s, p);
}
double dist2(const S &s, const L &l) {
  return intersect(s, l) ? .0 : min(dist2(l, s[0]), dist2(l, s[1]));
}
double dist2(const S &s, const S &t) {
  return intersect(s, t) ? .0
                         : min(min(dist2(s, t[0]), dist2(t, s[0])),
                               min(dist2(s, t[1]), dist2(t, s[1])));
}
template <class T>
double dist2(const G &g, const T &t) {
  double res = INF;
  for (int i = 0; i < (int)(g.size()); i++) res = min(res, dist2(g.edge(i), t));
  return res;
}
template <class S, class T>
double dist(const S &s, const T &t) {
  return sqrt(dist2(s, t));
}
inline int intersect(const C &a, const C &b) {
  return less((a.r - b.r) * (a.r - b.r), norm(a - b)) +
         less(norm(a - b), (a.r + b.r) * (a.r + b.r)) - 1;
}
inline int intersect(const C &c, const L &l) {
  return less(dist2(l, c), c.r * c.r);
}
inline int intersect(const C &c, const S &s) {
  int d = less(dist2(s, c), c.r * c.r);
  if (d != TRUE) return d;
  int p = c.inside(s[0]), q = c.inside(s[1]);
  return (p < 0 || q < 0) ? BORDER : p & q;
}
inline S crosspoint(const C &c1, const C &c2) {
  if (!intersect(c1, c2)) return S();
  double d = abs(c1 - c2);
  double x = (c1.r * c1.r - c2.r * c2.r + d * d) / (2 * d);
  double h = sqrt(c1.r * c1.r - x * x);
  complex<double> u = unit(c2 - c1);
  return S(c1 + u * x + u * complex<double>(0, -1) * h,
           c1 + u * x + u * complex<double>(0, 1) * h);
}
inline complex<double> crosspoint(const L &l, const L &m) {
  double A = outp(l.dir(), m.dir()), B = outp(l.dir(), l[1] - m[0]);
  if (!sig(abs(A)) && !sig(abs(B))) return m[0];
  if (abs(A) < EPS) assert(false);
  return m[0] + B / A * (m[1] - m[0]);
}
inline S crosspoint(const C &c, const L &l) {
  double d2 = dist2(l, c);
  if (c.r * c.r + EPS < d2) return S();
  complex<double> m = proj(c, l);
  complex<double> u = unit(l[1] - l[0]);
  double d = sqrt(c.r * c.r - d2);
  return S(m + u * d, m - u * d);
}
inline vector<complex<double>> crosspoint(const C &c, const S &s) {
  vector<complex<double>> res = crosspoint(c, (const L &)s);
  for (int i = ((int)(res.size()) - 1); i >= 0; i--) {
    if (inp(res[i] - s[0], s.dir()) * inp(res[i] - s[1], -s.dir()) < EPS)
      res.erase(res.begin() + i);
  }
  return res;
}
inline double commonarea(const C &a, const C &b) {
  if (less(norm(a - b), (a.r - b.r) * (a.r - b.r)) == TRUE)
    return min(a.r * a.r, b.r * b.r) * PI;
  if (less((a.r + b.r) * (a.r + b.r), norm(a - b)) == TRUE) return .0;
  double d = abs(a - b);
  double rc = (d * d + a.r * a.r - b.r * b.r) / (2 * d);
  double theta = acos(rc / a.r);
  double phi = acos((d - rc) / b.r);
  return a.r * a.r * theta + b.r * b.r * phi - d * a.r * sin(theta);
}
vector<L> CommonTangent(C c1, C c2) {
  if (c1.r > c2.r) swap(c1, c2);
  double d = abs(c1 - c2);
  vector<L> res;
  if (d < EPS) return res;
  if (d + EPS > c1.r + c2.r) {
    complex<double> crs = (c1 * c2.r + c2 * c1.r) / (c1.r + c2.r);
    double rad = asin(c1.r / abs(crs - c1));
    res.push_back(L(crs, crs + (c1 - crs) * polar(1., rad)));
    res.push_back(L(crs, crs + (c1 - crs) * polar(1., -rad)));
  }
  if (c1.r + d + EPS > c2.r) {
    double rad = 0.5 * PI + asin((c2.r - c1.r) / d);
    complex<double> v = unit(c2 - c1) * polar(1., rad);
    if (c1.r + d - EPS < c2.r) {
      res.push_back(
          L(c1 + v * c1.r, c1 + v * c1.r + (c1 - c2) * complex<double>(0, 1)));
    } else {
      res.push_back(L(c1 + v * c1.r, c2 + v * c2.r));
      v = 2. * proj(v, c2 - c1) - v;
      res.push_back(L(c1 + v * c1.r, c2 + v * c2.r));
    }
  }
  return res;
}
vector<vector<int>> visibility(const G &g) {
  int n = g.size();
  vector<vector<int>> vg(n, vector<int>(n));
  for (int i = 0; i < (int)(n); i++)
    for (int j = 0; j < (int)(i + 1); j++) {
      if (i == j || (i + 1) % n == j || (j + 1) % n == i || [&]() {
            for (int k = 0; k < (int)(n); k++)
              if (intersect(g.edge(k), S(g[i], g[j])) == TRUE ||
                  !g.contains((g[i] + g[j]) * .5))
                return false;
            return true;
          }())
        vg[i][j] = vg[j][i] = 1;
    }
  return vg;
}
struct Arrangement {
  struct AEdge {
    int u, v, t;
    double cost;
    AEdge(int u = 0, int v = 0, int t = 0, double cost = 0)
        : u(u), v(v), t(t), cost(cost) {}
  };
  vector<complex<double>> p;
  vector<vector<AEdge>> g;
  Arrangement() {}
  Arrangement(vector<S> seg) {
    int m = seg.size();
    for (int i = 0; i < (int)(m); i++) {
      p.push_back(seg[i][0]);
      p.push_back(seg[i][1]);
      for (int j = 0; j < (int)(i); j++)
        if (sig(outp(seg[i].dir(), seg[j].dir())) &&
            intersect(seg[i], seg[j]) == TRUE)
          p.push_back(crosspoint(seg[i], seg[j]));
    }
    sort((p).begin(), (p).end());
    p.erase(unique(p.begin(), p.end()), p.end());
    ;
    int n = p.size();
    g.resize(n);
    for (int i = 0; i < (int)(m); i++) {
      S &s = seg[i];
      vector<pair<double, int>> ps;
      for (int j = 0; j < (int)(n); j++)
        if (s.online(p[j])) ps.emplace_back(norm(p[j] - s[0]), j);
      sort((ps).begin(), (ps).end());
      for (int j = 0; j < (int)((int)ps.size() - 1); j++) {
        const int u = ps[j].second;
        const int v = ps[j + 1].second;
        g[u].emplace_back(u, v, 0, abs(p[u] - p[v]));
        g[v].emplace_back(v, u, 0, abs(p[u] - p[v]));
      }
    }
  }
  int getIdx(complex<double> q) {
    auto it = lower_bound((p).begin(), (p).end(), q);
    if (it == p.end() || *it != q) return -1;
    return it - p.begin();
  }
};
struct min_ball {
  complex<double> center;
  double radius2;
  min_ball(const vector<complex<double>> &p) {
    for (__typeof((p).begin()) it = (p).begin(); it != (p).end(); it++)
      ps.push_back(*it);
  }
  min_ball &compile() {
    m = 0;
    center = complex<double>(0, 0);
    radius2 = -1;
    make_ball(ps.end());
    return *this;
  }

 private:
  list<complex<double>> ps;
  list<complex<double>>::iterator supp_end;
  int m;
  complex<double> v[3], c[3];
  double z[3], r[3];
  void pop() { --m; }
  void push(const complex<double> &p) {
    if (m == 0) {
      c[0] = p;
      r[0] = 0;
    } else {
      double e = norm(p - c[m - 1]) - r[m - 1];
      complex<double> delta = p - c[0];
      v[m] = p - c[0];
      for (int i = 1; i < m; ++i) v[m] -= v[i] * inp(v[i], delta) / z[i];
      z[m] = inp(v[m], v[m]);
      c[m] = c[m - 1] + e * v[m] / z[m] * .5;
      r[m] = r[m - 1] + e * e / z[m] * .25;
    }
    center = c[m];
    radius2 = r[m];
    ++m;
  }
  void make_ball(list<complex<double>>::iterator i) {
    supp_end = ps.begin();
    if (m == 3) return;
    for (list<complex<double>>::iterator k = ps.begin(); k != i;) {
      list<complex<double>>::iterator j = k++;
      if (norm(*j - center) > radius2) {
        push(*j);
        make_ball(j);
        pop();
        move_to_front(j);
      }
    }
  }
  void move_to_front(list<complex<double>>::iterator j) {
    if (supp_end == j) ++supp_end;
    ps.splice(ps.begin(), ps, j);
  }
};
}  // namespace geom
using namespace geom;
namespace std {
bool operator<(const complex<double> &a, const complex<double> &b) {
  return sig(a.real() - b.real()) ? a.real() < b.real() : a.imag() < b.imag();
}
bool operator==(const complex<double> &a, const complex<double> &b) {
  return !sig(norm(a - b));
}
istream &operator>>(istream &is, complex<double> &p) {
  double x, y;
  is >> x >> y;
  p = complex<double>(x, y);
  return is;
}
istream &operator>>(istream &is, L &l) {
  l.resize(2);
  return is >> l[0] >> l[1];
}
istream &operator>>(istream &is, C &c) {
  return is >> (complex<double> &)c >> c.r;
}
}  // namespace std
int n, m;
int main() {
  ios::sync_with_stdio(false);
  while (cin >> n, n) {
    G g(n);
    for (int i = 0; i < (int)(n); i++) cin >> g[i];
    vector<vector<int>> vg = visibility(g);
    vector<int> mask(n);
    for (int i = 0; i < (int)(n); i++)
      for (int j = 0; j < (int)(n); j++)
        if (vg[i][j]) mask[i] |= 1 << j;
    vector<int> dp(1 << n, INF);
    dp[0] = 0;
    for (int i = 0; i < (int)(1 << n); i++)
      for (int j = 0; j < (int)(n); j++) {
        dp[i | mask[j]] = min(dp[i | mask[j]], dp[i] + 1);
      }
    cout << dp[(1 << n) - 1] << endl;
  }
  return 0;
}
