#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
 
#define rep(i,x) for(int i=1;i<=(int)(x);i++)
#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=(x);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define SZ(container) ((int)container.size())
#define mp(a, b) make_pair(a, b)
 
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
/*
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
*/
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}
 
 
 
const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000007;
 #define EPS 1.0e-10
inline int signum(double x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }

struct P{
	double x, y, z;
	P():x(0),y(0),z(0){}
	P(double a, double b, double c):x(a),y(b),z(c){}
	
	P operator+(const P &opp){
		return P(x+opp.x, y+opp.y, z+opp.z);
	}
	P operator-(const P &opp){
		return P(x-opp.x, y-opp.y, z-opp.z);
	}
	P operator/(const P &opp){
		return P(abs(opp.x)<EPS?0:x/opp.x, abs(opp.y)<EPS?0:y/opp.y, abs(opp.z)<EPS?0:z/opp.z);
	}
	P operator/(const double &opp){
		return P(x/opp, y/opp, z/opp);
	}
	P operator*(const double opp){
		return P(x*opp, y*opp, z*opp);
	}
};
ostream& operator<<(ostream &os, const P &t) { return os<<"("<<t.x<<","<<t.y<<","<<t.z<<")";}

struct L{
	P pos, dir;
	L(){}
	L(P p, P d):pos(p),dir(d){}
	L(P d):pos(),dir(d){}
};

struct C{
	P p;
	double r;
	C(){}
	C(P q, double s):p(q),r(s){}
};

inline double inp(P v1, P v2){
	return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
}
inline double norm(P v){
	return v.x*v.x + v.y*v.y + v.z*v.z;
}
inline double abs(P v){
	return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
}

inline P perf(P v1, L l){
	return l.pos + l.dir*(inp(v1-l.pos, l.dir)/norm(l.dir));
}

bool sp_intersect(L l, P t){	// 点が線分上にあるかどうか
	P v = perf(t, l);
//	cout << v << ", " << t << endl;
	if(signum(t.x - v.x) || signum(t.y - v.y) || signum(t.z - v.z)) return false;
	t = (v - l.pos) / l.dir;
//	cout << t << endl;
	if(t.x < -EPS || 1+EPS < t.x || t.y < -EPS || 1+EPS < t.y || t.z < -EPS || 1+EPS < t.z) return false;	// 境界を含む
//	cout << "return true" << endl;
	return true;
}

double sp_distance(L l, P t){
	P v1 = t-l.pos;
	P v2 = perf(v1, L(l.dir));
	if(sp_intersect(L(l.dir), v2)) return sqrt(norm(v1 - v2));
	else return sqrt(min(norm(t-l.pos), norm(t-(l.pos + l.dir))));
}
double sp_distance(P t, P p1, P p2){
	return sp_distance(L(p1, p2-p1), t);
}

vector<P> cl_crosspoint(C c, L l){
	P p = perf(c.p, l);
	double d = abs(c.p-p);
	if(d > c.r+EPS) return vector<P>();
	if(d > c.r-EPS) return vector<P>(1, p);
	vector<P> ret;
	double s = sqrt(c.r*c.r - d*d);
	ret.push_back(p + l.dir/abs(l.dir)*s);
	ret.push_back(p - l.dir/abs(l.dir)*s);
	return ret;
}

vector<P> cs_crosspoint(C c, L l){
	vector<P> ret, res = cl_crosspoint(c, l);
	REP(i, res.size()) if(sp_intersect(l, res[i])) ret.push_back(res[i]);
	return ret;
}

bool cl_intersect(C c, L l){
	return sp_distance(l, c.p) < c.r + EPS;	// 境界を含む
}

bool cs_intersect(C c, L l){
	return !cs_crosspoint(c, l).empty();
}


 
int n, m, r;
main(){
	while(cin >> n >> m >> r, n){
		vector<C> cir;
		vector<pair<P, double> > l;
		P e;
		REP(i, n){
			double x,y,z,r;
			cin >> x >> y >> z >> r;
			cir.push_back(C(P(x,y,z),r));
		}
		REP(i, m){
			double x,y,z,b;
			cin >> x >> y >> z >> b;
			l.push_back(mp(P(x,y,z),b));
		}
		cin >> e.x >> e.y >> e.z;
		REP(i, m){
			l[i].second /= norm(l[i].first - e);
//		  printf("%d is %f brights\n", i, l[i].second);
		}
		vector<int> lb(n);
		REP(i, n)REP(j, m){
//		  printf("dist(<%.0f,%.0f,%.0f>, <%.0f,%.0f,%.0f>, <%.0f,%.0f,%.0f>) = %f\n", cir[i].p.x, cir[i].p.y, cir[i].p.z, l[j].first.x, l[j].first.y, l[j].first.z, e.z, e.y, e.z, sp_distance(cir[i].p, l[j].first, e));
			if(sp_distance(cir[i].p, l[j].first, e) <= cir[i].r+EPS && !(norm(cir[i].p - l[j].first) <= cir[i].r*cir[i].r+EPS && norm(cir[i].p - e) <= cir[i].r*cir[i].r+EPS)){
				lb[i] |= 1<<j;
//			  printf("%d and %d is intersect\n", i, j);
			}
		}
		double ans = 0;
		REP(i, 1<<m){
			int b = 0;
			REP(j, n) if(lb[j] & i) b++;
			if(b > r) continue;
			double sum = 0;
			REP(j, m) if((i>>j)&1) sum += l[j].second;
			ans = max(ans, sum);
		}
		printf("%.10f\n", ans);
	}
	return 0;
}

Measured memory_bytes: 1384