Problem: In a far away galaxy there are n inhabited planets, numbered with numbers from 1 to n. They are located at large distances from each other, that's why the communication between them was very difficult until on the planet number 1 a hyperdrive was invented. As soon as this significant event took place, n - 1 spaceships were built on the planet number 1, and those ships were sent to other planets to inform about the revolutionary invention. 

Paradoxical thought it may be, but the hyperspace is represented as simple three-dimensional Euclidean space. The inhabited planets may be considered fixed points in it, and no two points coincide and no three points lie on the same straight line. The movement of a ship with a hyperdrive between two planets is performed along a straight line at the constant speed, the same for all the ships. That's why the distance in the hyperspace are measured in hyperyears (a ship with a hyperdrive covers a distance of s hyperyears in s years).

When the ship reaches an inhabited planet, the inhabitants of the planet dissemble it, make n - 2 identical to it ships with a hyperdrive and send them to other n - 2 planets (except for the one from which the ship arrived). The time to make a new ship compared to the time in which they move from one planet to another is so small that it can be disregarded. New ships are absolutely identical to the ones sent initially: they move at the same constant speed along a straight line trajectory and, having reached a planet, perform the very same mission, i.e. are dissembled to build new n - 2 ships and send them to all the planets except for the one from which the ship arrived. Thus, the process of spreading the important news around the galaxy continues.

However the hyperdrive creators hurried to spread the news about their invention so much that they didn't study completely what goes on when two ships collide in the hyperspace. If two moving ships find themselves at one point, they provoke an explosion of colossal power, leading to the destruction of the galaxy!

Your task is to find the time the galaxy will continue to exist from the moment of the ships' launch from the first planet.

Input

The first line contains a number n (3 ≤ n ≤ 5000) — the number of inhabited planets in the galaxy. The next n lines contain integer coordinates of the planets in format "xi yi zi" ( - 104 ≤ xi, yi, zi ≤ 104). 

Output

Print the single number — the solution to the task with an absolute or relative error not exceeding 10 - 6.

Examples

Input

4
0 0 0
0 0 1
0 1 0
1 0 0


Output

1.7071067812

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:102400000,102400000")
const double Pi = acos(-1.0);
const double eps = 1e-6;
const double Ee = 2.718281828459045235360;
const int INF = 0x3f3f3f3f;
const long long INFF = 0x3f3f3f3f3f3f3f3fLL;
const int MOD = 1000000007;
const int dx4[] = {-1, 0, 1, 0};
const int dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, 0, 1, 0, -1, -1, 1, 1};
const int dy8[] = {0, 1, 0, -1, -1, 1, -1, 1};
const int dxhorse[] = {-2, -2, -1, -1, 1, 1, 2, 2};
const int dyhorse[] = {1, -1, 2, -2, 2, -2, 1, -1};
using namespace std;
namespace Math {
long long GCD(long long a, long long b) { return b ? GCD(b, a % b) : a; }
long long extendGCD(long long a, long long b, long long &x, long long &y) {
  if (!b) return x = 1, y = 0, a;
  long long res = extendGCD(b, a % b, x, y), tmp = x;
  x = y, y = tmp - (a / b) * y;
  return res;
}
long long power(long long x, long long k) {
  long long res = 1;
  while (k) {
    if (k & 1) res *= x;
    x *= x, k >>= 1;
  }
  return res;
}
long long powerMod(long long x, long long k, long long m) {
  long long res = 1;
  while (x %= m, k) {
    if (k & 1) res *= x, res %= m;
    x *= x, k >>= 1;
  }
  return res;
}
long long inverse(long long a, long long p, long long t = 1) {
  long long pt = power(p, t);
  long long x, y;
  y = extendGCD(a, pt, x, y);
  return x < 0 ? x += pt : x;
}
long long linearCongruence(long long a, long long b, long long p, long long q) {
  long long x, y;
  y = extendGCD(p, q, x, y);
  while (b < a) b += q / y;
  x *= b - a, x = p * x + a, x %= p * q;
  if (x < 0) x += p * q;
  return x;
}
const int PRIMERANGE = 1000000;
int prime[PRIMERANGE + 1];
int mobius[PRIMERANGE + 1];
int getPrime() {
  memset(prime, 0, sizeof(int) * (PRIMERANGE + 1));
  memset(mobius, 0, sizeof(mobius));
  mobius[1] = 1;
  for (int i = 2; i <= PRIMERANGE; i++) {
    if (!prime[i]) prime[++prime[0]] = i, mobius[i] = -1;
    for (int j = 1; j <= prime[0] && prime[j] <= PRIMERANGE / i; j++) {
      prime[prime[j] * i] = 1;
      if (i % prime[j] == 0)
        break;
      else
        mobius[i * prime[j]] = -mobius[i];
    }
  }
  return prime[0];
}
int factor[100][3], facCnt;
int getFactors(int x) {
  facCnt = 0;
  int tmp = x;
  for (int i = 1; prime[i] <= tmp / prime[i]; i++) {
    factor[facCnt][1] = 1, factor[facCnt][2] = 0;
    if (tmp % prime[i] == 0) factor[facCnt][0] = prime[i];
    while (tmp % prime[i] == 0)
      factor[facCnt][2]++, factor[facCnt][1] *= prime[i], tmp /= prime[i];
    if (factor[facCnt][1] > 1) facCnt++;
  }
  if (tmp != 1)
    factor[facCnt][0] = tmp, factor[facCnt][1] = tmp, factor[facCnt++][2] = 1;
  return facCnt;
}
long long combinationModP(long long n, long long k, long long p) {
  if (k > n) return 0;
  if (n - k < k) k = n - k;
  long long a = 1, b = 1, x, y;
  int pcnt = 0;
  for (int i = 1; i <= k; i++) {
    x = n - i + 1, y = i;
    while (x % p == 0) x /= p, pcnt++;
    while (y % p == 0) y /= p, pcnt--;
    x %= p, y %= p, a *= x, b *= y;
    b %= p, a %= p;
  }
  if (pcnt) return 0;
  extendGCD(b, p, x, y);
  if (x < 0) x += p;
  a *= x, a %= p;
  return a;
}
long long inv[100005];
long long ba[100005];
long long rba[100005];
void Init_Com() {
  inv[0] = inv[1] = 1;
  ba[0] = ba[1] = 1;
  rba[0] = rba[1] = 1;
  for (int i = 2; i < 100005; i++) {
    inv[i] = ((MOD - MOD / i) * inv[MOD % i]) % MOD;
    ba[i] = (ba[i - 1] * i) % MOD;
    rba[i] = (rba[i - 1] * inv[i]) % MOD;
  }
}
long long C(int n, int m) { return (ba[n] * rba[m] % MOD) * rba[n - m] % MOD; }
int fib[1000000];
int Fib(int a, int b, int n) {
  if (n == 0) return a;
  if (n == 1) return b;
  return (a * fib[n - 1] % MOD + b * fib[n] % MOD) % MOD;
}
};  // namespace Math
namespace Geo {
const double eps = 1e-9;
int dblcmp(double d) { return d < -eps ? -1 : d > eps; }
struct Point {
  double x, y;
  Point() {}
  Point(double _x, double _y) : x(_x), y(_y){};
  void input() { scanf("%lf%lf", &x, &y); }
  void output() { printf("%.2f %.2f\n", x, y); }
  bool operator==(Point a) const {
    return dblcmp(a.x - x) == 0 && dblcmp(a.y - y) == 0;
  }
  bool operator<(Point a) const {
    return dblcmp(a.x - x) == 0 ? dblcmp(y - a.y) < 0 : x < a.x;
  }
  double len() { return hypot(x, y); }
  double len2() { return x * x + y * y; }
  double distance(Point p) { return hypot(x - p.x, y - p.y); }
  double distance2(Point p) {
    return ((x - p.x) * (x - p.x)) + ((y - p.y) * (y - p.y));
  }
  Point add(Point p) { return Point(x + p.x, y + p.y); }
  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
  Point sub(Point p) { return Point(x - p.x, y - p.y); }
  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
  Point mul(double b) { return Point(x * b, y * b); }
  Point div(double b) { return Point(x / b, y / b); }
  double dot(Point p) { return x * p.x + y * p.y; }
  double operator*(const Point &p) const { return x * p.x + y * p.y; }
  double det(Point p) { return x * p.y - y * p.x; }
  double operator^(const Point &p) const { return x * p.y - y * p.x; }
  double rad(Point a, Point b) {
    Point p = *this;
    return fabs(atan2(fabs(a.sub(p).det(b.sub(p))), a.sub(p).dot(b.sub(p))));
  }
  Point trunc(double r) {
    double l = len();
    if (!dblcmp(l)) return *this;
    r /= l;
    return Point(x * r, y * r);
  }
  Point rotleft() { return Point(-y, x); }
  Point rotright() { return Point(y, -x); }
  Point rotate(Point p, double angle) {
    Point v = this->sub(p);
    double c = cos(angle), s = sin(angle);
    return Point(p.x + v.x * c - v.y * s, p.y + v.x * s + v.y * c);
  }
};
struct Line {
  Point a, b;
};
};  // namespace Geo
namespace BigNum {
class BigInteger {
 private:
  int a[10010];
  int length;

 public:
  BigInteger() {
    length = 1;
    memset(a, 0, sizeof(a));
  }
  BigInteger(const int);
  BigInteger(const char *);
  BigInteger(const BigInteger &);
  BigInteger &operator=(const BigInteger &);
  friend istream &operator>>(istream &, BigInteger &);
  friend ostream &operator<<(ostream &, BigInteger &);
  BigInteger operator+(const BigInteger &) const;
  BigInteger operator-(const BigInteger &) const;
  BigInteger operator*(const BigInteger &) const;
  BigInteger operator/(const int &) const;
  BigInteger operator^(const int &) const;
  int operator%(const int &) const;
  bool operator>(const BigInteger &T) const;
  bool operator>(const int &t) const;
  void print();
};
BigInteger::BigInteger(const int b) {
  int c, d = b;
  length = 0;
  memset(a, 0, sizeof(a));
  while (d > 9999) {
    c = d - (d / (9999 + 1)) * (9999 + 1);
    d = d / (9999 + 1);
    a[length++] = c;
  }
  a[length++] = d;
}
BigInteger::BigInteger(const char *s) {
  memset(a, 0, sizeof(a));
  int L = strlen(s);
  length = L / 4;
  if (L % 4) length++;
  int index = 0;
  for (int i = L - 1; i >= 0; i -= 4) {
    int t = 0;
    int k = i - 4 + 1;
    if (k < 0) k = 0;
    for (int j = k; j <= i; ++j) t = t * 10 + s[j] - '0';
    a[index++] = t;
  }
}
BigInteger::BigInteger(const BigInteger &T) : length(T.length) {
  memset(a, 0, sizeof(a));
  for (int i = 0; i < length; i++) a[i] = T.a[i];
}
BigInteger &BigInteger::operator=(const BigInteger &n) {
  length = n.length;
  memset(a, 0, sizeof(a));
  for (int i = 0; i < length; i++) a[i] = n.a[i];
  return *this;
}
istream &operator>>(istream &in, BigInteger &b) {
  char ch[1010 * 4];
  in >> ch;
  int i = -1, L = strlen(ch), count = 0, sum = 0;
  for (i = L - 1; i >= 0;) {
    sum = 0;
    int t = 1;
    for (int j = 0; j < 4 && i >= 0; j++, i--, t *= 10) {
      sum += (ch[i] - '0') * t;
    }
    b.a[count] = sum;
    count++;
  }
  b.length = count++;
  return in;
}
ostream &operator<<(ostream &out, BigInteger &b) {
  cout << b.a[b.length - 1];
  for (int i = b.length - 2; i >= 0; i--) {
    cout.width(4);
    cout.fill('0');
    cout << b.a[i];
  }
  return out;
}
BigInteger BigInteger::operator+(const BigInteger &T) const {
  BigInteger t(*this);
  int big;
  big = T.length > length ? T.length : length;
  for (int i = 0; i < big; ++i) {
    t.a[i] += T.a[i];
    if (t.a[i] > 9999) {
      t.a[i + 1]++;
      t.a[i] -= 9999 + 1;
    }
  }
  if (t.a[big] != 0)
    t.length = big + 1;
  else
    t.length = big;
  return t;
}
BigInteger BigInteger::operator-(const BigInteger &T) const {
  int big;
  bool flag;
  BigInteger t1, t2;
  if (*this > T) {
    t1 = *this;
    t2 = T;
    flag = 0;
  } else {
    t1 = T;
    t2 = *this;
    flag = 1;
  }
  big = t1.length;
  for (int i = 0; i < big; ++i) {
    if (t1.a[i] < t2.a[i]) {
      int j = i + 1;
      while (t1.a[j] == 0) j++;
      t1.a[j--]--;
      while (j > i) t1.a[j--] += 9999;
      t1.a[i] += 9999 + 1 - t2.a[i];
    } else
      t1.a[i] -= t2.a[i];
  }
  t1.length = big;
  while (t1.a[t1.length - 1] == 0 && t1.length > 1) {
    t1.length--;
    big--;
  }
  if (flag) t1.a[big - 1] = 0 - t1.a[big - 1];
  return t1;
}
BigInteger BigInteger::operator*(const BigInteger &T) const {
  BigInteger ret;
  int i, j, temp, temp1;
  for (i = 0; i < length; ++i) {
    int up = 0;
    for (j = 0; j < T.length; ++j) {
      temp = a[i] * T.a[j] + ret.a[i + j] + up;
      if (temp > 9999) {
        temp1 = temp - temp / (9999 + 1) * (9999 + 1);
        up = temp / (9999 + 1);
        ret.a[i + j] = temp1;
      } else {
        up = 0;
        ret.a[i + j] = temp;
      }
    }
    if (up != 0) ret.a[i + j] = up;
  }
  ret.length = i + j;
  while (ret.a[ret.length - 1] == 0 && ret.length > 1) ret.length--;
  return ret;
}
BigInteger BigInteger::operator/(const int &b) const {
  BigInteger ret;
  int down = 0;
  for (int i = length - 1; i >= 0; --i) {
    ret.a[i] = (a[i] + down * (9999 + 1)) / b;
    down = a[i] + down * (9999 + 1) - ret.a[i] * b;
  }
  ret.length = length;
  while (ret.a[ret.length - 1] == 0 && ret.length > 1) ret.length--;
  return ret;
}
int BigInteger::operator%(const int &b) const {
  long long d = 0;
  for (int i = length - 1; i >= 0; --i) {
    d = ((d * (9999 + 1)) % b + a[i]) % b;
  }
  return (int)d;
}
BigInteger BigInteger::operator^(const int &n) const {
  BigInteger t, ret(1);
  if (n < 0) exit(-1);
  if (n == 0) return 1;
  if (n == 1) return *this;
  int m = n;
  while (m > 1) {
    t = *this;
    int i;
    for (i = 1; (i << 1) <= m; i <<= 1) {
      t = t * t;
    }
    m -= i;
    ret = ret * t;
    if (m == 1) ret = ret * (*this);
  }
  return ret;
}
bool BigInteger::operator>(const BigInteger &T) const {
  int ln;
  if (length > T.length)
    return true;
  else if (length == T.length) {
    ln = length - 1;
    while (a[ln] == T.a[ln] && ln >= 0) ln--;
    if (ln >= 0 && a[ln] > T.a[ln])
      return true;
    else
      return false;
  } else
    return false;
}
bool BigInteger::operator>(const int &t) const {
  BigInteger b(t);
  return *this > b;
}
void BigInteger::print() {
  printf("%d", a[length - 1]);
  for (int i = length - 2; i >= 0; --i) {
    printf("%04d", a[i]);
  }
  puts("");
}
};  // namespace BigNum
namespace IO_Optimize {
template <class T>
inline T &RD(T &);
template <class T>
inline T &RDD(T &);
inline long long RD() {
  long long x;
  return RD(x);
}
inline long long RDD() {
  long long x;
  return RDD(x);
}
inline double &RF(double &);
inline double RF() {
  double x;
  return RF(x);
}
template <class T0, class T1>
inline T0 &RD(T0 &x0, T1 &x1) {
  RD(x0), RD(x1);
  return x0;
}
template <class T0, class T1, class T2>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2) {
  RD(x0), RD(x1), RD(x2);
  return x0;
}
template <class T0, class T1, class T2, class T3>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3) {
  RD(x0), RD(x1), RD(x2), RD(x3);
  return x0;
}
template <class T0, class T1, class T2, class T3, class T4>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4) {
  RD(x0), RD(x1), RD(x2), RD(x3), RD(x4);
  return x0;
}
template <class T0, class T1, class T2, class T3, class T4, class T5>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5) {
  RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5);
  return x0;
}
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6) {
  RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6);
  return x0;
}
template <class T0, class T1>
inline void RDD(T0 &a, T1 &b) {
  RDD(a), RDD(b);
}
template <class T0, class T1, class T2>
inline void RDD(T0 &a, T1 &b, T2 &c) {
  RDD(a), RDD(b), RDD(c);
}
inline double &RF(double &a, double &b) {
  RF(a), RF(b);
  return a;
}
inline double &RF(double &a, double &b, double &c) {
  RF(a), RF(b), RF(c);
  return a;
}
inline double &RF(double &a, double &b, double &c, double &d) {
  RF(a), RF(b), RF(c), RF(d);
  return a;
}
inline double &RF(double &a, double &b, double &c, double &d, double &e) {
  RF(a), RF(b), RF(c), RF(d), RF(e);
  return a;
}
inline double &RF(double &a, double &b, double &c, double &d, double &e,
                  double &f) {
  RF(a), RF(b), RF(c), RF(d), RF(e), RF(f);
  return a;
}
inline double &RF(double &a, double &b, double &c, double &d, double &e,
                  double &f, double &g) {
  RF(a), RF(b), RF(c), RF(d), RF(e), RF(f), RF(g);
  return a;
}
template <class T>
inline T &RD(T &x) {
  char c;
  while (!isdigit((c = getchar())))
    ;
  x = c - '0';
  while (isdigit((c = getchar()))) x = x * 10 + c - '0';
  return x;
}
template <class T>
inline T &RDD(T &x) {
  char c;
  while ((c = getchar()), c != '-' && !isdigit(c))
    ;
  if (c == '-') {
    x = '0' - (c = getchar());
    while (isdigit((c = getchar()))) x = x * 10 + '0' - c;
  } else {
    x = c - '0';
    while (isdigit((c = getchar()))) x = x * 10 + c - '0';
  }
  return x;
}
inline double &RF(double &x) {
  char c;
  while ((c = getchar()), c != '-' && c != '.' && !isdigit(c))
    ;
  if (c == '-')
    if ((c = getchar()) == '.') {
      x = 0;
      double l = 1;
      while (isdigit((c = getchar()))) l /= 10, x = x * 10 + '0' - c;
      x *= l;
    } else {
      x = '0' - c;
      while (isdigit((c = getchar()))) x = x * 10 + '0' - c;
      if (c == '.') {
        double l = 1;
        while (isdigit((c = getchar()))) l /= 10, x = x * 10 + '0' - c;
        x *= l;
      }
    }
  else if (c == '.') {
    x = 0;
    double l = 1;
    while (isdigit((c = getchar()))) l /= 10, x = x * 10 + c - '0';
    x *= l;
  } else {
    x = c - '0';
    while (isdigit((c = getchar()))) x = x * 10 + c - '0';
    if (c == '.') {
      double l = 1;
      while (isdigit((c = getchar()))) l /= 10, x = x * 10 + c - '0';
      x *= l;
    }
  }
  return x;
}
};  // namespace IO_Optimize
namespace Debug {
void out(int *s, int n) {
  for (int i = 0; i <= n; i++) printf(i < n ? "%d " : "%d(--)\n", s[i]);
}
void out(long long *s, int n) {
  for (int i = 0; i <= n; i++) printf(i < n ? "%2lld " : "%2lld\n", s[i]);
}
void out(bool *s, int n) {
  for (int i = 0; i <= n; i++) printf(i < n ? "%2d " : "%2d\n", s[i] ? 1 : 0);
}
void out(int n) {
  for (int i = 0; i <= n; i++) printf(i < n ? "%2d " : "%2d\n", i);
}
};  // namespace Debug
using namespace Math;
using namespace Debug;
const int maxn = 5500;
struct Poi {
  int x, y, z;
  void init() { scanf("%d %d %d", &x, &y, &z); }
} arr[maxn];
double dis(Poi a, Poi b) {
  double x = a.x - b.x;
  double y = a.y - b.y;
  double z = a.z - b.z;
  double di = x * x + y * y + z * z;
  return sqrt(di);
}
double cals(int p, int q) {
  double dp = dis(arr[1], arr[p]);
  double dq = dis(arr[1], arr[q]);
  double dpq = dis(arr[p], arr[q]);
  return 0.5 * (dp + dq + dpq);
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) arr[i].init();
  double ans = INF;
  for (int i = 2; i <= n; i++) {
    for (int j = i + 1; j <= n; j++)
      ans = ((ans) < (cals(i, j)) ? (ans) : (cals(i, j)));
  }
  printf("%.10f\n", ans);
  return 0;
}