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

using pii = pair<int,int>;
using ll = long long;
using ld = long double;
#define rep(i, j) for(int i=0; i < (int)(j); i++)
#define repeat(i, j, k) for(int i = (j); i < (int)(k); i++)
#define all(v) v.begin(),v.end()
#define debug(x) cerr << #x << " : " << x << endl

template<class T> bool set_min(T &a, const T &b) { return a > b  ? a = b, true : false; }
template<class T> bool set_max(T &a, const T &b) { return a < b  ? a = b, true : false; }
// vector
template<class T> istream&
operator >> (istream &is , vector<T> &v) { for(T &a : v) is >> a; return is; }
template<class T> ostream&
operator << (ostream &os , const vector<T> &v) { for(const T &t : v) os << "\t" << t; return os << endl; }
// pair
template<class T, class U> ostream&
operator << (ostream &os , const pair<T, U> &v) { return os << "<" << v.first << ", " << v.second << ">"; }

const int INF = 1 << 30;
const ll INFL = 1LL << 60;
const ld EPS = 1e-9;
bool eq(ld a, ld b) { return abs(a - b) < EPS; }
template<class T>
struct Point {
    T x, y, z;
    bool operator < (const Point<T> &r) const {
        return make_tuple(x, y, z) < make_tuple(r.x, r.y, r.z);
    }
};
template<class T>
ld length(const Point<T> &p) { return sqrtl(p.x * p.x + p.y * p.y + p.z * p.z); }
template<class T>
ld dot(const Point<T> &a, const Point<T> &b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
template<class T>
ld angle(const Point<T> &a, const Point<T> &b) {
    return acosl(dot(a, b) / length(a) / length(b));
}
template<class T>
Point<ld> unit(Point<T> a) {
    Point<ld> p = {(ld)a.x, (ld)a.y, (ld)a.z};
    ld l = length(p);
    p.x /= l;
    p.y /= l;
    p.z /= l;
    return p;
}

bool solve() {
    int m, n, S, W; cin >> m >> n >> S >> W;
    if(m == 0 and n == 0 and S == 0 and W == 0) return false;
    vector<Point<int>> VI(m + n);
    rep(i, m) {
        cin >> VI[i].x >> VI[i].y >> VI[i].z;
    }
    int g = S;
    for(int i=m; i<m+n; i++) {
        VI[i].x = (g/7)    %100 + 1;
        VI[i].y = (g/700)  %100 + 1;
        VI[i].z = (g/70000)%100 + 1;
        if( g%2 == 0 ) { g = (g/2); }
        else           { g = (g/2) ^ W; }
    }
    sort(all(VI), [&] (Point<int> a, Point<int> b) {
            return unit(a).x > unit(b).x;
        });
    ld min_angle = 1e9;    
    Point<int> a, b;

    auto need_check = [&] (Point<int> &a, Point<int> &b) {
        ld alpha = acosl(unit(a).x);
        auto ss = cosl(alpha + min_angle);
        auto tt = unit(b).x;
        // cerr << ss << " " << tt << endl;
        return ss < tt + EPS*10;
    };
    
    queue<Point<int>> que;
    rep(i, VI.size()) {
        queue<Point<int>> nxt_que;
        while(que.size()) {
            auto p = que.front(); que.pop();
            if(not need_check(p, VI[i])) continue;
            ld ang = angle(VI[i], p);
            if(ang > EPS) {
                if(min_angle + EPS > ang) {                    
                    auto aa = VI[i], bb = p;
                    if(bb < aa) swap(aa, bb);
                    if(!eq(min_angle, ang) or make_pair(a, b) > make_pair(aa, bb)) {
                        a = aa;
                        b = bb;
                    }
                    min_angle = ang;
                }
            }
            nxt_que.push(p);
        }
        nxt_que.push(VI[i]);
        swap(que, nxt_que);
    }
    printf("%d %d %d %d %d %d\n",
           a.x, a.y, a.z,
           b.x, b.y, b.z);
    return true;
}

int main() {
    while(solve());
    return 0;
}