#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

#define MAXN 524288
#define MAXC 1048576
#define NO_VALUE -1

#define LEFT(x) ( 2*(x) )
#define RIGHT(x) ( 2*(x)+1 )

int A, B, C, M;

int r() {
    A = 36969 * (A & M) + (A >> 16);
    B = 18000 * (B & M) + (B >> 16);
    return (C & ((A << 16) + B)) % 1000000;
}

int x[MAXN], y[MAXN], z[MAXN], ox[MAXN], val[MAXN], N, BEST;

bool cmp_x(const int &a, const int &b) { return x[a] < x[b]; }

map<int, int> best[MAXN];

int query(int cury, int curz) {
    int s = 0, e = N, mid;
    while (e-s > 1) {
        mid = (s+e)/2;
        map<int, int>::iterator it = best[mid].lower_bound(cury);
        if (it != best[mid].begin() && (--it)->second < curz) s = mid;
        else e = mid;
    }
    return s+1;
}

void update(int cury, int curz, int v) {
    map<int, int>::iterator it1, it2;

    BEST = max(BEST, v);

    it1 = it2 = best[v].lower_bound(cury);
    while (it2 != best[v].end() && it2->second >= curz) it2++;
    best[v].erase(it1, it2);

    it1 = best[v].upper_bound(cury);
    if (it1 == best[v].begin() || (--it1)->second > curz) best[v][cury] = curz;
}

int main() {
    int m, n, i, j;

    while (scanf("%d %d %d %d", &m, &n, &A, &B) && (m || n || A || B)) {
        C = ~(1<<31); M = (1<<16)-1;
        for (i=0; i<m; i++) scanf("%d %d %d", &x[i], &y[i], &z[i]);
        for (i=m; i<m+n; i++) { x[i] = r(); y[i] = r(); z[i] = r(); }
        N = m+n;

        for (i=0; i<N; i++) ox[i] = i;
        sort(ox, ox+N, cmp_x);

        for (i=1; i<=N; i++) best[i].clear();

        i = BEST = 0;
        do {
            for (j=i; j<N && x[ox[j]]==x[ox[i]]; j++) val[j] = query(y[ox[j]], z[ox[j]]);
            for (; i<j; i++) update(y[ox[i]], z[ox[i]], val[i]);
        } while (i < N);
        printf("%d\n", BEST);
    }

    return 0;
}