#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <map>
#include <set>
using namespace std;


const double eps = 1e-6;
struct point {
	double x, y, z;
	point() {}
	point(double x, double y, double z) :x(x), y(y), z(z) {}
	point& operator-=(const point &p) { x -= p.x; y -= p.y; z -= p.z; return *this; }
	point& operator+=(const point &p) { x += p.x; y += p.y; z += p.z; return *this; }
	point& operator*=(double d) { x *= d; y *= d; z *= d; return *this; }
	point& operator/=(double d) { x /= d; y /= d; z /= d; return *this; }
};
point operator-(const point &p, const point &q) { point r(p); return r -= q; }
point operator+(const point &p, const point &q) { point r(p); return r += q; }
point operator*(const point &p, double d) { point r(p); r *= d; return r; }
point operator*(double d, const point &p) { return p*d; }
point operator/(const point &p, double d) { point r(p); r /= d; return r; }
ostream& operator<<(ostream &o, const point &p) {
	o << setprecision(10);
	o << p.x << " " << p.y << " " << p.z;
	return o;
}

struct sphere {
	point p; double r;
	sphere() {}
	sphere(point p, double r) :p(p), r(r) {}
};

struct line {
	point s, t;
	line(point s, point t) :s(s), t(t) {}
};

inline double dot(const point &a, const point &b) { return a.x*b.x + a.y*b.y + a.z*b.z; }
inline point cross(const point &a, const point &b) { return point(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 point &p) { return p.x*p.x + p.y*p.y + p.z*p.z; }
inline double abs(const point &p) { return sqrt(norm(p)); }
inline double abs(const line &l) { return abs(l.s - l.t); }

point projection(const line &l, const point &p) {
	double t = dot(p - l.s, l.s - l.t) / norm(l.s - l.t);
	return l.s + t*(l.s - l.t);
}

inline point reflection(const line &l, const point &p) { return p + 2.0*(projection(l, p) - p); }

bool intersect(const sphere &s, const line &l) {
	if(abs(l.t - s.p) < s.r - eps) return 1;
	point p = projection(l, s.p);
	return abs(p - l.s) + abs(p - l.t) - abs(l) < eps && abs(p - s.p) < s.r - eps;
}
point cross_point(const sphere &s, const line &l) {
	point p = projection(l, s.p);
	double d = sqrt(s.r*s.r - norm(p - s.p));
	return p + (l.s - l.t) / abs(l)*d;
}


int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int N;
	while(cin >> N, N) {
		point s;
		cin >> s.x >> s.y >> s.z;
		line l(point(0, 0, 0), s / abs(s) * 500);

		vector<sphere> sp(N);
		for(int i = 0; i < N; i++) {
			cin >> sp[i].p.x >> sp[i].p.y >> sp[i].p.z >> sp[i].r;
		}

		point ans;
		while(1) {
			int idx = -1;
			bool hit = false;
			double dist = 1e9;
			point hitP;
			for(int i = 0; i < N; i++) {
				if(intersect(sp[i], l)) {
					point p = cross_point(sp[i], l);
					if(dot(p - l.s, l.t - l.s) < 0) continue;
					hit = true;
					double d = abs(l.s - p);
					if(dist > d) {
						dist = d;
						hitP = p;
						idx = i;
					}
				}
			}
			if(!hit) break;
			ans = hitP;
			line H(sp[idx].p, hitP);
			point ref = reflection(H, l.s);
			point dir = ref - hitP;
			dir = dir / abs(dir) * 500;
			l = line(hitP, hitP + dir);
		}
		cout << ans << endl;
	}
}

Measured memory_bytes: 3196