
#include <fstream>
#include <deque>
#include <vector>
#include <cmath>
#include <algorithm>

struct Vector
{
  double x, y, z;
  Vector (double x_ = 0, double y_ = 0, double z_ = 0): x(x_), y(y_), z(z_) {}
};

std::vector<Vector> pts;

bool angleCompare(const Vector& lhs, const Vector& rhs)
{
  return atan2(lhs.x, lhs.y) > atan2(rhs.x, rhs.y);
}

double scalarMult (const Vector& lhs, const Vector& rhs)
{
  return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
}

Vector vectMult (const Vector& lhs, const Vector& rhs)
{
  return Vector(lhs.y * rhs.z - lhs.z * rhs.y, - lhs.x * rhs.z + lhs.z * rhs.x, lhs.x * rhs.y - lhs.y * rhs.x);
}

double norm(const Vector& v)
{
  return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}

double distance (int a, int b)
{
  return acos (scalarMult(pts[a], pts[b]) / (norm(pts[a]) * norm(pts[b]))) * (norm(pts[a]) + norm(pts[b])) / 2;
}

int main(int argc, char** argv)
{
  std::fstream input("input.txt", std::ios_base::in);
  std::fstream output("output.txt", std::ios_base::out);

  int n, i, j;

  input >> n;
  pts.resize(n);
  for (i = 0; i < n; ++i) 
  {
    double x, y, z;
    input >> x >> y >> z;
    pts[i] = Vector(x, y, z);
  }

  sort(pts.begin(), pts.end(), angleCompare);

  Vector poleAxis(0, 0, 1);

  double maxPerimeter = 0;
  for (j = 0; j < n; ++j)
  {
    std::deque<int> upper, lower;
    upper.push_back(j); lower.push_back(j);
    Vector mainPlaneNormal = vectMult(poleAxis, pts[j]);

    int l = (j + 1) % n;

    int r = l;
    while (r != j && scalarMult(mainPlaneNormal, pts[r]) == 0 && scalarMult(vectMult(vectMult(pts[j], poleAxis), poleAxis),
                                                                            pts[r]) < 0)
      r = (r + 1) % n;
    while (r != j && scalarMult(mainPlaneNormal, pts[r]) > 0)
      r = (r + 1) % n;

    double perimeter = 0;
    for (i = l; i != r; i = (i + 1) % n)
    {
      while (upper.size() > 1 && scalarMult(vectMult(vectMult(pts[upper[1]], pts[upper[0]]), vectMult(pts[upper[0]], pts[i])), pts[upper[0]]) <= 0)
      {
        perimeter -= distance(upper[0], upper[1]);
        upper.pop_front();
      }
      while (lower.size() > 1 && scalarMult(vectMult(vectMult(pts[lower[1]], pts[lower[0]]), vectMult(pts[lower[0]], pts[i])), pts[lower[0]]) >= 0)
      {
        perimeter -= distance(lower[0], lower[1]);
        lower.pop_front();
      }

      upper.push_front(i);
      lower.push_front(i);

      perimeter += distance(upper[0], upper[1]);
      perimeter += distance(lower[0], lower[1]);
    }

    if (perimeter > maxPerimeter && perimeter > 2*distance(upper.front(), upper.back())) maxPerimeter = perimeter;
  }  

  output << maxPerimeter;
}
