#include <bits/stdc++.h>
using namespace std;
struct node {
  double x, y, t, val;
} pnt[2050];
struct Edge {
  int u, v, next;
} edge[2050 * 2050];
int head[2050], tot = 0;
void add(int u, int v) {
  edge[tot].u = u;
  edge[tot].v = v;
  edge[tot].next = head[u];
  head[u] = tot++;
}
double Dist(node x, node y) {
  return sqrt((x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y));
}
int ru[2050];
double Max(double x, double y) {
  if (x > y) return x;
  return y;
}
int mark[2050];
int n;
double dis[2050];
double spfa(int x) {
  for (int i = 1; i <= n; i++) {
    mark[i] = false;
    dis[i] = 0;
  }
  queue<int> Q;
  Q.push(x);
  dis[x] = pnt[x].val;
  mark[x] = true;
  while (!Q.empty()) {
    int k = Q.front();
    Q.pop();
    mark[k] = false;
    for (int i = head[k]; i != -1; i = edge[i].next) {
      if (dis[edge[i].v] < dis[k] + pnt[edge[i].v].val) {
        dis[edge[i].v] = dis[k] + pnt[edge[i].v].val;
        if (mark[edge[i].v] == false) {
          Q.push(edge[i].v);
          mark[edge[i].v] = true;
        }
      }
    }
  }
  double maxn = dis[x];
  for (int i = 1; i <= n; i++) {
    if (dis[i] > maxn) {
      maxn = dis[i];
    }
  }
  return maxn;
}
int main() {
  int i, j;
  while (scanf("%d", &n) != EOF) {
    for (i = 1; i <= n; i++) {
      scanf("%lf%lf%lf%lf", &pnt[i].x, &pnt[i].y, &pnt[i].t, &pnt[i].val);
    }
    memset(head, -1, sizeof(head));
    memset(ru, 0, sizeof(ru));
    tot = 0;
    for (i = 1; i <= n; i++) {
      for (j = 1; j <= n; j++) {
        if (i == j) continue;
        if (Dist(pnt[i], pnt[j]) + pnt[i].t <= pnt[j].t) {
          add(i, j);
          ru[j]++;
        }
      }
    }
    double maxn = 0;
    for (i = 1; i <= n; i++) {
      if (ru[i] == 0) {
        maxn = Max(maxn, spfa(i));
      }
    }
    printf("%.7f\n", maxn);
  }
  return 0;
}
