#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#define pb push_back
#define rep(i,n) for (int i = 0; i < n; ++i)
#define rrep(i,n) for (int i = 1; i <= n; ++i)
#define drep(i,n) for (int i = (n)-1; i >= 0; --i)
#define mins(x,y) x = min(x,y)
#define maxs(x,y) x = max(x,y)
#define rng(x) x.begin(),x.end()
#define sz(x) int((x).size())
#define fi first
#define se second
#define double long double
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<P> vp;
typedef vector<ll> vl;

const int MX = 100005;
const int INF = 1001001001;

const double eps = 1e-9;
struct V {
  double x, y;
  V(double x=0, double y=0):x(x),y(y) {}
  V operator+(V t) { return V(x+t.x, y+t.y);}
  V operator-(V t) { return V(x-t.x, y-t.y);}
  V operator*(double t) { return V(x*t, y*t);}
  V operator/(double t) { return V(x/t, y/t);}
  double dot(V t) { return x*t.x+y*t.y;}
  double cross(V t) { return x*t.y-y*t.x;}
  double norm2() { return x*x+y*y;}
  double norm() { return sqrt(norm2());}
  V normalize() { return V(x/norm(), y/norm());}
  V rotate90() { return V(-y,x);}
};
typedef vector<V> Poly;
struct Line {
  V s, t;
  Line(V s=V(0,0), V t=V(0,0)):s(s),t(t) {}
  V dir() { return t-s;}
  V normalize() { return dir().normalize();}
  double norm() { return dir().norm();}
  int ccw(V p) {
    if (dir().cross(p-s) > eps) return +1;
    if (dir().cross(p-s) < -eps) return -1;
    if (dir().dot(p-s) < -eps) return +2;
    if (dir().norm()+eps < (p-s).norm()) return -2;
    return 0;
  }
  double distLP(V p) { return abs(dir().cross(p-s)/norm());}
  V proj(V p) {
    double a = (p-s).dot(dir())/dir().norm2();
    return s + dir()*a;
  }
};
struct C {
  V o; double r;
  C(V o=V(0,0), double r=0):o(o),r(r) {}
  Poly xp(Line l) {
    Poly res;
    double h = l.distLP(o);
    if (h > r+eps) return res;
    V p = l.proj(o);
    double d = sqrt(max((double)0.0, r*r-h*h));
    V q = l.normalize();
    res.pb(p+q*d);
    res.pb(p-q*d);
    return res;
  }
  Poly tang(V p) {
    Poly res;
    double a = (p-o).norm2(), b = a-r*r;
    if (b < -eps) return res;
    b = max(b,(double)0.0);
    V h = o+(p-o)*(r*r/a);
    V v = (p-o).rotate90()*(r*sqrt(b)/a);
    res.pb(h+v);
    res.pb(h-v);
    return res;
  }
  vector<Line> tangC(C c) {
    vector<Line> res;
    if (abs(r-c.r) < eps) {
      V v = (c.o-o).rotate90().normalize()*r;
      res.pb(Line(o+v,c.o+v));
      res.pb(Line(o-v,c.o-v));
    } else {
      V p = (o*-c.r+c.o*r) / (r-c.r);
      Poly a = tang(p), b = c.tang(p);
      rep(i,sz(a))rep(j,sz(b)) {
        if (abs(Line(a[i],b[j]).ccw(p)) == 2) res.pb(Line(a[i],b[j]));
      }
    }
    V p = (o*c.r+c.o*r) / (r+c.r);
    Poly a = tang(p), b = c.tang(p);
    rep(i,sz(a))rep(j,sz(b)) {
      if (Line(a[i],b[j]).ccw(p) == 0) res.pb(Line(a[i],b[j]));
    }
    return res;
  }
};

int n;
C a;
vector<C> c;
int dp[1<<15];
vi f;

void add(Line l, int i) {
  int x = 1<<i;
  auto ps = a.xp(l);
  if (sz(ps) == 0) return;
  V p = ps[0];
  ps = c[i].xp(l);
  if (sz(ps) == 0) return;
  V q = ps[0];
  rep(j,n) if (i != j) {
    ps = c[j].xp(l);
    if (sz(ps) == 0) continue;
    V s = ps[0];
    if (Line(s,q).ccw(p) != 0) x |= 1<<j;
  }
  f.pb(x);
}

int main() {
  cin >> n;
  c.resize(n);
  --n;
  cin >> a.o.x >> a.o.y >> a.r;
  rep(i,n) cin >> c[i].o.x >> c[i].o.y >> c[i].r;
  rep(i,n) f.pb(1<<i);
  rep(i,n)rep(j,i) {
    auto ls = c[i].tangC(c[j]);
    for (Line l : ls) add(l, i);
  }
  rep(i,n) {
    auto ls = c[i].tangC(a);
    for (Line l : ls) add(l, i);
  }
  rep(i,1<<n) dp[i] = INF;
  dp[0] = 0;
  sort(rng(f)); f.erase(unique(rng(f)),f.end());
  rep(i,1<<n) for (int x : f) mins(dp[i|x], dp[i]+1);
  cout<<dp[(1<<n)-1]<<endl;
  return 0;
}

Measured memory_bytes: 3368