#include <bits/stdc++.h>
using namespace std;
const long long INF = (long long)1e13 + 7LL;
int reqHigh[100100], grow[100100];
int n, nDay, allow, cut;
struct Tree {
  int id;
  long long finHigh, timeDie;
  Tree() { id = finHigh = timeDie = 0; }
  Tree(int id, long long x) {
    this->id = id;
    finHigh = x - 1LL * grow[id] * nDay;
    timeDie = min((x + 1) / grow[id] + ((x + 1) % grow[id] > 0), nDay + 1LL);
  }
  void cutTree(void) {
    finHigh += cut;
    long long tmp = finHigh + 1LL * grow[id] * nDay + 1;
    timeDie = min(tmp / grow[id] + (tmp % grow[id] > 0), nDay + 1LL);
  }
  bool needCut(void) const { return (finHigh < reqHigh[id]); }
  bool operator>(const Tree &t) const {
    if (timeDie != t.timeDie) return (timeDie < t.timeDie);
    return (reqHigh[id] - finHigh > reqHigh[t.id] - t.finHigh);
  }
  bool operator<(const Tree &t) const { return (t > *this); }
};
void init(void) {
  scanf("%d%d%d%d", &n, &nDay, &allow, &cut);
  for (int i = (1), _b = (n); i <= _b; i = i + 1)
    scanf("%d%d", &reqHigh[i], &grow[i]);
}
bool ok(long long x) {
  priority_queue<Tree> q;
  for (int i = (1), _b = (n); i <= _b; i = i + 1) q.push(Tree(i, x));
  for (int i = (1), _b = (nDay); i <= _b; i = i + 1) {
    Tree tmp = q.top();
    q.pop();
    if (tmp.timeDie <= i) return (false);
    q.push(tmp);
    int used = 0;
    while (used < allow) {
      Tree tmp = q.top();
      q.pop();
      if (!tmp.needCut()) return (true);
      tmp.cutTree();
      q.push(tmp);
      used++;
    }
  }
  Tree tmp = q.top();
  q.pop();
  return (!tmp.needCut());
}
long long process(void) {
  long long L = 1;
  long long R = INF;
  while (true) {
    if (L == R) return (R);
    if (R - L == 1) return (ok(L) ? L : R);
    long long M = (L + R) >> 1;
    if (ok(M))
      R = M;
    else
      L = M + 1;
  }
}
int main(void) {
  init();
  cout << process() << endl;
  return 0;
}
