#include<stdio.h>
#include<vector>
#include<queue>

int n,m,k;

std::vector<std::vector<std::pair<int, int>>> adjList;

int t, t2, t3;

bool visited[100100];
int result = 0;
int matrix[100100];
int matrix2[100100];
std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>>pq;

int main(){

	scanf("%d %d %d", &n, &m, &k);
	//fflush(stdin);

	adjList.assign(n+1, std::vector<std::pair<int, int>>());

	for(int i = 0; i < m ; i ++){
		scanf("%d %d %d", &t, &t2, &t3);
		//fflush(stdin);

		//adjList[t].push_back(std::make_pair(t2,t3));
		//adjList[t2].push_back(std::make_pair(t,t3));

		if( t == 1){

			adjList[t2].push_back(std::make_pair(t,t3));

			if(matrix2[t2] == 0)
				matrix2[t2] = t3;
			else if(matrix2[t2] > t3)
				matrix2[t2] = t3;
		}
		else if(t2 == 1){

			adjList[t].push_back(std::make_pair(t2,t3));

			if(matrix2[t] == 0)
				matrix2[t] = t3;
			else if(matrix2[t] > t3)
				matrix2[t] = t3;
		}
		else{
			adjList[t].push_back(std::make_pair(t2,t3));
			adjList[t2].push_back(std::make_pair(t,t3));
		}
	}

	for(int i = 0; i < k; i ++){
		scanf("%d %d", &t, &t2);
		//fflush(stdin);

		adjList[t].push_back(std::make_pair(1,t2));
		//adjList[1].push_back(std::make_pair(t,t2));

		if(matrix[t] == 0)
			matrix[t] = t2;
		else if(matrix[t] > t2)
			matrix[t] = t2;

		result++;
	}

	long long before;

	std::pair<long long, int> c;

	int vb;

	bool flag;

	int tem;

	for(int i = 0; i < 100100; i ++)
		visited[i] = 0;

	for(int i = 2 ; i < n+1 ; i ++){

		vb = i;

		while(!pq.empty())
			pq.pop();

		c.second = i;
		before = 0;

		while(1){

			visited[c.second] = 1;

			tem = adjList[c.second].size();

			while(!adjList[c.second].empty()){

				if(adjList[c.second][0].first != vb){
					pq.push(std::pair<long long, int>(before+adjList[c.second][0].second, adjList[c.second][0].first));
					adjList[c.second].erase(adjList[c.second].begin());
				}
			}

			if(pq.empty() )
				break;

			vb = c.second;

			do{
				visited[c.second] = 0;

				c = pq.top();
				pq.pop();

			}while(visited[c.second] == 1 && !pq.empty());

			if(c.second == 1 && c.first == matrix[i]){

				if(matrix2[i] == 0){

					if(before == 0){
						result--;
						matrix[i] = -(matrix[i]);
					}
					else if((matrix[i] !=  (before + matrix2[vb])) &&  (matrix[i] !=  (before + abs(matrix[vb])))){

						result--;
						matrix[i] = -(matrix[i]);
					}
				}
				else{
					if(matrix[i] != matrix2[i]){

						result--;
						matrix[i] = -(matrix[i]);
					}
				}
			}

			before = c.first;

			if(c.second == 1 )
				break;
		}

	}

	printf("%d\n", result);
	//getchar();

	return 0;
}


#include<stdio.h>
#include<vector>
#include<queue>

#define INF 1e18;

int n,m,k;

std::vector<std::vector<std::pair<int, int>>> adjList;

int t, t2, t3;

int path[100010];
int result = 0;
int matrix[100010];
int matrix2[300010];
long long dist[100010];
std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>>pq;

int main(){

	scanf("%d %d %d", &n, &m, &k);

	adjList.assign(n+1, std::vector<std::pair<int, int>>());

	for(int i = 0; i < m ; i ++){
		scanf("%d %d %d", &t, &t2, &t3);

		adjList[t].push_back(std::make_pair(t2,t3));
		adjList[t2].push_back(std::make_pair(t,t3));

		if( t == 1){

			if(matrix2[t2] == 0)
				matrix2[t2] = t3;
			else if(matrix2[t2] > t3)
				matrix2[t2] = t3;
		}
		else if(t2 == 1){

			if(matrix2[t] == 0)
				matrix2[t] = t3;
			else if(matrix2[t] > t3)
				matrix2[t] = t3;
		}

	}

	for(int i = 0; i < k; i ++){
		scanf("%d %d", &t, &t2);

		adjList[t].push_back(std::make_pair(1,t2));
		adjList[1].push_back(std::make_pair(t,t2));

		if(matrix[t] == 0)
			matrix[t] = t2;
		else if(matrix[t] > t2)
			matrix[t] = t2;
	}

	result = k;

	std::pair<long long, int> c;
	std::pair<long long, int> c2;

	for(int i  = 2; i < 100010; i ++)
		dist[i] = INF;

	dist[1] = 0;
	pq.push(std::make_pair(0,1));

	while(!pq.empty()){

		c = pq.top();
		pq.pop();

		int d = c.first, u = c.second;
		if(d > dist[c.second]) continue;

		while(!adjList[u].empty()){
			c2 = adjList[u][0];
			if(dist[u] + c2.second <= dist[c2.first]){
				dist[c2.first] = dist[u] + c2.second;
				path[c2.first] = u;
				pq.push(std::make_pair(dist[c2.first], c2.first));
			}

			adjList[u].erase(adjList[u].begin());
		}
	}

	for(int i  = 2; i < n+1; i ++){
		if(dist[i] == matrix[i]){
			if(path[i] == 1 ){
				if(dist[i] != matrix2[i])
					result--;
			}
		}
	}

	printf("%d\n", result);
	//system("pause");

	return 0;
}


#include<stdio.h>
#include<vector>
#include<queue>

#define INF 1e18

int n,m,k;

std::vector<std::vector<std::pair<int, int>>> adjList;

int t, t2, t3;

int visited[101000];
int result = 0;
int matrix[101000];
int matrix2[101000];
std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>>pq;

int main(){

	scanf("%d %d %d", &n, &m, &k);
	//fflush(stdin);

	adjList.assign(n+1, std::vector<std::pair<int, int>>());

	for(int i = 0; i < m ; i ++){
		scanf("%d %d %d", &t, &t2, &t3);
		//fflush(stdin);

		adjList[t].push_back(std::make_pair(t2,t3));
		adjList[t2].push_back(std::make_pair(t,t3));

		if( t == 1){
			if(matrix2[t2] == 0)
				matrix2[t2] = t3;
			else if(matrix2[t2] > t3)
				matrix2[t2] = t3;
		}
		else if(t2 == 1){
			if(matrix2[t] == 0)
				matrix2[t] = t3;
			else if(matrix2[t] > t3)
				matrix2[t] = t3;
		}

	}

	for(int i = 0; i < k; i ++){
		scanf("%d %d", &t, &t2);
		//fflush(stdin);

		adjList[t].push_back(std::make_pair(1,t2));
		adjList[1].push_back(std::make_pair(t,t2));

		if(matrix[t] == 0)
			matrix[t] = t2;
		else if(matrix[t] > t2)
			matrix[t] = t2;

		result++;
	}

	long long before;

	std::pair<long long, int> c;

	int vb;

	bool flag;

	for(int i = 2 ; i < n+1 ; i ++){

		vb = i;

		while(!pq.empty())
			pq.pop();

		c.second = i;
		before = 0;

		while(1){

			visited[c.second] = 1;

			for(int j = 0 ; j < adjList[c.second].size(); j ++){

				if(
					adjList[c.second][j].first != vb){

					pq.push(std::pair<long long, int>(before+adjList[c.second][j].second, adjList[c.second][j].first));
				}
			}

			if(pq.empty() )
				break;

			vb = c.second;

			do{
				visited[c.second] = 0;

				c = pq.top();
				pq.pop();

			}while(visited[c.second] == 1 && !pq.empty());

			if(c.second == 1 && c.first == matrix[i]){

				if(matrix2[i] == 0){

					if(before == 0){
						result--;
						matrix[i] = -(matrix[i]);
					}
					else if((matrix[i] !=  (before + matrix2[vb])) &&  (matrix[i] !=  (before + abs(matrix[vb])))){

						result--;
						matrix[i] = -(matrix[i]);
					}
				}
				else{
					if(matrix[i] != matrix2[i]){

						result--;
						matrix[i] = -(matrix[i]);
					}
				}
			}

			before = c.first;

			if(c.second == 1 )
				break;
		}

	}

	printf("%d\n", result);
	//getchar();

	return 0;
}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAX=30001;
int dp[MAX][500],gem[MAX];
bool check[MAX][500];
int n,d,pistol;
int solve(int u,int v)
{
	if(u==MAX-1) return gem[MAX-1];
	if(check[u][v-pistol]) return dp[u][v-pistol];
	int tempA=0;
	int tempB=0;
	int tempC=0;
	if(u+v<MAX) tempB=solve(u+v,v);
	if(v>1&&u+v-1<MAX) tempA=solve(u+v-1,v-1);
	if(u+v+1<MAX) tempC=solve(u+v+1,v+1);
	dp[u][v]=gem[u]+max(max(tempA,tempB),tempC);
	check[u][v-pistol]=true;
	return dp[u][v];
}
int main()
{
	int a;
	cin>>n>>d;
	for(int i=1;i<=n;++i){
		cin>>a;
//		a=939;
		gem[a]++;
	}
	int t=245;
	if(d<=t) pistol=0;
	else pistol=d-249;
	cout<<solve(d,d)<<endl;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAX=30001;
int dp[MAX][500],gem[MAX];
bool check[MAX][500];
int n,d,pistol;
int solve(int u,int v)
{
	if(u==MAX-1) return gem[MAX-1];
	if(check[u][v-pistol]) return dp[u][v-pistol];
	int tempA=0;
	int tempB=0;
	int tempC=0;
	if(u+v<MAX) tempB=solve(u+v,v);
	if(v>1&&u+v-1<MAX) tempA=solve(u+v-1,v-1);
	if(u+v+1<MAX) tempC=solve(u+v+1,v+1);
	dp[u][v]=gem[u]+max(max(tempA,tempB),tempC);
	check[u][v]=true;
	return dp[u][v];
}
int main()
{
	int a;
	cin>>n>>d;
	for(int i=1;i<=n;++i){
		cin>>a;
		gem[a]++;
	}
	int t=245;
	if(d<=t) pistol=0;
	else pistol=d-249;
	cout<<solve(d,d)<<endl;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAX=30001;
int dp[MAX][500],gem[MAX];
bool check[MAX][500];
int n,d,pistol;
int solve(int u,int v)
{
	if(u==MAX-1) return gem[MAX-1];
	if(check[u][v-pistol]) return dp[u][v-pistol];
	int tempA=0;
	int tempB=0;
	int tempC=0;
	if(u+v<MAX) tempB=solve(u+v,v);
	if(v>1&&u+v-1<MAX) tempA=solve(u+v-1,v-1);
	if(u+v+1<MAX) tempC=solve(u+v+1,v+1);
	dp[u][v-pistol]=gem[u]+max(max(tempA,tempB),tempC);
	check[u][v-pistol]=true;
	return dp[u][v];
}
int main()
{
	int a;
	cin>>n>>d;
	for(int i=1;i<=n;++i){
		cin>>a;
//		a=939;
		gem[a]++;
	}
	int t=245;
	if(d<=t) pistol=0;
	else pistol=d-249;
	cout<<solve(d,d)<<endl;
	return 0;
}


#include <vector>
#include <stdio.h>
#include <string.h>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
typedef long long ll;
using namespace std;
int dp[30005][2200],arr[30005]= {};
int dfs(int i,int d)
{
    if(i>=30001)
    {
        return 0;
    }
    if(dp[i][d]!=-1)
        return dp[i][d];
    int ret=0;
    if(d==1&&i+d<=30000)
    {
        ret=max(ret,dfs(i+d,d)+arr[i]);

    }
    else
    {
        if(i+d<=30000)
        {
            ret=max(ret,dfs(i+d,d)+arr[i]);
        }
        if(i+d+1<=30000)
        {
            ret=max(ret,dfs(i+d+1,d+1)+arr[i]);
        }
        if(d-1>0&&i+d-1<=30000)
        {
            ret=max(ret,dfs(i+d-1,d-1)+arr[i]);
        }
    }
    return dp[i][d]=ret;
}
int main()
{
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    //freopen("read.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int n,d,x;
    cin >> n>>d;
    for(int i =0; i<n; i++)
    {
        cin >> x;
        arr[x]++;
    }
    if(d>=2000)
    {
        queue<pair<int,pair<int,int> > > q;
        q.push({d,{d,arr[d]}});
        int y,z,maxx=0;
        while(q.size())
        {
            x=q.front().first,y=q.front().second.first,z=q.front().second.second;
            q.pop();
            if(x>=30000)
            {
                maxx=max(z,maxx);
            }
            if(y==1&&x+y<=30000)
            {
                q.push({x+y,{y,z+arr[x+y]}});
            }
            else
            {

                if(x+y<=30000)
                {
                    q.push({x+y,{y,z+arr[x+y]}});
                }
                if(x+y+1<=30000)
                {
                    q.push({x+y+1,{y+1,z+arr[x+y+1]}});
                }
                if(y-1>0&&x+y-1<=30000)
                {
                    q.push({x+y-1,{y-1,z+arr[x+y-1]}});
                }
            }
        }
        cout << maxx << endl;
    }
    else
    {
        memset(dp,-1,sizeof dp);
        cout << dfs(d,d)<< endl;
    }
    return 0;
}


#include <vector>
#include <stdio.h>
#include <string.h>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
typedef long long ll;
using namespace std;
ll dp[30005][3000],arr[30005]= {};
ll dfs(ll i,ll d)
{
    if(i>=30001)
    {
        return 0;
    }
    if(dp[i][d]!=-1)
        return dp[i][d];
    ll ret=0;
    if(d==1&&i+d<=30000)
    {
        ret=max(ret,dfs(i+d,d)+arr[i]);

    }
    else
    {
        if(i+d<=30000)
        {
            ret=max(ret,dfs(i+d,d)+arr[i]);
        }
        if(i+d+1<=30000)
        {
            ret=max(ret,dfs(i+d+1,d+1)+arr[i]);
        }
        if(d-1>0&&i+d-1<=30000)
        {
            ret=max(ret,dfs(i+d-1,d-1)+arr[i]);
        }
    }
    return dp[i][d]=ret;
}
int main()
{
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    //freopen("read.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    ll n,d,x;
    cin >> n>>d;
    for(int i =0; i<n; i++)
    {
        cin >> x;
        arr[x]++;
    }
    if(d>=2000)
    {
        queue<pair<ll,pair<ll,ll> > > q;
        q.push({d,{d,arr[d]}});
        ll y,z,maxx=0;
        while(q.size())
        {
            x=q.front().first,y=q.front().second.first,z=q.front().second.second;
            q.pop();
            if(x>=30000)
            {
                maxx=max(z,maxx);
            }
            if(y==1&&x+y<=30000)
            {
                q.push({x+y,{y,z+arr[x+y]}});
            }
            else
            {

                if(x+y<=30000)
                {
                    q.push({x+y,{y,z+arr[x+y]}});
                }
                if(x+y+1<=30000)
                {
                    q.push({x+y+1,{y+1,z+arr[x+y+1]}});
                }
                if(y-1>0&&x+y-1<=30000)
                {
                    q.push({x+y-1,{y-1,z+arr[x+y-1]}});
                }
            }
        }
        cout << maxx << endl;
    }
    else
    {
        memset(dp,-1,sizeof dp);
        cout << dfs(d,d)<< endl;
    }
    return 0;
}


#include <vector>
#include <stdio.h>
#include <string.h>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
typedef long long ll;
using namespace std;
int dp[30005][2200],arr[30005]= {};
int dfs(int i,int d)
{
    if(i>=30001)
    {
        return 0;
    }
    if(dp[i][d]!=-1)
        return dp[i][d];
    int ret=0;
    if(d==1&&i+d<=30001)
    {
        ret=max(ret,dfs(i+d,d)+arr[i]);

    }
    else
    {
        if(i+d<=30001)
        {
            ret=max(ret,dfs(i+d,d)+arr[i]);
        }
        if(i+d+1<=30001)
        {
            ret=max(ret,dfs(i+d+1,d+1)+arr[i]);
        }
        if(d-1>0&&i+d-1<=30001)
        {
            ret=max(ret,dfs(i+d-1,d-1)+arr[i]);
        }
    }
    return dp[i][d]=ret;
}
int main()
{
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    //freopen("read.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int n,d,x;
    cin >> n>>d;
    for(int i =0; i<n; i++)
    {
        cin >> x;
        arr[x]++;
    }
    if(d>=2000)
    {
        queue<pair<int,pair<int,int> > > q;
        q.push({d,{d,arr[d]}});
        int y,z,maxx=0;
        while(q.size())
        {
            x=q.front().first,y=q.front().second.first,z=q.front().second.second;
            q.pop();
            if(x>=30001)
            {
                maxx=max(z,maxx);
            }
            if(y==1&&x+y<=30001)
            {
                q.push({x+y,{y,z+arr[x+y]}});
            }
            else
            {

                if(x+y<=30001)
                {
                    q.push({x+y,{y,z+arr[x+y]}});
                }
                if(x+y+1<=30001)
                {
                    q.push({x+y+1,{y+1,z+arr[x+y+1]}});
                }
                if(y-1>0&&x+y-1<=30001)
                {
                    q.push({x+y-1,{y-1,z+arr[x+y-1]}});
                }
            }
        }
        cout << maxx << endl;
    }
    else
    {
        memset(dp,-1,sizeof dp);
        cout << dfs(d,d)<< endl;
    }
    return 0;
}


#include <vector>
#include <stdio.h>
#include <string.h>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
typedef long long ll;
using namespace std;
ll gem[300005]= {};
ll vis[300005]= {};
int main()
{
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    //freopen("read.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    ll n,m,x;
    cin >> n>>m;
    for(int i =0; i<n; i++)
    {
        cin >> x;
        gem[x]++;
    }
    priority_queue< pair<ll,pair<ll,ll> > > p;
    ll len=m,maxx=0;
    p.push({m*-1,{0,len}});
    while(p.size())
    {
        m=p.top().first*-1,x=p.top().second.first,len=p.top().second.second;
        p.pop();
        if(!vis[m])
        {
            vis[m]=1;
            x+=gem[m];
            maxx=max(maxx,x);
            //cout << m<< " " << x<< " "<< len<< " " << endl;
            //cin >> n;
            if(len==1&&m+len<=30001&&!vis[m+len])
            {
                p.push({(m+len)*-1,{x,len}});
                continue;
            }
            if(m+len<=30001&&!vis[m+len])
            {
                p.push({(m+len)*-1,{x,len}});
            }
            if(m+len+1<=30001&&!vis[m+len+1])
            {
                p.push({(m+len+1)*-1,{x,(len+1)}});
            }
            if(len-1>0&&m+len-1<=30001&&!vis[m+len-1])
            {
                p.push({(m+len-1)*-1,{x,(len-1)}});
            }
        }
    }
    cout << maxx << endl;
    return 0;
}


#include <vector>
#include <stdio.h>
#include <string.h>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
typedef long long ll;
using namespace std;
short int dp[30005][2200],arr[30005]= {};
short int dfs(short int i,short int d)
{
    if(i>=30001)
    {
        return 0;
    }
    if(dp[i][d]!=-1)
        return dp[i][d];
    short int ret=0;
    if(d==1&&i+d<=30001)
    {
        ret=max(ret,(short int )(dfs(i+d,d)+arr[i]));

    }
    else
    {
        ret=max(ret,(short int )(dfs(i+d,d)+arr[i]));
        ret=max(ret,(short int )(dfs(i+d+1,d+1)+arr[i]));
        if(d-1>0)
        {
            ret=max(ret,(short int )(dfs(i+d-1,d-1)+arr[i]));
        }
    }
    return dp[i][d]=ret;
}
int main()
{
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    //freopen("read.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    short int n,d,x;
    cin >> n>>d;
    for(short int i =0; i<n; i++)
    {
        cin >> x;
        arr[x]++;
    }
    if(d>=2000)
    {
        queue<pair<short int,pair<short int,short int> > > q;
        q.push({d,{d,0}});
        short int y,z,maxx=0;
        while(q.size())
        {
            x=q.front().first,y=q.front().second.first,z=q.front().second.second;
            q.pop();
            //cout << x << " "<< y << " " << z<< endl;
            //cin >> n;
            if(x>=30002)
            {
                maxx=max(z,maxx);
                continue;
            }
            if(y==1)
            {
                q.push({x+y,{y,z+arr[x]}});
            }
            else
            {

                q.push({x+y,{y,z+arr[x]}});
                q.push({x+y+1,{y+1,z+arr[x]}});
                if(y-1>0)
                {
                    q.push({x+y-1,{y-1,z+arr[x]}});
                }
            }
        }
        cout << maxx << endl;
    }
    else
    {
        memset(dp,-1,sizeof dp);
        cout << dfs(d,d)<< endl;
    }
    return 0;
}


#include <vector>
#include <stdio.h>
#include <string.h>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
typedef long long ll;
using namespace std;
short int dp[30005][2200],arr[30005]= {};
short int dfs(short int i,short int d)
{
    if(i>=30001)
    {
        return 0;
    }
    if(dp[i][d]!=-1)
        return dp[i][d];
    int ret=0;
    if(d==1&&i+d<=30001)
    {
        ret=max(ret,(dfs(i+d,d)+arr[i]));

    }
    else
    {
        ret=max(ret,(dfs(i+d,d)+arr[i]));
        ret=max(ret,(dfs(i+d+1,d+1)+arr[i]));
        if(d-1>0)
        {
            ret=max(ret,(dfs(i+d-1,d-1)+arr[i]));
        }
    }
    return dp[i][d]=ret;
}
int main()
{
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    //freopen("read.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int n,d,x;
    cin >> n>>d;
    for(short int i =0; i<n; i++)
    {
        cin >> x;
        arr[x]++;
    }
    if(d>=2000)
    {
        queue<pair<int,pair<int,int> > > q;
        q.push({d,{d,0}});
        int y,z,maxx=0;
        while(q.size())
        {
            x=q.front().first,y=q.front().second.first,z=q.front().second.second;
            q.pop();
            //cout << x << " "<< y << " " << z<< endl;
            //cin >> n;
            if(x>=30002)
            {
                maxx=max(z,maxx);
                continue;
            }
            if(y==1)
            {
                q.push({x+y,{y,z+arr[x]}});
            }
            else
            {

                q.push({x+y,{y,z+arr[x]}});
                q.push({x+y+1,{y+1,z+arr[x]}});
                if(y-1>0)
                {
                    q.push({x+y-1,{y-1,z+arr[x]}});
                }
            }
        }
        cout << maxx << endl;
    }
    else
    {
        memset(dp,-1,sizeof dp);
        cout << dfs(d,d)<< endl;
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <queue>
#include <algorithm>
#define x first
#define y second
#define now q.front()
using namespace std;
string s;
int i,j,m,n,o,p,a,b,pas[100][100],ok,t,k,maxi=0,mini=1000000000,c[30001];
int v[30001];
vector <int> in,d;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void dfs(int poz,int l,int cur)
{
    if(c[poz])
        return;
    c[poz]=1;
    maxi=max(maxi,cur);
    if(l>1&&poz+l-1<=30000)
        dfs(poz+l-1,l-1,cur+v[poz+l-1]);
    if(poz+l<=30000)
        dfs(poz+l,l,cur+v[poz+l]);
    if(poz+l+1<=30000)
        dfs(poz+l+1,l+1,cur+v[poz+l+1]);
}
int main()
{
     #ifndef ONLINE_JUDGE
ifstream cin(".in");
//ofstream cout(".out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);

    cin >> n >> m;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> a;
        v[ a ] ++;
    }
    dfs(0,m,0);
    cout<<maxi;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <queue>
#include <algorithm>
#define x first
#define y second
#define now q.front()
using namespace std;
string s;
int i,j,m,n,o,p,a,b,pas[100][100],ok,t,k,maxi=0,mini=1000000000,c[30001];
int v[30001],dp[30500];
vector <int> in,d;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void dfs(int poz,int l)
{
    if(poz>30000)
        return;
    if(dp[poz] + v[poz + l] > dp[poz + l])
    {
        dp[poz + l] = dp[poz] + v[poz + l] ;
        dfs(poz + l, l);
    }
    if(l > 1)
        if(dp[poz] + v[poz + l - 1] > dp[poz + l - 1])
        {
            dp[poz + l - 1] = dp[poz] + v[poz + l - 1] ;
            dfs(poz + l - 1, l - 1);
        }
    if(dp[poz] + v[poz + l + 1] > dp[poz + l + 1])
    {
        dp[poz + l + 1] = dp[poz] + v[poz + l + 1] ;
        dfs(poz + l + 1, l + 1);
    }
    maxi = max(maxi, dp[poz]);
}
int main()
{
     #ifndef ONLINE_JUDGE
ifstream cin(".in");
//ofstream cout(".out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);

    cin >> n >> m;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> a;
        v[ a ] ++;
    }
    for(i = 1; i <= 30000; i++)
        dp[i] = -1;
    dp[m] = v[m];
    dfs(m,m);
    cout<<maxi;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <cstdlib>
#include <fstream>
#include <queue>
#include <cstdio>
#include <algorithm>
#define x first
#define y second
#define now q.front()
using namespace std;
string s;
int i,j,m,n,o,p,a,b,pas[100][100],ok,t,k,maxi=0,mini=1000000000,c[30001];
int v[30001],dp[30500][1000],ul[300500];
vector <int> in,d;
int dfs(int poz,int l)
{
    if(poz > 30000 || l == 0)
        return 0;
    if(dp[poz][l - m + 300] != -1)
        return dp[poz][l - m + 300];
    return dp[poz][l - m + 300] = max(dfs(poz + l -1, l - 1), max(dfs(poz + l, l), dfs(poz + l +1, l + 1))) + v[poz];
}
int main()
{
     #ifndef ONLINE_JUDGE
ifstream cin(".in");
//ofstream cout(".out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);

    cin >> n >> m;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> a;
        v[ a ] ++;
    }
    for( i = 0; i <= 30000; i++)
        for(j = 0; j<=1000;j++)
            dp[i][j] =- 1;

    cout<<dfs(m, m);
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <queue>
#include <algorithm>
#define x first
#define y second
#define now q.front()
using namespace std;
string s;
int i,j,m,n,o,p,a,b,pas[100][100],ok,t,k,maxi=0,mini=1000000000,c[30001];
int v[30001],dp[30500],ul[300500];
vector <int> in,d;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void dfs(int poz,int l)
{
    if(poz>30000)
        return;
    if(l > 1)
    if(dp[poz] + v[poz + l - 1] > dp[poz + l - 1] || ul[poz + l -1] < l - 1)
        {
            dp[poz + l - 1] = max(dp[poz + l - 1],dp[poz] + v[poz + l - 1]);
            ul[poz + l -1] = l - 1;
            dfs(poz + l - 1, l - 1);

        }
    if(dp[poz] + v[poz + l] > dp[poz + l] || ul[poz + l -1] < l)
    {
        dp[poz + l] =max(dp[poz + l], dp[poz] + v[poz + l] );
        ul[poz + l -1] = l;
        dfs(poz + l, l);

    }

    if(dp[poz] + v[poz + l + 1] > dp[poz + l + 1] || ul[poz + l -1] < l + 1)
    {
        dp[poz + l + 1] = max(dp[poz + l + 1], dp[poz] + v[poz + l + 1] );
        ul[poz + l -1] = l + 1;
        dfs(poz + l + 1, l + 1);

    }
    maxi = max(maxi, dp[poz]);
}
int main()
{
     #ifndef ONLINE_JUDGE
ifstream cin(".in");
//ofstream cout(".out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);

    cin >> n >> m;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> a;
        v[ a ] ++;
    }
    for(i = 1; i <= 30000; i++)
        dp[i] = -1;
    dp[m] = v[m];
    dfs(m,m);
    cout<<maxi;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <queue>
#include <algorithm>
#define x first
#define y second
#define now q.front()
using namespace std;
string s;
int i,j,m,n,o,p,a,b,pas[100][100],ok,t,k,maxi=0,mini=1000000000,c[30001];
int v[30001];
vector <int> in,d;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void dfs(int poz,int l,int cur)
{
    if(c[poz])
        return;
    c[poz]=1;
    maxi=max(maxi,cur);
    if(l>1&&poz+l-1<=30000)
        dfs(poz+l-1,l-1,cur+v[poz+l-1]);
    if(poz+l<=30000)
        dfs(poz+l,l,cur+v[poz+l]);
    if(poz+l+1<=30000)
        dfs(poz+l+1,l+1,cur+v[poz+l+1]);
}
int main()
{
     #ifndef ONLINE_JUDGE
ifstream cin(".in");
//ofstream cout(".out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);

    cin >> n >> m;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> a;
        v[ a ] ++;
    }
    dfs(10,10,v[10]);
    cout<<maxi;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <queue>
#include <algorithm>
#define x first
#define y second
#define now q.front()
using namespace std;
string s;
int i,j,m,n,o,p,a,b,pas[100][100],ok,t,k,maxi=0,mini=1000000000,c[30001];
int v[30001];
vector <int> in,d;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void dfs(int poz,int l,int cur)
{
    if(c[poz])
        return;
    c[poz]=1;
    maxi=max(maxi,cur);
    if(l>1&&poz+l-1<=30000)
        dfs(poz+l-1,l-1,cur+v[poz+l-1]);
    if(poz+l<=30000)
        dfs(poz+l,l,cur+v[poz+l]);
    if(poz+l+1<=30000)
        dfs(poz+l+1,l+1,cur+v[poz+l+1]);
}
int main()
{
     #ifndef ONLINE_JUDGE
ifstream cin(".in");
//ofstream cout(".out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);

    cin >> n >> m;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> a;
        v[ a ] ++;
    }
    dfs(m,m,v[m]);
    cout<<maxi;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <queue>
#include <algorithm>
#define x first
#define y second
#define now q.front()
using namespace std;
string s;
int i,j,m,n,o,p,a,b,pas[100][100],ok,t,k,maxi=0,mini=1000000000,c[30001];
int v[30001],dp[30500],ul[300500];
vector <int> in,d;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void dfs(int poz,int l)
{
    if(poz>b)
        return;
    if(l > 1)
    if(dp[poz] + v[poz + l - 1] > dp[poz + l - 1] || ul[poz + l -1] < l - 1)
        {
            dp[poz + l - 1] = max(dp[poz + l - 1],dp[poz] + v[poz + l - 1]);
            ul[poz + l -1] = l - 1;
            dfs(poz + l - 1, l - 1);

        }
    if(dp[poz] + v[poz + l] > dp[poz + l] || ul[poz + l -1] < l)
    {
        dp[poz + l] =max(dp[poz + l], dp[poz] + v[poz + l] );
        ul[poz + l -1] = l;
        dfs(poz + l, l);

    }

    if(dp[poz] + v[poz + l + 1] > dp[poz + l + 1] || ul[poz + l -1] < l + 1)
    {
        dp[poz + l + 1] = max(dp[poz + l + 1], dp[poz] + v[poz + l + 1] );
        ul[poz + l -1] = l + 1;
        dfs(poz + l + 1, l + 1);

    }
    maxi = max(maxi, dp[poz]);
}
int main()
{
     #ifndef ONLINE_JUDGE
ifstream cin(".in");
//ofstream cout(".out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);

    cin >> n >> m;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> a;
        v[ a ] ++;
        b = max(b, a);
    }
    for(i = 1; i <= 30000; i++)
        dp[i] = -1;
    dp[m] = v[m];
    dfs(m,m);
    cout<<maxi;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <queue>
#include <algorithm>
#define x first
#define y second
#define now q.front()
using namespace std;
string s;
int i,j,m,n,o,p,a,b,pas[100][100],ok,t,k,maxi=0,mini=1000000000,c[30001];
int v[30001];
vector <int> in,d;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void dfs(int poz,int l,int cur)
{
    if(c[poz])
        return;
    c[poz]=1;
    maxi=max(maxi,cur);
    if(l>1&&poz+l-1<=30000)
        dfs(poz+l-1,l-1,cur+v[poz+l-1]);
    if(poz+l<=30000)
        dfs(poz+l,l,cur+v[poz+l]);
    if(poz+l+1<=30000)
        dfs(poz+l+1,l+1,cur+v[poz+l+1]);
}
int main()
{
     #ifndef ONLINE_JUDGE
ifstream cin(".in");
//ofstream cout(".out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);

    cin >> n >> m;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> a;
        v[ a ] ++;
    }
    dfs(m,m,v[m]);
    m--;
    dfs(m,m,v[m]);
    m++;
    dfs(m,m,v[m]);
    cout<<maxi;
    return 0;
}


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i])
			return false;
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i])
			return false;
	}
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		if(n == 5321)
			cout << l << " " << r << endl;
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i]) {
			if(n == 5321)
				cout << i << " " << ct[i] << endl;
			return false;
		}
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		if(n == 5321)
			cout << l << " " << r << endl;
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
		if(n == 5321)
			cout << mid << endl;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(n == 5321)
			cout << ct[i] << " ";
		if(i * k < ct[i])
			return false;
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	if(n == 5321) {
		cout << check(13631074) << endl;
		return 0;
	}
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[(x - cnt) / a[i]]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i])
			return false;
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[x / a[i]]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i])
			return false;
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[max(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i])
			return false;
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos <= m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i])
			return false;
	}
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
		if(val > 1)
			return false;
		if(val == 1 && max((int)0, cnt - p) + a[i] > x)
			return false;
	}
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	if(n == 5321)
		cout << mx << endl;
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i]) {
			if(n == 5321)
				cout << i << " " << ct[i] << endl;
			return false;
		}
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		if(n == 5321)
			cout << l << " " << r << endl;
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i]) {
			if(n == 5321)
				cout << i << " " << ct[i] << endl;
			return false;
		}
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		cout << l << " " << r << endl;
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
		if(n == 5321)
			cout << mid << endl;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[(x - cnt) / a[i]]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i])
			return false;
	}
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i]) {
			if(n == 5321)
				cout << i << " " << ct[i] << endl;
			return false;
		}
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	if(n == 5321) {
		cout << check(13631074) << endl;
		return 0;
	}
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


///                             In The Name Of Allah
//                             	Mohammad Hosseini
#include <bits/stdc++.h>
#define	ss second
#define ff first
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define se(n) cout << setprecision(n) << fixed
#define pb push_back
#define int long long
#define ld long double
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 2e5 + 100, OO = 1e9 + 7, T = 22, M = 1e9 + 7, P = 6151, SQ = 1300, lg = 22;
typedef pair <int, int> pii;
int h[N], a[N], f[N], n, m, k, p, ct[N], mx = 0;

bool check(int x) {
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		cnt += (f[i] - x + p - 1) / p;
	}
	for(int i = 0; i <= m + 1; i++)
		ct[i] = 0;
	if(cnt > k * (m + 1))
		return false;
	for(int i = 1; i <= n; i++) {
		if(x >= f[i])
			continue;
		int val = (f[i] - x + p - 1) / p;
		int pos = 0, cnt = h[i];
		while(val && pos < m) {
			if(cnt >= p) {
				val--;
				cnt -= p;
				continue;
			}
			int g = (p - cnt + a[i] - 1) / a[i];
			if(g + pos > m) {
				cnt += (m - pos) * a[i];
				if(val > 1 || max((int)0, cnt - p) + a[i] > x)
					return false;
				cnt -= (m - pos) * a[i];
				ct[min(x / a[i], m + 1)]++;
				break;
			}
			cnt += g * a[i];
			cnt -= p;
			val--;
			pos += g;
		}
	}
	for(int i = 1; i <= m + 1; i++) {
		ct[i] += ct[i - 1];
		if(i * k < ct[i])
			return false;
	}
	return true;
}

int32_t main() {
	use_fast;
	cin >> n >> m >> k >> p;
	for(int i = 1; i <= n; i++)
		cin >> h[i] >> a[i], f[i] = h[i] + a[i] * m, mx = max(mx, f[i]);
	m--;
	int l = 0, r = mx;
	while(l < r) {
		int mid = (l + r) >> 1;
		if(check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << r << endl;
	return 0;
}
/*
be carefull :
1- if not solve after 20 min, read again twice
2- after submit read the code again
3- fun with contest
4- uploaded by ubuntu 20.04
5- ...
*/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#define N 101000
#define MP make_pair
#define PLL pair<ll, ll>
typedef long long ll;
template<typename T> inline void read(T &x) {
	x = 0; char c = getchar();
	while (!isdigit(c)) c = getchar();
	while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); }
}
using namespace std;
const ll inf = 1e16;
inline void MIN(ll &a, ll b) {
	if (b < a)	a = b;
}
inline void MAX(ll &a, ll b) {
	if (b > a)	a = b;
}
int n, m, k, p;
int h[N], a[N];
ll nw[N];
priority_queue<PLL> q;
inline bool che(ll H) {
	while (!q.empty())	q.pop();
	for (int i = 1; i <= n; ++i)	nw[i] = H;
	for (int i = 1; i <= n; ++i)
		if (H - 1ll * m * a[i] < h[i])	q.push(MP(-(H/a[i]),i));
	for (int i = 1; i <= m; ++i) {
		for (int j = 1; j <= k; ++j) {
			if (q.empty())	return true;
			PLL pr = q.top(); q.pop();
			if (-pr.first < i)	return false;
			int id = pr.second;
			nw[id] += p;
			if (nw[id] - 1ll * m * a[id] < h[id])	q.push(MP(-(nw[id]/a[id]),id));
		}
	}
	return q.empty();
}
int main() {
	read(n), read(m), read(k), read(p);
	ll l = 0, r = 0, res = 0;
	for (int i = 1; i <= n; ++i)
		read(h[i]), read(a[i]), MAX(r, h[i] + 1ll * a[i] * m), MAX(l, a[i]);
	while (l <= r) {
		ll mid = (l + r) >> 1;
		if (che(mid))	res = mid, r = mid - 1;
		else	l = mid + 1;
	}
	printf("%lld\n", res);
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
//#pragma GCC optimize("Os")
using namespace std;
#define sync()      ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F           first
#define S           second
#define mp          make_pair
#define ers         erase
#define ins         insert
#define db          pop_back
#define pb          push_back
#define df          pop_front
#define pf          push_front
#define sqr(x)      (x)*(x)
#define Blz(x)      __builtin_clz(x)
#define Brz(x)      __builtin_ctz(x)
#define Bones(x)    __builtin_popcount(x)
#define all(x)      x.begin(),x.end()
#define kill(x)     return cout<<x,0
#define dbgp(x)     cerr<< #x << " = " << x.F << ", " << x.S << endl
#define dbg(x)      cerr<< #x << " = " << x << endl
#define ddbg(i,x)   cerr<< #i << " = " << i << " / "; dbg(x[i])
#define tdbg(i,j,x) cerr<< #i << " = " << i << " / "; ddbg(j,x[i])
typedef long long                                 ll;
typedef long double                               ld;
typedef unsigned short int                        usi;
typedef pair<long long,bool>                      plb;
typedef pair<long long,long long>                 pll;
typedef string                                    str;
typedef priority_queue<ll>                        maxheap;
typedef priority_queue<ll,vector<ll>,greater<ll>> minheap;
const ll maxn=1e5+10, inf=4e18, mod=1e9+7; const ld pi=3.14159265359, eps=1e-9;
ll n,m,k,p,h[maxn],h2[maxn],g[maxn],zr;
pll v;
priority_queue<pll,vector<pll>,greater<pll>> bs;
bool check(ll d){
    while(bs.size()) bs.pop();
    for(int i=0;i<n;i++){
        h2[i]=d;
        if(d-m*g[i]<0) bs.push(mp(d/g[i],i));
    }
    zr=0;
    while(zr<=m*k){
        if(bs.empty()) break;
        v=bs.top(); bs.pop();
        //dbgp(v);
        if(v.F-1<zr/k) return 0;
        h2[v.S]+=p;
        if(h2[v.S]-m*g[v.S]<0) bs.push(mp(h2[v.S]/g[v.S],v.S));
        zr++;
    }
    for(int i=0;i<n;i++){
        if(h2[i]-m*g[i]<h[i]) zr+=ceil((ld)(h[i]-(h2[i]-m*g[i]))/p);
        if(zr>m*k) return 0;
    }
    return 1;
}
int main(){
    sync();
    cin>>n>>m>>k>>p;
    for(int i=0;i<n;i++){ cin>>h[i]>>g[i]; }
    //dbg(check(17)); dbg(check(26)); dbg(check(26));
    ll l=0,r=inf,mid;
    while(r-l>1){
        mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }
    //dbg(check(26));
    cout<<r;
    return 0;
}
/**
 (                            )   (   )
 )\ )             (      )  ( /(  () /(
(()/(  (  (    (  )\  ( /(  )\()) )\ ())
 /(_))_)  )\   )\((_) )(_))(_)\) ((_)(_)
(_)) __| ((_) ((_)| |((_)_)| |(_)| |_| |
  | (_ |/ _ \/ _ \| |/ _` || / / |  _  |
   \___|\___/\___/|_|\__,_||_\_\ |_| |_|
**/


#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
//#pragma GCC optimize("Os")
using namespace std;
#define sync()      ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F           first
#define S           second
#define mp          make_pair
#define ers         erase
#define ins         insert
#define db          pop_back
#define pb          push_back
#define df          pop_front
#define pf          push_front
#define sqr(x)      (x)*(x)
#define Blz(x)      __builtin_clz(x)
#define Brz(x)      __builtin_ctz(x)
#define Bones(x)    __builtin_popcount(x)
#define all(x)      x.begin(),x.end()
#define kill(x)     return cout<<x,0
#define dbgp(x)     cerr<< #x << " = " << x.F << ", " << x.S << endl
#define dbg(x)      cerr<< #x << " = " << x << endl
#define ddbg(i,x)   cerr<< #i << " = " << i << " / "; dbg(x[i])
#define tdbg(i,j,x) cerr<< #i << " = " << i << " / "; ddbg(j,x[i])
typedef long long                                 ll;
typedef long double                               ld;
typedef unsigned short int                        usi;
typedef pair<long long,bool>                      plb;
typedef pair<long long,long long>                 pll;
typedef string                                    str;
typedef priority_queue<ll>                        maxheap;
typedef priority_queue<ll,vector<ll>,greater<ll>> minheap;
const ll maxn=1e5+10, inf=4e18, mod=1e9+7; const ld pi=3.14159265359, eps=1e-9;
ll n,m,k,p,h[maxn],h2[maxn],g[maxn],zr;
pll v;
priority_queue<pll,vector<pll>,greater<pll>> bs;
bool check(ll d){
    while(bs.size()) bs.pop();
    for(int i=0;i<n;i++){
        h2[i]=d;
        if(d-m*g[i]<0) bs.push(mp(d/g[i],i));
    }
    zr=0;
    while(zr<=m*k){
        if(bs.empty()) break;
        v=bs.top(); bs.pop();
        //dbgp(v);
        if(v.F-1<zr/k) return 0;
        h2[v.S]+=p;
        if(h2[v.S]-m*g[v.S]<0) bs.push(mp(h2[v.S]/g[v.S],v.S));
        zr++;
    }
    for(int i=0;i<n;i++){
        if(h2[i]-m*g[i]<h[i]) zr+=ceil((ld)(h[i]-(h2[i]-m*g[i]))/p);
        if(zr>m*k) return 0;
    }
    return 1;
}
int main(){
    sync();
    cin>>n>>m>>k>>p;
    for(int i=0;i<n;i++){ cin>>h[i]>>g[i]; }
    //dbg(check(17)); dbg(check(26)); dbg(check(26));
    ll l=0,r=inf,mid;
    while(r-l>1){
        mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }
    //dbg(check(26));
    if(check(l)) r=l;
    cout<<r;
    return 0;
}
/**
 (                            )   (   )
 )\ )             (      )  ( /(  () /(
(()/(  (  (    (  )\  ( /(  )\()) )\ ())
 /(_))_)  )\   )\((_) )(_))(_)\) ((_)(_)
(_)) __| ((_) ((_)| |((_)_)| |(_)| |_| |
  | (_ |/ _ \/ _ \| |/ _` || / / |  _  |
   \___|\___/\___/|_|\__,_||_\_\ |_| |_|
**/


#include <bits/stdc++.h>
using namespace std;
#define sync()      ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F           first
#define S           second
#define mp          make_pair
#define ers         erase
#define ins         insert
#define db          pop_back
#define pb          push_back
#define df          pop_front
#define pf          push_front
#define sqr(x)      (x)*(x)
#define SZ(x)       (ll)x.size()
#define Blz(x)      __builtin_clz(x)
#define Brz(x)      __builtin_ctz(x)
#define Bones(x)    __builtin_popcount(x)
#define all(x)      x.begin(),x.end()
#define kill(x)     return cout<<x,0
#define dbgp(x)     cerr<< #x << " = " << x.F << ", " << x.S << endl
#define dbg(x)      cerr<< #x << " = " << x << endl
#define ddbg(i,x)   cerr<< #i << " = " << i << " / "; dbg(x[i])
#define tdbg(i,j,x) cerr<< #i << " = " << i << " / "; ddbg(j,x[i])
typedef long long                                 ll;
typedef long double                               ld;
typedef unsigned short int                        usi;
typedef pair<long long,bool>                      plb;
typedef pair<long long,long long>                 pll;
typedef string                                    str;
typedef priority_queue<ll>                        maxheap;
typedef priority_queue<ll,vector<ll>,greater<ll>> minheap;
const ll maxn=1e5+10, inf=4e18, mod=1e9+7; const ld pi=3.14159265359, eps=1e-9;
ll n,m,k,p,b[maxn],g[maxn],t;
bool check(ll h){
    t=0;
    for(int i=0;i<n;i++){ t+=ceil((ld)max((b[i]+g[i]*m)-h,0ll)/p); }
    return (t<=k*m);
}
int main(){
    sync();
    cin>>n>>m>>k>>p;
    for(int i=0;i<n;i++){ cin>>b[i]>>g[i]; }
    ll l=*max_element(g,g+n),r=inf,mid;
    while(r-l>1){
        mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }
    if(check(l)) r=l;
    cout<<r;
    return 0;
}
/**
 (                            )   (   )
 )\ )             (      )  ( /(  () /(
(()/(  (  (    (  )\  ( /(  )\()) )\ ())
 /(_))_)  )\   )\((_) )(_))(_)\) ((_)(_)
(_)) __| ((_) ((_)| |((_)_)| |(_)| |_| |
  | (_ |/ _ \/ _ \| |/ _` || / / |  _  |
   \___|\___/\___/|_|\__,_||_\_\ |_| |_|
**/


#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
//#pragma GCC optimize("Os")
using namespace std;
#define sync()      ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F           first
#define S           second
#define mp          make_pair
#define ers         erase
#define ins         insert
#define db          pop_back
#define pb          push_back
#define df          pop_front
#define pf          push_front
#define sqr(x)      (x)*(x)
#define Blz(x)      __builtin_clz(x)
#define Brz(x)      __builtin_ctz(x)
#define Bones(x)    __builtin_popcount(x)
#define all(x)      x.begin(),x.end()
#define kill(x)     return cout<<x,0
#define dbgp(x)     cerr<< #x << " = " << x.F << ", " << x.S << endl
#define dbg(x)      cerr<< #x << " = " << x << endl
#define ddbg(i,x)   cerr<< #i << " = " << i << " / "; dbg(x[i])
#define tdbg(i,j,x) cerr<< #i << " = " << i << " / "; ddbg(j,x[i])
typedef long long                                 ll;
typedef long double                               ld;
typedef unsigned short int                        usi;
typedef pair<long long,bool>                      plb;
typedef pair<long long,long long>                 pll;
typedef string                                    str;
typedef priority_queue<ll>                        maxheap;
typedef priority_queue<ll,vector<ll>,greater<ll>> minheap;
const ll maxn=1e3+10, inf=4e18, mod=1e9+7; const ld pi=3.14159265359, eps=1e-9;
ll n,m,k,p,h[maxn],h2[maxn],g[maxn],zr;
pll v;
priority_queue<pll,vector<pll>,greater<pll>> bs;
bool check(ll d){
    while(bs.size()) bs.pop();
    for(int i=0;i<n;i++){
        h2[i]=d;
        if(d-m*g[i]<0) bs.push(mp(d/g[i],i));
    }
    zr=0;
    while(zr<=m*k){
        if(bs.empty()) break;
        v=bs.top(); bs.pop();
        //dbgp(v);
        if(v.F-1<zr/k) return 0;
        h2[v.S]+=p;
        if(h2[v.S]-m*g[v.S]<0) bs.push(mp(h2[v.S]/g[v.S],v.S));
        zr++;
    }
    for(int i=0;i<n;i++){
        if(h2[i]-m*g[i]<h[i]) zr+=ceil((ld)(h[i]-(h2[i]-m*g[i]))/p);
        if(zr>m*k) return 0;
    }
    return 1;
}
int main(){
    sync();
    cin>>n>>m>>k>>p;
    for(int i=0;i<n;i++){ cin>>h[i]>>g[i]; }
    //dbg(check(17)); dbg(check(26)); dbg(check(26));
    ll l=0,r=inf,mid;
    while(r-l>1){
        mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }
    //dbg(check(26));
    cout<<r;
    return 0;
}
/**
 (                            )   (   )
 )\ )             (      )  ( /(  () /(
(()/(  (  (    (  )\  ( /(  )\()) )\ ())
 /(_))_)  )\   )\((_) )(_))(_)\) ((_)(_)
(_)) __| ((_) ((_)| |((_)_)| |(_)| |_| |
  | (_ |/ _ \/ _ \| |/ _` || / / |  _  |
   \___|\___/\___/|_|\__,_||_\_\ |_| |_|
**/


#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
//#pragma GCC optimize("Os")
using namespace std;
#define sync()      ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F           first
#define S           second
#define mp          make_pair
#define ers         erase
#define ins         insert
#define db          pop_back
#define pb          push_back
#define df          pop_front
#define pf          push_front
#define sqr(x)      (x)*(x)
#define Blz(x)      __builtin_clz(x)
#define Brz(x)      __builtin_ctz(x)
#define Bones(x)    __builtin_popcount(x)
#define all(x)      x.begin(),x.end()
#define kill(x)     return cout<<x,0
#define dbgp(x)     cerr<< #x << " = " << x.F << ", " << x.S << endl
#define dbg(x)      cerr<< #x << " = " << x << endl
#define ddbg(i,x)   cerr<< #i << " = " << i << " / "; dbg(x[i])
#define tdbg(i,j,x) cerr<< #i << " = " << i << " / "; ddbg(j,x[i])
typedef long long                                 ll;
typedef long double                               ld;
typedef unsigned short int                        usi;
typedef pair<long long,bool>                      plb;
typedef pair<long long,long long>                 pll;
typedef string                                    str;
typedef priority_queue<ll>                        maxheap;
typedef priority_queue<ll,vector<ll>,greater<ll>> minheap;
const ll maxn=1e5+10, inf=4e18, mod=1e9+7; const ld pi=3.14159265359, eps=1e-9;
ll n,m,k,p,h[maxn],h2[maxn],g[maxn],zr;
pll v;
priority_queue<pll,vector<pll>,greater<pll>> bs; //chan rooz davoom miare,index
bool check(ll d){
    while(bs.size()) bs.pop();
    for(int i=0;i<n;i++){
        h2[i]=d;
        if(d-m*g[i]<0) bs.push(mp(d/g[i]-1,i));
    }
    zr=0;
    while(zr<=m*k){
        if(bs.empty()) break;
        v=bs.top(); bs.pop();
        //dbgp(v);
        if(v.F<zr/k) return 0;
        h2[v.S]+=p;
        if(h2[v.S]-m*g[v.S]<0) bs.push(mp(h2[v.S]/g[v.S]-1,v.S));
        zr++;
    }
    for(int i=0;i<n;i++){
        if(h2[i]-m*g[i]<h[i]) zr+=(h[i]-(h2[i]-m*g[i])+p-1)/p;
    }
    return (zr<=m*k);
}
int main(){
    sync();
    cin>>n>>m>>k>>p;
    for(int i=0;i<n;i++){ cin>>h[i]>>g[i]; }
    //dbg(check(17)); dbg(check(26)); dbg(check(26));
    ll l=0,r=inf,mid;
    while(r-l>1){
        mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }
    //dbg(check(26));
    if(check(l)) r=l;
    cout<<r;
    return 0;
}
/**
 (                            )   (   )
 )\ )             (      )  ( /(  () /(
(()/(  (  (    (  )\  ( /(  )\()) )\ ())
 /(_))_)  )\   )\((_) )(_))(_)\) ((_)(_)
(_)) __| ((_) ((_)| |((_)_)| |(_)| |_| |
  | (_ |/ _ \/ _ \| |/ _` || / / |  _  |
   \___|\___/\___/|_|\__,_||_\_\ |_| |_|
**/


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
typedef long long ll;
#define MAX 100005
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
bool debug = 1;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
ll ln, lk, lm;

int h[MAX],p,a[MAX], cnt[MAX];
ll day(ll val, ll ai) {
    ll ans = val/ai; if (val%ai==0) ans++;
    return ans;
}
bool ck(ll x) {
    priority_queue<pair<int,int>, std::vector<pair<int,int>>, std::greater<pair<int,int>>> q;
    memset(cnt, 0, sizeof cnt);
    REP(i,n) if (x - (ll)a[i]*m < h[i]) {
        q.push({day(x,a[i]),i});
    }
    REQ(i,m) {
        REQ(j,k) {
            if (q.empty()) return 1;
            auto z = q.top(); q.pop();
            if (z.first < i) return 0;
            int id = z.second;
            cnt[id]++;
            if (x + (ll)p * cnt[id]- (ll)a[id] * m < h[id]) {
                q.push({day(x + (ll)p * cnt[id], a[id]), id});
            }
        }
    }
    return q.empty();
}
int main() {
    scanf("%d%d%d%d", &n, &m, &k, &p);
    REP(i,n) scanf("%d%d", h+i, a+i);
    ll l=0,r=1e15;
    while(l+1<r) {
        ll mid = (l+r)/2;
        if (ck(mid)) r=mid; else l=mid+1;
    }
    printf("%lld\n", ck(l) ? l : r);
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
typedef long long ll;
#define MAX 100005
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
bool debug = 1;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
ll ln, lk, lm;

int h[MAX],p,a[MAX], cnt[MAX];
ll day(ll val, ll ai) {
    ll ans = val/ai; if (val%ai==0) ans++;
    return ans;
}
bool ck(ll x) {
    priority_queue<pair<int,int>, std::vector<pair<int,int>>, std::greater<pair<int,int>>> q;
    memset(cnt, 0, sizeof cnt);
    REP(i,n) if (x - (ll)a[i]*m < h[i]) {
        q.push({day(x,a[i]),i});
    }
    REQ(i,m) {
        REQ(j,k) {
            if (q.empty()) return 1;
            auto z = q.top(); q.pop();
            if (z.first < i) return 0;
            int id = z.second;
            cnt[id]++;
            if (x + (ll)p * cnt[id]- (ll)a[id] * m < h[id]) {
                q.push({day(x + (ll)p * cnt[id], a[id]), id});
            }
        }
    }
    return q.empty();
}
int main() {
    scanf("%d%d%d%d", &n, &m, &k, &p);
    REP(i,n) scanf("%d%d", h+i, a+i);
    ll l=0,r=2e9;
    while(l+1<r) {
        ll mid = (l+r)/2;
        if (ck(mid)) r=mid; else l=mid+1;
    }
    printf("%lld\n", ck(l) ? l : r);
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
typedef long long ll;
#define MAX 100005
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
bool debug = 1;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
ll ln, lk, lm;

int h[MAX],p,a[MAX], cnt[MAX];
ll day(ll val, ll ai) {
    ll ans = val/ai;
    return ans;
}
bool ck(ll x) {
    priority_queue<pair<int,int>, std::vector<pair<int,int>>, std::greater<pair<int,int>>> q;
    memset(cnt, 0, sizeof cnt);
    REP(i,n) if (x - (ll)a[i]*m < h[i]) {
        q.push({day(x,a[i]),i});
    }
    REQ(i,m) {
        REQ(j,k) {
            if (q.empty()) return 1;
            auto z = q.top(); q.pop();
            if (z.first < i) return 0;
            int id = z.second;
            cnt[id]++;
            if (x + (ll)p * cnt[id]- (ll)a[id] * m < h[id]) {
                q.push({day(x + (ll)p * cnt[id], a[id]), id});
            }
        }
    }
    return q.empty();
}
int main() {
    scanf("%d%d%d%d", &n, &m, &k, &p);
    REP(i,n) scanf("%d%d", h+i, a+i);
    ll l=0,r=1e15;
    while(l+1<r) {
        ll mid = (l+r)/2;
        if (ck(mid)) r=mid; else l=mid+1;
    }
    printf("%lld\n", ck(l) ? l : r);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define Mp make_pair
#define pb push_back

using ll = long long;
using db = double;
using pii = pair<int, int>;
using vi = vector<int>;

const int N = 101000;
int n, m, k, p, h[N], a[N];
bool chk(int x) {
    priority_queue<pii, vector<pii>, greater<pii> >q; // <day, id> day: 第day + 1天会<0
    vi num(n + 1, 0);
    for(int i = 1; i <= n; i++)
        if(x - a[i] * m < h[i]) q.push(Mp(x / a[i], i));
    for(int i = 1; i <= m && q.size(); i++)
        for(int j = 1; j <= k && q.size(); j++) {
            auto u = q.top(); q.pop();
            if(u.fi < i) return 0;
            num[u.se]++;
            if(x + num[u.se] * p - a[u.se] * m < h[u.se])
                q.push(Mp((x + num[u.se] * p) / a[u.se], u.se));
        }
    return q.empty();
}
signed main(){
    scanf("%d %d %d %d", &n, &m, &k, &p); int l = 0, r = 0, mid;
    for(int i = 1; i <= n; i++) scanf("%d %d", &h[i], &a[i]), r = max(r, h[i] + a[i] * m);
    // for(int i = l; i <= r; i++) printf("%d\n", chk(i));
    while(l < r) chk(mid = l + r >> 1) ? r = mid : l = mid + 1;
    printf("%d\n", l);
    fprintf(stderr, "time=%.4f\n", (db)clock()/CLOCKS_PER_SEC);
    return 0;
    /* 取模直接除，爆零两行泪
     * 不开ll见祖宗
     */
}


#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define Mp make_pair
#define pb push_back

using ll = long long;
using db = double;
using pii = pair<int, int>;
using vi = vector<int>;

const int N = 101000;
int n, m, k; ll p, h[N], a[N];
bool chk(ll x) {
    priority_queue<pii, vector<pii>, greater<pii> >q; // <day, id> day: 第day + 1天会<0
    vi num(n + 1, 0);
    for(int i = 1; i <= n; i++)
        if(x - a[i] * m < h[i]) q.push(Mp(x / a[i], i));
    for(int i = 1; i <= m && q.size(); i++)
        for(int j = 1; j <= k && q.size(); j++) {
            auto u = q.top(); q.pop();
            if(u.fi < i) return 0;
            num[u.se]++;
            if(x + num[u.se] * p - a[u.se] * m < h[u.se])
                q.push(Mp((x + num[u.se] * p) / a[u.se], u.se));
        }
    return q.empty();
}
signed main(){
    scanf("%d %d %d %lld", &n, &m, &k, &p); ll l = 0, r = 0, mid;
    for(int i = 1; i <= n; i++) scanf("%lld %lld", &h[i], &a[i]), r = max(r, h[i] + a[i] * m);
    // for(int i = l; i <= r; i++) printf("%d\n", chk(i));
    while(l < r) chk(mid = l + r >> 1) ? r = mid : l = mid + 1;
    printf("%lld\n", l);
    fprintf(stderr, "time=%.4f\n", (db)clock()/CLOCKS_PER_SEC);
    return 0;
    /* 取模直接除，爆零两行泪
     * 不开ll见祖宗
     */
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,K,p,h[100010],a[100010];
class bam
{
    public:
        ll day;
        int id;
        bool operator <(const bam &x)const
        {
            return day>x.day;
        }
};
priority_queue<bam> q;
int f[100010];
bool check(ll x)
{
    while(!q.empty())q.pop();
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++)if(x-1ll*a[i]*m<h[i])q.push((bam){x/a[i],i});
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=K;j++)
        {
            if(q.empty())return 1;
            bam cur=q.top();q.pop();
            if(cur.day<i)return 0;
            if(x+1ll*p*(++f[cur.id])-1ll*m*a[cur.id]<h[cur.id])q.push((bam){(x+1ll*p*f[cur.id])/a[cur.id],cur.id});
        }
    }
    return q.empty();
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&K,&p);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&h[i],&a[i]);
    ll L=0,R=1e15,ans=R+1;
    while(L<=R)
    {
        ll mid=(L+R)>>1;
        if(check(mid))ans=mid,R=mid-1;
        else L=mid+1;
    }
    printf("%lld\n",ans);
    return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rsz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 200005;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace input {
    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class T> void re(T& x) { cin >> x; }
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest) {
        re(first); re(rest...);
    }

    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
    template<class T1, class T2> void pr(const pair<T1,T2>& x);
    template<class T, size_t SZ> void pr(const array<T,SZ>& x);
    template<class T> void pr(const vector<T>& x);
    template<class T> void pr(const set<T>& x);
    template<class T1, class T2> void pr(const map<T1,T2>& x);

    template<class T> void pr(const T& x) { cout << x; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        pr(first); pr(rest...);
    }

    template<class T1, class T2> void pr(const pair<T1,T2>& x) {
        pr("{",x.f,", ",x.s,"}");
    }
    template<class T> void prContain(const T& x) {
        pr("{");
        bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0; // const needed for vector<bool>
        pr("}");
    }
    template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
    template<class T> void pr(const vector<T>& x) { prContain(x); }
    template<class T> void pr(const set<T>& x) { prContain(x); }
    template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

    void ps() { pr("\n"); }
    template<class Arg> void ps(const Arg& first) {
        pr(first); ps(); // no space at end of line
    }
    template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
        pr(first," "); ps(rest...); // print w/ spaces
    }
}

using namespace output;

namespace io {
    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
    }
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
    a %= b; if (a == 0) return b == 1 ? 0 : -1;
    T x = invGeneral(b,a);
    return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modular {
    T val;
    explicit operator T() const { return val; }
    modular() { val = 0; }
    modular(const ll& v) {
        val = (-MOD <= v && v <= MOD) ? v : v % MOD;
        if (val < 0) val += MOD;
    }

    // friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
    friend void pr(const modular& a) { pr(a.val); }
    friend void re(modular& a) { ll x; re(x); a = modular(x); }

    friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
    friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }
    friend bool operator<(const modular& a, const modular& b) { return a.val < b.val; }

    modular operator-() const { return modular(-val); }
    modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
    modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
    modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
    friend modular pow(modular a, ll p) {
        modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend modular inv(const modular& a) {
        auto i = invGeneral(a.val,MOD); assert(i != -1);
        return i;
    } // equivalent to return exp(b,MOD-2) if MOD is prime
    modular& operator/=(const modular& m) { return (*this) *= inv(m); }

    friend modular operator+(modular a, const modular& b) { return a += b; }
    friend modular operator-(modular a, const modular& b) { return a -= b; }
    friend modular operator*(modular a, const modular& b) { return a *= b; }

    friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n,k,p,m;
vpi v;

ll cdiv(ll a, ll b) {
	if (a < 0) return 0;
	return (a+b-1)/b;
}

bool ok(ll mid) {
	ll co = 0;
	vi cnt(m+1);
	trav(t,v) {
		ll need = cdiv(t.f+(ll)t.s*m-mid,p);
		co += need; if (co > m*k || t.s > mid) return 0;
		F0R(i,need) {
			// lowest d such that (m-d)*a[i] <= mid
			// m-d <= (mid+p*i)/a[i]
			// d >= m-mid/a[i]
			cnt[max(0LL,m-(mid+(ll)i*p)/t.s)] ++; // need one at time >= x
		} // lowest d such that (m-d)*a[i] <= mid+p
	}
	F0Rd(i,m) {
		cnt[i] += cnt[i+1];
		if (k*(m-i) < cnt[i]) return 0;
	}
	return 1;
}

int main() {
    setIO(); re(n,m,k,p);
    v.rsz(n); re(v);
    ll lo = 0, hi = (m+1)*1e9;
    while (lo < hi) {
    	ll mid = (lo+hi)/2;
    	if (ok(mid)) hi = mid;
    	else lo = mid+1;
    }
    ps(lo);
}

/* stuff you should look for
    * int overflow, array bounds
    * special cases (n=1?), set tle
    * do smth instead of nothing and stay organized
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rsz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 200005;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace input {
    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class T> void re(T& x) { cin >> x; }
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest) {
        re(first); re(rest...);
    }

    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
    template<class T1, class T2> void pr(const pair<T1,T2>& x);
    template<class T, size_t SZ> void pr(const array<T,SZ>& x);
    template<class T> void pr(const vector<T>& x);
    template<class T> void pr(const set<T>& x);
    template<class T1, class T2> void pr(const map<T1,T2>& x);

    template<class T> void pr(const T& x) { cout << x; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        pr(first); pr(rest...);
    }

    template<class T1, class T2> void pr(const pair<T1,T2>& x) {
        pr("{",x.f,", ",x.s,"}");
    }
    template<class T> void prContain(const T& x) {
        pr("{");
        bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0; // const needed for vector<bool>
        pr("}");
    }
    template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
    template<class T> void pr(const vector<T>& x) { prContain(x); }
    template<class T> void pr(const set<T>& x) { prContain(x); }
    template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

    void ps() { pr("\n"); }
    template<class Arg> void ps(const Arg& first) {
        pr(first); ps(); // no space at end of line
    }
    template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
        pr(first," "); ps(rest...); // print w/ spaces
    }
}

using namespace output;

namespace io {
    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
    }
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
    a %= b; if (a == 0) return b == 1 ? 0 : -1;
    T x = invGeneral(b,a);
    return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modular {
    T val;
    explicit operator T() const { return val; }
    modular() { val = 0; }
    modular(const ll& v) {
        val = (-MOD <= v && v <= MOD) ? v : v % MOD;
        if (val < 0) val += MOD;
    }

    // friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
    friend void pr(const modular& a) { pr(a.val); }
    friend void re(modular& a) { ll x; re(x); a = modular(x); }

    friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
    friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }
    friend bool operator<(const modular& a, const modular& b) { return a.val < b.val; }

    modular operator-() const { return modular(-val); }
    modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
    modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
    modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
    friend modular pow(modular a, ll p) {
        modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend modular inv(const modular& a) {
        auto i = invGeneral(a.val,MOD); assert(i != -1);
        return i;
    } // equivalent to return exp(b,MOD-2) if MOD is prime
    modular& operator/=(const modular& m) { return (*this) *= inv(m); }

    friend modular operator+(modular a, const modular& b) { return a += b; }
    friend modular operator-(modular a, const modular& b) { return a -= b; }
    friend modular operator*(modular a, const modular& b) { return a *= b; }

    friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n,k,p,m;
vpi v;

ll cdiv(ll a, ll b) {
	if (a < 0) return 0;
	return (a+b-1)/b;
}

bool ok(ll mid) {
	ll co = 0;
	vi cnt(m+1);
	trav(t,v) {
		ll need = cdiv(t.f+(ll)t.s*m-mid,p);
		co += need; if (co > m*k || t.s > mid) return 0;
		F0R(i,need) {
			// lowest d such that (m-d)*a[i] <= mid
			// m-d <= (mid+p*i)/a[i]
			// d >= m-mid/a[i]
			cnt[max(0LL,m-(mid+(ll)i*p)/t.s)] ++; // need one at time >= x
		} // lowest d such that (m-d)*a[i] <= mid+p
	}
	F0Rd(i,m) {
		cnt[i] += cnt[i+1];
		if (k*(m-i) < cnt[i]) return 0;
	}
	return 1;
}

int main() {
    setIO(); re(n,m,k,p);
    v.rsz(n); re(v);
    ll lo = 0, hi = m*1e9;
    while (lo < hi) {
    	ll mid = (lo+hi)/2;
    	if (ok(mid)) hi = mid;
    	else lo = mid+1;
    }
    ps(lo);
}

/* stuff you should look for
    * int overflow, array bounds
    * special cases (n=1?), set tle
    * do smth instead of nothing and stay organized
*/


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100100;
int n,k,m,p,cnt[N];
ll b[N];
pair<int,int>a[N];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >S;
bool chk(ll x){
	ll sum=0;
	for(int i=1;i<=n;++i){
		b[i]=x;
		ll ret=(a[i].first-(b[i]-(ll)m*a[i].second));ret=max(ret,0ll);
		cnt[i]=(ret+p-1)/p;if(cnt[i]>m)return 0;sum+=cnt[i];
	}
	if(sum>m*k)return 0;
	while(!S.empty())S.pop();
	for(int i=1;i<=n;++i)S.emplace(b[i]/a[i].second,i);
	for(int i=m;i&&!S.empty();--i){
		if(S.top().first<=0)return 0;
		for(int j=1;j<=k&&!S.empty();++j){
			int x=S.top().second;S.pop();
			if(!cnt[x]){--j;continue;}
			b[x]+=p;--cnt[x];S.emplace(b[x]/a[x].second,x);
		}
	}
	return S.empty();
}

int main(){
	cin>>n>>m>>k>>p;
	for(int i=1;i<=n;++i)cin>>a[i].first>>a[i].second;
	ll l=0,r=1e18;
	while(l<r){
		ll mid=(l+r)/2;
		if(chk(mid))r=mid;
		else l=mid+1;
	}
	cout<<l<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100100;
int n,k,m,p,cnt[N];
ll b[N];
pair<int,int>a[N];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >S;
bool chk(ll x){
	ll sum=0;
	for(int i=1;i<=n;++i){
		b[i]=x;
		ll ret=(a[i].first-(b[i]-(ll)m*a[i].second));ret=max(ret,0ll);
		cnt[i]=(ret+p-1)/p;if(cnt[i]>m)return 0;sum+=cnt[i];
	}
	if(sum>m*k)return 0;
	while(!S.empty())S.pop();
	for(int i=1;i<=n;++i)S.emplace(b[i]/a[i].second,i);
	for(int i=m;i&&!S.empty();--i){
		if(S.top().first<=m-i)return 0;
		for(int j=1;j<=k&&!S.empty();++j){
			int x=S.top().second;S.pop();
			if(!cnt[x]){--j;continue;}
			b[x]+=p;--cnt[x];S.emplace(b[x]/a[x].second,x);
		}
	}
	for(int i=1;i<=n;++i)if(cnt[i])return 0;
	return 1;
}

int main(){
	cin>>n>>m>>k>>p;
	for(int i=1;i<=n;++i)cin>>a[i].first>>a[i].second;
	ll l=0,r=1e18;
	while(l<r){
		ll mid=(l+r)/2;
		if(chk(mid))r=mid;
		else l=mid+1;
	}
	cout<<l<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100100;
int n,k,m,p,f[N];
ll b[N];
pair<int,int>a[N];
set<pair<ll,int> >S;
bool chk(ll x){
	ll sum=0;
	for(int i=1;i<=n;++i){
		b[i]=x;
		ll ret=(a[i].first-(b[i]-(ll)m*a[i].second));ret=max(ret,0ll);
		ret=(ret+p-1)/p;if(ret>m)return 0;sum+=ret;
	}
	if(sum>m*k)return 0;
	S.clear();
	for(int i=1;i<=n;++i)S.emplace(b[i]/a[i].second,i);
	for(int i=m;i;--i){
		if(S.begin()->first<=0)return 0;
		for(int j=1;j<=k;++j)f[j]=-1;
		for(int j=1;j<=k;++j){
			int x=S.begin()->second;S.erase(S.begin());
			b[x]+=p;f[j]=x;
		}
		for(int j=1;j<=k;++j)if(f[j]!=-1)
			S.emplace(b[f[j]]/a[f[j]].second,f[j]);
	}
	return 1;
}

int main(){
	cin>>n>>m>>k>>p;
	for(int i=1;i<=n;++i)cin>>a[i].first>>a[i].second;
	ll l=0,r=1e18;
	while(l<r){
		ll mid=(l+r)/2;
		if(chk(mid))r=mid;
		else l=mid+1;
	}
	cout<<l<<'\n';
	return 0;
}