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

const int MAXN = 300000 + 10;

struct Point {
    int x, y, z;
    Point() {}
    Point(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
    bool operator < (const Point &rhs) const {
        return x < rhs.x || (x == rhs.x && y < rhs.y) || (x == rhs.x && y == rhs.y && z < rhs.z);
    }
} P[MAXN];

map<int, int> best[MAXN];
int dp[MAXN], ret;

int r(int &a, int &b) {
    static const int C = ~(1u << 31), M = (1 << 16) - 1;
    a = 36969 * (a & M) + (a >> 16);
    b = 18000 * (b & M) + (b >> 16);
    return (C & ((a << 16) + b)) % 1000000;
}

inline bool check(const map<int, int> &mp, int x, int y) {
    auto it = mp.lower_bound(x);
    return it != mp.begin() && (-- it)->second < y;
}

int query(int x, int y) {
    int left = 0, right = ret;
    while (left < right) {
        int mid = (left + right + 1) >> 1;
        if (check(best[mid], x, y)) left = mid;
        else right = mid - 1;
    }
    return left;
}

void update(map<int, int> &mp, int x, int y) {
    auto it = mp.upper_bound(x);
    if (it != mp.begin() && (-- it)->second <= y) return;
    it = mp.lower_bound(x);
    while (it != mp.end() && it->second >= y) mp.erase(it ++);
    mp[x] = y;
}

int main() {
    int N, M, A, B;
    while (scanf("%d%d%d%d", &M, &N, &A, &B) == 4 && (N + M)) {
        for (int i = 0; i < M; ++ i) {
            scanf("%d%d%d", &P[i].x, &P[i].y, &P[i].z);
        }
        N += M;
        for (int i = M; i < N; ++ i) {
            P[i].x = r(A, B);
            P[i].y = r(A, B);
            P[i].z = r(A, B);
        }
        for (int i = 0; i <= N; ++ i) best[i].clear();
        sort(P, P + N);
        ret = 0;
        for (int i = 0, j; i < N;) {
            for (j = i; j < N && P[i].x == P[j].x; ++ j) dp[j] = query(P[j].y, P[j].z) + 1;
            for (; i < j; ++ i) {
                update(best[dp[i]], P[i].y, P[i].z);
                ret = max(ret, dp[i]);
            }
        }
        printf("%d\n", ret);
    }
    return 0;
}
