#include <bits/stdc++.h>
const int maxn = 1e5 + 10;
using namespace std;
long long n, m, k, p;
long long high[maxn], v[maxn];
long long cnt[maxn];
long long max(long long a, long long b) { return a > b ? a : b; }
inline long long read() {
  long long res = 0;
  bool flag = 1;
  char c = getchar();
  while (c > '9' || c < '0')
    if (c == '-') flag = 0, c = getchar();
  while (c <= '9' && c >= '0')
    res = (res << 3) + (res << 1) + (c ^ '0'), c = getchar();
  return flag ? res : -res;
}
struct hehe {
  long long day, order;
} a[maxn];
bool operator<(hehe a, hehe b) { return a.day > b.day; }
priority_queue<hehe> je;
bool check(long long x) {
  while (!je.empty()) je.pop();
  memset(cnt, 0, sizeof(cnt));
  for (register long long i = 1; i <= n; i++) {
    if (x - v[i] * m < high[i]) {
      hehe xy;
      xy.day = x / v[i];
      xy.order = i;
      je.push(xy);
    }
  }
  for (int i = 1; !je.empty() && i <= m; i++) {
    for (int j = 1; !je.empty() && j <= k; j++) {
      hehe xy = je.top();
      je.pop();
      if (xy.day < i) return false;
      cnt[xy.order]++;
      if (x + cnt[xy.order] * p - m * v[xy.order] < high[xy.order]) {
        hehe temp;
        temp.day = (x + cnt[xy.order] * p) / v[xy.order];
        temp.order = xy.order;
        je.push(temp);
      }
    }
  }
  return je.empty();
}
int main() {
  scanf("%lld%lld%lld%lld", &n, &m, &k, &p);
  long long l = 0, r = 0;
  long long mid, ans;
  for (register long long i = 1; i <= n; i++) {
    scanf("%lld%lld", &high[i], &v[i]);
    r = max(r, high[i] + m * v[i]);
  }
  while (l <= r) check(mid = l + r >> 1) ? ans = mid, r = mid - 1 : l = mid + 1;
  printf("%lld", ans);
  return 0;
}
