#include <bits/stdc++.h>
using namespace std;

typedef long double flt;
typedef pair<int, int> PII;
const flt eps = 1e-8, inf = 1e9;
const int MAXN = 200000 + 10;

inline int sgn(flt x) {
    if (x < -eps) return -1;
    else return x > eps;
}

struct Point {
    flt x, y, z;
    int idx;
    Point() {}
    Point(flt _x, flt _y, flt _z, int _i = -1) : x(_x), y(_y), z(_z), idx(_i) {}
    bool operator < (const Point &rhs) const {
        if (sgn(x - rhs.x) != 0) return sgn(x - rhs.x) < 0;
        if (sgn(y - rhs.y) != 0) return sgn(y - rhs.y) < 0;
        if (sgn(z - rhs.z) != 0) return sgn(z - rhs.z) < 0;
        return idx < rhs.idx;
    }
    bool operator == (const Point &rhs) const {
        return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0 && sgn(z - rhs.z) == 0;
    }
    Point operator - (const Point &rhs) const {
        return Point(x - rhs.x, y - rhs.y, z - rhs.z);
    }
    flt abs() {
        return sqrt(x * x + y * y + z * z);
    }
    void out() {
        cout << x << " " << y << " " << z << endl;
    }
};

vector<int> V[MAXN];
Point P[MAXN];
int N, M, S, W;

inline bool cmpX(const Point &a, const Point &b) {
    return sgn(a.x - b.x) < 0;
}

inline bool cmpY(const Point &a, const Point &b) {
    return sgn(a.y - b.y) < 0;
}

inline bool cmpZ(const Point &a, const Point &b) {
    return sgn(a.z - b.z) < 0;
}

flt close_point(Point P[], int N, PII &ret) {
    int mid = N / 2;
    if (N == 1) {
        ret = PII(-1, -1);
        return inf;
    }
    if (N == 2) {
        ret = PII(P[0].idx, P[1].idx);
        if (ret.second < ret.first) swap(ret.first, ret.second);
        return (P[0] - P[1]).abs();
    }
    PII tmp(-1, -1);
    flt dis = close_point(P, mid, ret);
    flt dtmp = close_point(P + mid, N - mid, tmp);
    if (ret.first == -1) ret = tmp, dis = dtmp;
    if (sgn(dtmp - dis) < 0) ret = tmp, dis = dtmp;
    else if (sgn(dtmp - dis) == 0 && tmp < ret) ret = tmp;
    vector<Point> qt; qt.clear();
    for (int i = 0; i < N; ++ i) {
        if (fabs(P[i].x - P[mid].x) < dis + eps) qt.push_back(P[i]);
    }
    sort(qt.begin(), qt.end(), cmpY);
    for (int i = 0, n = qt.size(); i < n; ++ i) {
        for (int j = 1; j < 16; ++ j) {
            if (i + j < n) {
                dtmp = (qt[i] - qt[j + i]).abs();
                tmp = PII(qt[i].idx, qt[j + i].idx);
                if (tmp.second < tmp.first) swap(tmp.first, tmp.second);
                if (ret.first == -1) ret = tmp, dis = dtmp;
                if (sgn(dtmp - dis) < 0) ret = tmp, dis = dtmp;
                else if (sgn(dtmp - dis) == 0 && tmp < ret) ret = tmp;
            }
            else break;
        }
    }
    return dis;
}

int main() {
    while (scanf("%d%d%d%d", &M, &N, &S, &W) == 4 && (N + M)) {
        for (int i = 0; i < M; ++ i) {
            V[i].resize(3);
            scanf("%d%d%d", &V[i][0], &V[i][1], &V[i][2]);
        }
        N += M;
        for (int i = M, g = S; i < N; ++ i) {
            V[i].resize(3);
            V[i][0] = (g / 7) % 100 + 1;
            V[i][1] = (g / 700) % 100 + 1;
            V[i][2] = (g / 70000) % 100 + 1;
            if (g % 2 == 0) g = g >> 1;
            else g = (g >> 1) ^ W;
        }
        sort(V, V + N);
        for (int i = 0; i < N; ++ i) {
            flt len = sqrt((flt)V[i][0] * V[i][0] + (flt)V[i][1] * V[i][1] + (flt)V[i][2] * V[i][2]);
            P[i] = Point(V[i][0] / len, V[i][1] / len, V[i][2] / len, i);
        }
        sort(P, P + N);
        M = 1;
        for (int i = 1; i < N; ++ i) {
            if (P[i] == P[i - 1]) continue;
            else P[M ++] = P[i];
        }
        PII ret;
        close_point(P, M, ret);
        printf("%d %d %d ", V[ret.first][0], V[ret.first][1], V[ret.first][2]);
        printf("%d %d %d\n", V[ret.second][0], V[ret.second][1], V[ret.second][2]);
    }
}
