#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
using namespace std;
const double eps = 1e-9;
struct Point {
  double first, second;
  Point() : first(0), second(0) {}
  Point(double _x, double _y) : first(_x), second(_y) {}
  Point(pair<double, double> t) : first(t.first), second(t.second) {}
  inline double squaredDistance(Point p) const {
    return (first - p.first) * (first - p.first) +
           (second - p.second) * (second - p.second);
  }
  inline double distance(Point p) const {
    return sqrt((first - p.first) * (first - p.first) +
                (second - p.second) * (second - p.second));
  }
  inline bool equals(Point other) const {
    return abs(first - other.first) < eps && abs(second - other.second) < eps;
  }
};
inline Point operator+(const Point &a, const Point &b) {
  return Point(a.first + b.first, a.second + b.second);
}
inline Point operator-(const Point &a, const Point &b) {
  return Point(a.first - b.first, a.second - b.second);
}
inline Point operator*(const Point &a, const double &b) {
  return Point(a.first * b, a.second * b);
}
inline Point operator/(const Point &a, const double &b) {
  return Point(a.first / b, a.second / b);
}
inline double vec(const Point &a, const Point &b) {
  return a.first * b.second - b.first * a.second;
}
inline double scal(const Point &a, const Point &b) {
  return a.first * b.first + a.second * b.second;
}
struct Line {
  double a, b, c;
  Line() : a(0), b(0), c(0) {}
  Line(double _a, double _b, double _c) : a(_a), b(_b), c(_c) { normalize(); }
  Line(const Point &t1, const Point &t2) {
    a = t2.second - t1.second;
    b = t1.first - t2.first;
    c = -a * t1.first - b * t1.second;
    normalize();
  }
  inline bool degenerate() {
    return abs(a) < eps && abs(b) < eps && abs(c) < eps;
  }
  inline void normalize() {
    double h = sqrt(a * a + b * b);
    if (a < -eps || (abs(a) < eps && b < -eps) ||
        (abs(a) < eps && abs(b) < eps && c < -eps)) {
      a = -a;
      b = -b;
      c = -c;
    }
    if (h < eps) return;
    a /= h;
    b /= h;
    c /= h;
  }
  inline Point intersect(Line other) {
    if (parallel(other)) return Point(-1e100, -1e100);
    double det = b * other.a - a * other.b;
    double first = (c * other.b - b * other.c) / det;
    double second = (a * other.c - c * other.a) / det;
    return Point(first, second);
  }
  inline bool parallel(Line other) {
    return abs(a * other.b - b * other.a) < eps;
  }
  inline double evaluate(Point point) {
    return a * point.first + b * point.second + c;
  }
  inline bool contains(Point point) { return abs(evaluate(point)) < eps; }
  inline Line perpendicular(Point point) {
    return Line(-b, a, b * point.first - a * point.second);
  }
  inline double distance(Point point) { return abs(evaluate(point)); }
};
struct Circle {
  Point center;
  double radius;
  Circle() : radius(0) {}
  Circle(Point _center, double _radius) : center(_center), radius(_radius) {}
  bool contains(Point point) { return center.distance(point) < radius + eps; }
  bool strictlyContains(Point point) {
    return center.distance(point) + eps < radius;
  }
  vector<Point> findTouchingPoints(Point point) {
    double distance = center.distance(point);
    if (distance + eps < radius) return vector<Point>();
    if (distance < radius + eps) return vector<Point>(1, point);
    Circle p(point, sqrt((distance - radius) * (distance + radius)));
    return intersect(p);
  }
  vector<Point> intersect(Line line) {
    double distance = line.distance(center);
    if (distance > radius + eps) return vector<Point>();
    Point intersection = line.intersect(line.perpendicular(center));
    if (abs(distance - radius) < eps) return vector<Point>(1, intersection);
    double shift = sqrt(radius * radius - distance * distance);
    vector<Point> ans;
    ans.push_back(Point(intersection.first + shift * line.b,
                        intersection.second - shift * line.a));
    ans.push_back(Point(intersection.first - shift * line.b,
                        intersection.second + shift * line.a));
    return ans;
  }
  vector<Point> intersect(Circle other) {
    double distance = center.distance(other.center);
    if (distance > radius + other.radius + eps ||
        abs(radius - other.radius) > distance + eps)
      return vector<Point>();
    double p = (radius + other.radius + distance) / 2;
    double h = 2.0 *
               sqrt(p * (p - radius) * (p - other.radius) * (p - distance)) /
               distance;
    double l1 = sqrt(radius * radius - h * h);
    double l2 = sqrt(other.radius * other.radius - h * h);
    if (radius * radius + distance * distance < other.radius * other.radius)
      l1 = -l1;
    if (radius * radius > distance * distance + other.radius * other.radius)
      l2 = -l2;
    Point middle((center.first * l2 + other.center.first * l1) / (l1 + l2),
                 (center.second * l2 + other.center.second * l1) / (l1 + l2));
    Line line(center, other.center);
    return intersect(line.perpendicular(middle));
  }
};
int a, b, c, d, n, m, k;
pair<pair<int, int>, int> q[3];
inline int ds(pair<int, int> t1, pair<int, int> t2) {
  return (t1.first - t2.first) * (t1.first - t2.first) +
         (t1.second - t2.second) * (t1.second - t2.second);
}
inline int sq(int a) { return a * a; }
inline void add(vector<pair<double, double> > &a, Point t) {
  for (int _n(((int)((a).size())) - 1), i(0); i <= _n; i++) {
    if (abs(a[i].first - t.first) < 1e-8 && abs(a[i].second - t.second) < 1e-8)
      return;
  }
  a.push_back(make_pair(t.first, t.second));
}
inline int ci(pair<pair<int, int>, int> a, pair<pair<int, int>, int> b,
              vector<pair<double, double> > &res) {
  Circle c1(Point(a.first.first, a.first.second), a.second);
  Circle c2(Point(b.first.first, b.first.second), b.second);
  auto pnt = c1.intersect(c2);
  for (int _n(((int)((pnt).size())) - 1), i(0); i <= _n; i++) {
    add(res, pnt[i]);
  }
  if ((int)((pnt).size()) == 2 && pnt[0].distance(pnt[1]) < 1e-8)
    pnt.pop_back();
  return (int)((pnt).size());
}
int main() {
  scanf("%d", &n);
  for (int _n((n)-1), i(0); i <= _n; i++) {
    scanf("%d%d%d", &q[i].first.first, &q[i].first.second, &q[i].second);
  }
  sort(q, q + n,
       [](const pair<pair<int, int>, int> &a,
          const pair<pair<int, int>, int> &b) {
         if (a.second != b.second) return a.second > b.second;
         return a.first < b.first;
       });
  n = unique(q, q + n) - q;
  if (n == 1) {
    printf("2\n");
    exit(0);
  }
  if (n == 2) {
    int d = ds(q[0].first, q[1].first);
    if (d < sq(q[0].second + q[1].second) &&
        d > sq(q[0].second - q[1].second)) {
      printf("4\n");
      exit(0);
    }
    printf("3\n");
    exit(0);
  }
  int ce = 0, ne = 0;
  vector<pair<double, double> > ooo;
  for (int _n((n)-1), i(0); i <= _n; i++) {
    vector<pair<double, double> > oo;
    for (int _n((n)-1), j(0); j <= _n; j++) {
      if (i == j) continue;
      ci(q[i], q[j], oo);
    }
    if (oo.empty()) {
      ++ne;
      continue;
    }
    ce += oo.size();
    for (int _n(((int)((oo).size())) - 1), j(0); j <= _n; j++) {
      add(ooo, Point(oo[j].first, oo[j].second));
    }
  }
  if (ne == 3) {
    printf("4\n");
    exit(0);
  }
  int cv = (int)((ooo).size());
  int ans = 2 + ce - cv + ne;
  cout << ans << endl;
}
