#include <bits/stdc++.h>
using namespace std;
#define out(x) cerr<<#x"="<<x<<endl
#define REP(i,n) for(int i=0; i<int(n); i++)
#define pb push_back
#define mp make_pair
#define X first
#define Y second
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
const double eps=1e-12;
struct CMP;
typedef double TData;
const int nDim=3;
template <class T>
T sqr(T x){return x*x;}
struct Pt{
    array<TData, nDim> x;
    int id;
    friend struct CMP;
    friend TData dis(Pt a, Pt b){
        TData res=0;
        for(int i=0; i<nDim; ++i)
            res+=sqr(a.x[i]-b.x[i]);
        return sqrt(res);
    }
};
struct CMP{
    int dim;
    bool operator()(const Pt &l, const Pt &r) const {
        return l.x[dim] < r.x[dim];
    }
} cmp;
bool vis[101][101][101];
vector<Pt> v;
struct Vec{
	array<int, 3> x;
	int len;
	void get(){
		scanf("%d%d%d",&x[0],&x[1],&x[2]);
	}
	void calc(){
		len=0;
		REP(i,3)len+=sqr(x[i]);
	}
	bool operator<(Vec r) const {
		return x<r.x;
	}
	bool &visit(){
		int g=__gcd(x[0], x[1]);
		g=__gcd(g, x[2]);
		return vis[x[0]/g][x[1]/g][x[2]/g];
	}
} pts[123456];
inline pii get_dis(pii &pr){
	int u=pr.X, v=pr.Y;
	int a=pts[u].len, b=pts[v].len, c=0;
	REP(i,3)c+=sqr(pts[u].x[i]-pts[v].x[i]);
	return mp(a+b-c, a*b);
}
inline bool cmp_dis_accurately(pii &a, pii &b){
	pii d0=get_dis(a), d1=get_dis(b);
	//check whether (d0.X)^2/d0.Y > (d1.X)^2/d1.Y
	LL res = d0.X*(LL)d0.X*d1.Y - d1.X*(LL)d1.X*d0.Y;
	if(res!=0)return res>0;
	return a < b;
}
//find the closest pair in v[l, r)
//make sure v is sorted by dimension[0] in ascending order before calling closest_pair()
TData min_dis=1e9; //This number should be large enough
pii best_pair=mp(-1,-1); //stores the closest pair
void take_best(Pt a, Pt b){
	if(a.id>b.id)swap(a,b);
	pii can_pair=mp(a.id, b.id);
    if(best_pair.X==-1 || cmp_dis_accurately(can_pair, best_pair)){
    	best_pair=can_pair;
    	min_dis=dis(a, b)+eps;
    }
}
void closest_pair(vector<Pt> &v, int l, int r, int dim=0){
    if(dim+1==nDim){
		//This part will not be executed
        int z=nDim-1;
        REP(i, v.size())
            for(int j=1; i+j<v.size() && v[j].x[z]-v[i].x[z]<=min_dis; ++j)
                take_best(v[i], v[i+j]);
		return;
    } else if(r-l<=100){
        for(int i=l+1; i<r; ++i)
            for(int j=l; j<i; ++j)
                take_best(v[i], v[j]);
    	return;
    }
    int m=(l+r)/2;
    closest_pair(v, l, m, dim);
    closest_pair(v, m, r, dim);
    vector<Pt> vtmp;
    REP(i,v.size())if(abs(v[i].x[dim]-v[m].x[dim])<=min_dis)
        vtmp.pb(v[i]);
    cmp.dim=dim+1;
    sort(vtmp.begin(), vtmp.end(), cmp);
    closest_pair(vtmp, 0, vtmp.size(), dim+1);
}
int main(){
    int m, n, S, W;
	v.reserve(123456);
    while(scanf("%d%d%d%d",&m,&n,&S,&W)==4 && (m||n||S||W)){
        min_dis=1e9;
        best_pair=mp(-1, -1);
		v.resize(0);
        REP(i,m)pts[i].get();
		int g=S;
		for(int i=m; i<m+n; ++i){
			pts[i].x[0]=(g/7)%100+1;
			pts[i].x[1]=(g/700)%100+1;
			pts[i].x[2]=(g/70000)%100+1;
			if(g%2==0)g=g/2;
			else g=(g/2)^W;
		}
		sort(pts, pts+m+n);
		REP(i,m+n)if(!pts[i].visit()){
			pts[i].visit()=1;
			pts[i].calc();
			Pt tmp;
			REP(j,3)tmp.x[j]=pts[i].x[j];
			double len=sqrt(pts[i].len);
			REP(j,3)tmp.x[j]/=len;
			tmp.id=i;
            v.pb(tmp);
		}
        cmp.dim=0;
        sort(v.begin(), v.end(), cmp);
        closest_pair(v, 0, v.size());
		int u=best_pair.X, v=best_pair.Y;
		REP(i,3)printf("%d ", pts[u].x[i]);
		REP(i,3)printf("%d%c", pts[v].x[i], i==2?'\n':' ');
		REP(i,m+n)pts[i].visit()=0;
    }
	//out(max_gao);
}
