#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-7)
#define equals(a,b) (fabs((a)-(b))<EPS)

using namespace std;

const int IINF = INT_MAX;

class Point3d{
public:
  double x,y,z,weight;
 
  Point3d(double x=0,double y=0,double z=0,double weight=0):x(x),y(y),z(z),weight(weight){}
 
  Point3d operator + (const Point3d& a){ return Point3d(x+a.x,y+a.y,z+a.z); }
  Point3d operator - (const Point3d& a){ return Point3d(x-a.x,y-a.y,z-a.z); }
  Point3d operator * (const double& d){ return Point3d(x*d,y*d,z*d); }
  Point3d operator / (const double& d){ return Point3d(x/d,y/d,z/d); }
  bool operator < (const Point3d& p)const { return !equals(x,p.x)?x<p.x:((!equals(y,p.y))?y<p.y:(!equals(z,p.z)&&z<p.z)); }
  bool operator == (const Point3d& p)const{ return equals(x,p.x) && equals(y,p.y) && equals(z,p.z); }
 
};
 
//Verify AOJ 0115
struct Segment3d{
  Point3d p[2];
  Segment3d(Point3d p1=Point3d(),Point3d p2=Point3d()){
    p[0] = p1, p[1] = p2;
  }
  bool operator == (const Segment3d& seg)const{
    return ( p[0] == seg.p[0] && p[1] == seg.p[1] ) || ( p[0] == seg.p[1] && p[1] == seg.p[0] );
  }
};
 
typedef Point3d Vector3d;
typedef Segment3d Line3d;
  
ostream& operator << (ostream& os,const Point3d& p){ os << "(" << p.x << "," << p.y << "," << p.z << ")"; }
 
ostream& operator << (ostream& os,const Segment3d& seg){ os << "(" << seg.p[0] << "," << seg.p[1] << ")"; }
 
double dot(const Point3d& a,const Point3d& b){ return a.x*b.x + a.y*b.y + a.z*b.z; }
 
Vector3d cross(const Point3d& a,const Point3d& b){ return Vector3d(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x); }
 
inline double norm(const Point3d &p){ return p.x*p.x + p.y*p.y + p.z*p.z; }
 
inline double abs(const Point3d &p){ return sqrt(norm(p)); }
 
double distanceLP(Line3d line,Point3d p){
  return abs(cross(line.p[1]-line.p[0],p-line.p[0])) / abs(line.p[1]-line.p[0]);
}
 
Point3d project(Segment3d seg,Point3d p){
  Vector3d base = seg.p[1] - seg.p[0];
  double t = dot(p-seg.p[0],base) / norm(base);
  return seg.p[0] + base * t;
}
 
Point3d reflect(Segment3d seg,Point3d p){
  return p + (project(seg,p)-p) * 2.0;
}

bool on_line3d(Line3d line,Point3d p){
  return equals(abs(cross(line.p[1]-p,line.p[0]-p)),0);
}
 
bool on_segment3d(Segment3d seg,Point3d p){
  if( !on_line3d(seg,p) ) return false;
  double dist[3] = { abs(seg.p[1]-seg.p[0]), abs(p-seg.p[0]), abs(p-seg.p[1]) };  
  return on_line3d(seg,p) && equals(dist[0],dist[1]+dist[2]);
}

double distanceSP(Segment3d seg,Point3d p){
  Point3d r = project(seg,p);
  if( on_segment3d(seg,r) ) return abs(p-r);
  return min(abs(seg.p[0]-p),abs(seg.p[1]-p));
}
 
bool LT(double x, double y){ return !equals(x,y) && x < y; }
bool LTE(double x, double y){ return equals(x,y) || x < y; }

const int MAX_N = 2100;
const int MAX_M = 20;
int N,M,R;
bitset<2100> remove_cost[MAX_M];
Point3d S[MAX_N],T[MAX_M];
Point3d E;

int getType(double a,double b){
  if( LT(a,b) ) return -1;
  return 1;
}

void init(){
  rep(i,M) remove_cost[i] = 0; 
  rep(i,M) {
    rep(j,N){
      int type[2] = { getType(abs(E-S[j]),S[j].weight), getType(abs(T[i]-S[j]),S[j].weight) };
      if( type[0] == type[1] && type[0] == -1 ) continue;
      double dist = distanceSP(Segment3d(E,T[i]),S[j]);
      if( LTE(dist,S[j].weight) ) remove_cost[i][j] = 1;
    }
  }
}

#define pow2(a) ((a)*(a))
void compute(){
  init();
  double maxi = 0;
  rep(bitmask,(1<<M)){
    bitset<2100> BIT(0);
    rep(i,M) if( (bitmask>>i) & 1 ) BIT |= remove_cost[i];
    if( BIT.count() <= R ) {
      double cost = 0;
      rep(i,M) if( (bitmask>>i) & 1 ) cost += T[i].weight / ( pow2(T[i].x-E.x) + pow2(T[i].y-E.y) + pow2(T[i].z-E.z) );
      maxi = max(maxi,cost);
    }
  }
  printf("%.10lf\n",maxi);
}

int main(){
  while( cin >> N >> M >> R, N|M|R ){
    assert( N <= 2000);
    rep(i,N) cin >> S[i].x >> S[i].y >> S[i].z >> S[i].weight;
    rep(i,M) cin >> T[i].x >> T[i].y >> T[i].z >> T[i].weight;
    cin >> E.x >> E.y >> E.z;
    compute();
  }
  return 0;
}

Measured memory_bytes: 1328