#include <bits/stdc++.h>
using namespace std;
struct drepteec {
  long long a, b;
  double eval(double y) { return (double)a * y + (double)b; }
};
bool cmpdrepteec(drepteec a, drepteec b) {
  if (a.a == b.a) return a.b < b.b;
  return a.a < b.a;
}
pair<double, int> distincte(drepteec x, drepteec y) {
  long long bdif = y.b - x.b;
  long long adif = x.a - y.a;
  double rap;
  if (adif != 0) rap = (double)bdif / adif;
  if (adif == 0) {
    return {0, 0};
  }
  if (adif > 0) {
    return {rap, -1};
  }
  if (adif < 0) {
    return {rap, 1};
  }
}
struct EqStack {
 private:
  long long type;
  bool check2(drepteec x1, drepteec x2) {
    if (x1.a == x2.a) {
      if (type == 1) {
        return x2.b > x1.b;
      }
      if (type == -1) return x2.b < x1.b;
    }
    return false;
  }
  bool check(drepteec x1, drepteec x2, drepteec x3) {
    return distincte(x1, x3).first <= distincte(x1, x2).first;
  }

 public:
  deque<drepteec> stk;
  EqStack(long long t, vector<drepteec> seg) {
    type = t;
    sort(seg.begin(), seg.end(), cmpdrepteec);
    if (type == -1) {
      reverse(seg.begin(), seg.end());
    }
    for (auto drp : seg) {
      while (
          (stk.size() >= 1 && check2(*(stk.end() - 1), drp)) ||
          (stk.size() >= 2 && check(*(stk.end() - 2), *(stk.end() - 1), drp)))
        stk.pop_back();
      stk.push_back(drp);
    }
  }
  double nexttime(double time) {
    if (type == 1) {
      while (stk.size() > 1 && stk[0].eval(time) < stk[1].eval(time)) {
        stk.pop_front();
      }
      return stk.front().eval(time);
    }
    if (type == -1) {
      while (stk.size() > 1 && stk[0].eval(time) > stk[1].eval(time)) {
        stk.pop_front();
      }
      return stk.front().eval(time);
    }
  }
};
const long long N = 2005;
drepteec sgm[N][2];
struct helpsort {
  double val;
  long long add;
};
vector<helpsort> ev;
bool cmphelp(helpsort a, helpsort b) {
  if (a.val == b.val) {
    return a.add < b.add;
  }
  return a.val < b.val;
}
const long long MIN = -1e15;
const long long MAX = 1e15;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  cout.precision(10);
  long long n;
  cin >> n;
  for (long long i = 1; i <= n; i++) {
    long long xl, xr, y;
    cin >> xl >> xr >> y;
    sgm[i][0] = {y, xl};
    sgm[i][1] = {y, xr};
  }
  for (long long i = 1; i <= n; i++) {
    for (long long j = i + 1; j <= n; j++) {
      auto rsp1 = distincte(sgm[i][1], sgm[j][0]);
      auto rsp2 = distincte(sgm[j][1], sgm[i][0]);
      if (rsp1.first > rsp2.first) swap(rsp1, rsp2);
      if (rsp1.second == 0 || rsp2.second == 0) continue;
      if (rsp1.second == 1 && rsp2.second == -1) {
        ev.push_back({MIN, 1});
        ev.push_back({rsp1.first, -1});
        ev.push_back({rsp2.first, 1});
        ev.push_back({MAX, -1});
      } else if (rsp1.second == -1 && rsp2.second == 1) {
        ev.push_back({rsp1.first, 1});
        ev.push_back({rsp2.first, -1});
      } else if (rsp1.second == -1 && rsp2.second == -1) {
        ev.push_back({rsp2.first, 1});
        ev.push_back({MAX, -1});
      } else if (rsp1.second == 1 && rsp2.first == 1) {
        ev.push_back({MIN, 1});
        ev.push_back({rsp1.first, -1});
      }
    }
  }
  vector<drepteec> sg;
  for (long long i = 1; i <= n; i++) {
    sg.push_back(sgm[i][0]);
    sg.push_back(sgm[i][1]);
  }
  EqStack minim(-1, sg);
  EqStack maxim(1, sg);
  long long cnt = 0;
  double ansmin = MAX;
  ev.push_back({0, 0});
  sort(ev.begin(), ev.end(), cmphelp);
  for (long long i = 0; i < ev.size();) {
    long long j = i;
    while (j < ev.size() && ev[j].val == ev[i].val &&
           (ev[j].add == -1 || ev[j].add == 0)) {
      cnt += ev[j].add;
      j++;
    }
    if (cnt == 0 && ev[i].val != MIN && ev[i].val != MAX) {
      double mini = minim.nexttime(ev[i].val);
      double maxi = maxim.nexttime(ev[i].val);
      ansmin = min(ansmin, maxi - mini);
    }
    while (j < ev.size() && ev[j].val == ev[i].val && ev[j].add == 1) {
      j++;
      cnt++;
    }
    i = j;
  }
  cout << fixed << ansmin;
  assert(cnt == 0);
  return 0;
}
