#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

typedef vector<double> Array;
typedef vector<Array> Matrix;

int n;
Array sphere[110];
double radius[110];

inline double square(double x) { return x * x; }

inline double dist(const Array &p, const Array &q) {
  return sqrt(square(p[0] - q[0]) + square(p[1] - q[1]) + square(p[2] - q[2]));
}

Array normalize(const Array &vect) {
  double sum = 0.0;
  Array ret(3, 0);
  REP(i, 3) { sum += square(vect[i]); }
  sum = sqrt(sum);
  REP(i, 3) { ret[i] = vect[i] / sum; }
  return ret;
}

double calc(const Array &pos, const Array &v, int index) {
  double l = 0.01;
  double r = 1001.0;
  double ld, rd;
  REP(i, 200) {
    double lm = (l * 2.0 + r) / 3.0;
    double rm = (l + r * 2.0) / 3.0;
    Array lpos = pos;
    lpos[0] += v[0] * lm;
    lpos[1] += v[1] * lm;
    lpos[2] += v[2] * lm;
    Array rpos = pos;
    rpos[0] += v[0] * rm;
    rpos[1] += v[1] * rm;
    rpos[2] += v[2] * rm;
    ld = dist(lpos, sphere[index]);
    rd = dist(rpos, sphere[index]);
    //cout << lm << " " << rm << " " << ld << " " << rd << endl;
    if (ld < radius[index] || ld < rd) {
      r = rm;
    } else {
      l = lm;
    }
  }
  //cout << endl;
  if (ld - radius[index] > EPS) { return 1001.0; }
  return l;
}

int main() {
  while (scanf("%d", &n), n) {
    double x, y, z, r;
    scanf("%lf %lf %lf", &x, &y, &z);
    Array v(3);
    v[0] = x;
    v[1] = y;
    v[2] = z;
    REP(i, n) {
      scanf("%lf %lf %lf %lf", &x, &y, &z, &r);
      sphere[i] = Array(3);
      sphere[i][0] = x;
      sphere[i][1] = y;
      sphere[i][2] = z;
      radius[i] = r;
    }
    Array pos(3, 0);
    REP(iter, 100) {
      assert(iter <= 5);
      v = normalize(v);
      //cout << pos[0] << " " << pos[1] << " " << pos[2] << endl;
      double mindist = 1000;
      int index = -1;
      REP(i, n) {
        double d = calc(pos, v, i);
        if (d < mindist) {
          mindist = d;
          index = i;
        }
      }
      if (mindist == 1000) { break; }
      assert(index != -1);
      //cout << index << " " << mindist << endl;
      Array q = pos;
      q[0] += v[0] * mindist;
      q[1] += v[1] * mindist;
      q[2] += v[2] * mindist;
      Array normal(3, 0);
      normal[0] = q[0] - sphere[index][0];
      normal[1] = q[1] - sphere[index][1];
      normal[2] = q[2] - sphere[index][2];
      normal = normalize(normal);
      double cosTheta = v[0] * normal[0] + v[1] * normal[1] + v[2] * normal[2];
      double cos2Theta = -(2 * square(cosTheta) - 1.0);
      double c = sqrt(1 + 1 - 2 * cos2Theta);
      Array nv(3, 0);
      nv[0] = v[0] + c * normal[0];
      nv[1] = v[1] + c * normal[1];
      nv[2] = v[2] + c * normal[2];
      pos = q;
      v = nv;
    }
    printf("%.3lf %.3lf %.3lf\n", pos[0], pos[1], pos[2]);
  }
}

Measured memory_bytes: 976