#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <cstdio>
#include <set>
using namespace std;

const double eps = 1e-8;

bool equals(double a, double b) {
  return abs(a-b) < eps;
}

struct P3D {
private:
  double v[3];
public:
  P3D() {
    v[0] = v[1] = v[2] = 0;
  }

  P3D(double a, double b, double c) {
    v[0] = a; v[1] = b; v[2] = c;
  }

  P3D(const double _v[]) {
    for(int i = 0; i < 3; ++i) {
      v[i] = _v[i];
    }
  }

  double& operator [](int x) {
    return v[x];
  }

  const double& operator [](int x) const{
    return v[x];
  }

  P3D operator +(const P3D &p) const {
    P3D res;
    for(int i = 0; i < 3; ++i) {
      res[i] = (*this)[i] + p[i];
    }
    return res;
  }

  P3D operator -(const P3D &p) const {
    P3D res;
    for(int i = 0; i < 3; ++i) {
      res[i] = (*this)[i] - p[i];
    }
    return res;
  }

  P3D operator *(const double &d) const {
    P3D res;
    for(int i = 0; i < 3; ++i) {
      res[i] = (*this)[i] * d;
    }
    return res;
  }

  P3D operator /(const double &d) const {
    P3D res;
    for(int i = 0; i < 3; ++i) {
      res[i] = (*this)[i] / d;
    }
    return res;
  }

  P3D& operator =(const P3D &p) {
    for(int i = 0; i < 3; ++i) {
      (*this)[i] = p[i];
    }
    return (*this);
  }
};


double dot(const P3D &a, const P3D &b) {
  double res = 0;
  for(int i = 0; i < 3; ++i) res += a[i] * b[i];
  return res;
}

double cross(const P3D &a, const P3D &b) {
  double res = 0;
  for(int i = 0; i < 3; ++i) {
    double t = a[i]*b[(i+1)%3] - a[(i+1)%3]*b[i];
    res += t*t;
  }
  return sqrt(res);
}

double norm(const P3D &a) {
  return dot(a,a);
}

double abs(const P3D &a) {
  return sqrt(norm(a));
}

double getDistance(const P3D &a, const P3D &b) {
  return abs(a-b);
}

double getDistanceLP(const P3D &s1, const P3D &s2, const P3D &p) {
  return abs(cross(s2 - s1, p - s1)/abs(s2 - s1));
}

double getDistanceSP(const P3D &s1, const P3D &s2, const P3D &p) {
  if(dot(s2 - s1, p - s1) < 0.0) return getDistance(s1, p);
  if(dot(s1 - s2, p - s2) < 0.0) return getDistance(s2 ,p);
  return getDistanceLP(s1, s2, p);
}

bool isIn(const P3D &p , const P3D &o, const double &r) {
  double d = abs(p - o);
  return equals(d, r) || d < r;
}

void show(const P3D &p) {
  cout << "(";
  for(int i = 0; i < 3; ++i) {
    if(i) cout << ", ";
    cout << p[i];
  }
  cout << ")" << endl;
}

const int MAXN = 2001;
const int MAXM = 16;
int N, M, R;
P3D S[MAXN];
double Sr[MAXN];
P3D T[MAXM];
double Tb[MAXM];
P3D E;
set<int> rballoon[MAXM];
double mem[1<<MAXM];

void makeRballoon() {
  for(int k = 0; k < M; ++k) {
    rballoon[k].clear();
    for(int i = 0; i < N; ++i) {
      double d = getDistanceSP(T[k], E, S[i]);
      if(!equals(d, Sr[i]) && d < Sr[i]) {
        if(isIn(T[k], S[i], Sr[i]) && isIn(E, S[i], Sr[i])) continue;
        rballoon[k].insert(i);
      }
    }
  }
}

double test(int b) {
  double res = 0;
  set<int> s;
  for(int i = 0; i < M; ++i) {
    if(b & (1<<i)) ; else continue;
    s.insert(rballoon[i].begin(), rballoon[i].end());
    if(s.size() > R) return -1.0;
    res += Tb[i];
  }
  return res;
}

double rec(int b) {
  double &res = mem[b];
  if(res != -1.0) return res;
  if(b == 0) return res = 0.0;
  res = test(b);
  if(res == -1.0) {
    for(int i = 0; i < M; ++i) {
      if(b & (1<<i)) {
        res = max(res, rec(b & ~(1<<i)));
      }
    }
  }
  return res;
}

int main() {
  while(cin >> N >> M >> R && (N|M|R)) {
    for(int i = 0; i < N; ++i) {
      for(int j = 0; j < 3; ++j) cin >> S[i][j];
      cin >> Sr[i];
    }
    for(int i = 0; i < M; ++i) {
      for(int j = 0; j < 3; ++j) cin >> T[i][j];
      cin >> Tb[i];
    }
    for(int j = 0; j < 3; ++j) cin >> E[j];

    for(int i = 0; i < M; ++i) {
      Tb[i] = Tb[i]/norm(T[i] - E);
    }

    makeRballoon();

    fill(mem, mem+(1<<M), -1.0);
    printf("%.8f\n", rec((1<<M)-1));
  }
  return 0;
}

Measured memory_bytes: 2108