#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
inline void amin(T &x, U y) {
  if (y < x) x = y;
}
template <typename T, typename U>
inline void amax(T &x, U y) {
  if (x < y) x = y;
}
struct UnionFind {
  vector<int> data;
  void init(int n) { data.assign(n, -1); }
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
struct GModInt {
  static int Mod;
  int x;
  GModInt() : x(0) {}
  GModInt(signed sig) {
    if ((x = sig % Mod + Mod) >= Mod) x -= Mod;
  }
  GModInt(signed long long sig) {
    if ((x = sig % Mod + Mod) >= Mod) x -= Mod;
  }
  int get() const { return x; }
  GModInt &operator+=(GModInt that) {
    if ((x += that.x) >= Mod) x -= Mod;
    return *this;
  }
  GModInt &operator-=(GModInt that) {
    if ((x += Mod - that.x) >= Mod) x -= Mod;
    return *this;
  }
  GModInt &operator*=(GModInt that) {
    x = (unsigned long long)x * that.x % Mod;
    return *this;
  }
  GModInt &operator/=(GModInt that) { return *this *= that.inverse(); }
  GModInt operator+(GModInt that) const { return GModInt(*this) += that; }
  GModInt operator-(GModInt that) const { return GModInt(*this) -= that; }
  GModInt operator*(GModInt that) const { return GModInt(*this) *= that; }
  GModInt operator/(GModInt that) const { return GModInt(*this) /= that; }
  GModInt inverse() const {
    long long a = x, b = Mod, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    return GModInt(u);
  }
  GModInt operator-() const {
    GModInt t;
    t.x = x == 0 ? 0 : Mod - x;
    return t;
  }
};
int GModInt::Mod = 0;
int main() {
  int n, m, dx, dy;
  scanf("%d%d%d%d", &n, &m, &dx, &dy);
  GModInt::Mod = n;
  vector<int> x(m), y(m);
  for (int(i) = 0; (i) < (int)(m); ++(i)) scanf("%d%d", &x[i], &y[i]);
  UnionFind uf;
  uf.init(m + n);
  GModInt idy = GModInt(dy).inverse();
  for (int(i) = 0; (i) < (int)(m); ++(i)) {
    GModInt a = -(idy * y[i]);
    GModInt xx = GModInt(x[i]) + a * dx;
    uf.unionSet(i, m + xx.get());
  }
  vector<int> cnt(m + n, 0);
  for (int(i) = 0; (i) < (int)(m); ++(i)) ++cnt[uf.root(i)];
  int ans = 0, ansy = 0, ansx = 0;
  for (int(i) = 0; (i) < (int)(m); ++(i)) {
    int t = cnt[uf.root(i)];
    if (ans < t) ans = t, ansy = y[i], ansx = x[i];
  }
  printf("%d %d\n", ansx, ansy);
  return 0;
}
