#include <bits/stdc++.h>
using namespace std;
namespace FGF {
int n, m, K;
const int N = 1e5 + 5;
struct Node {
  long long d;
  int id;
  Node(){};
  Node(long long _d, int _id) : d(_d), id(_id){};
};
long long h[N], a[N], p, ans;
int c[N];
bool operator<(Node x, Node y) { return x.d > y.d; }
priority_queue<Node> q;
bool check(long long x) {
  while (q.size()) q.pop();
  memset(c, 0, sizeof(c));
  for (int i = 1; i <= n; i++)
    if (x - a[i] * m < h[i]) q.push(Node(x / a[i], i));
  for (int i = 1; i <= m && q.size(); i++)
    for (int j = 1; j <= K && q.size(); j++) {
      Node u = q.top();
      q.pop();
      if (u.d < i) return 0;
      c[u.id]++;
      if (x + c[u.id] * p - a[u.id] * m < h[u.id])
        q.push(Node((x + c[u.id] * p) / a[u.id], u.id));
    }
  return q.empty();
}
void work() {
  scanf("%d%d%d%lld", &n, &m, &K, &p);
  long long l = 0, r = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%lld%lld", &h[i], &a[i]);
    r = max(r, h[i] + a[i] * m);
  }
  while (l <= r) {
    long long mid = (l + r) >> 1;
    if (check(mid))
      ans = mid, r = mid - 1;
    else
      l = mid + 1;
  }
  printf("%lld", ans);
}
}  // namespace FGF
int main() {
  FGF::work();
  return 0;
}
