#include using namespace std; #define ll long long #define rep(i, n) for (int i = 0; i < (int)(n); i++) template bool chmin(T& a, T b){if(a > b){a = b; return true;} return false;} template bool chmax(T& a, T b){if(a < b){a = b; return true;} return false;} const long long mod=998244353; const long long mod2=469762049; const long long mod100=1000000007; template struct segtree{ //0-indexed using F = function; int n, offset; vectornode; F op; T identity; segtree(int N, F op, T identity):op(op), identity(identity){ offset = 1; n = N; while(offset < N) offset <<= 1; node.assign(offset*2, identity); } T operator[](int p){ return node[p+offset]; } //seg[p]をxに変更する void set(int p, T x){ if(p < 0 || p >= offset){ if(p < 0) cerr << "segtree in set:p < 0"<= offset) cerr << "segtree in set:p >= offset"<= 2){ p >>= 1; node[p] = op(node[p*2], node[p*2+1]); } return; } //[l,r)の区間を取得する T fold(int l,int r){ if(l < 0){ cerr << "segtree in fold:l < 0" << endl; l = 0; } if(l >= offset){ cerr << "segtree in fold:l >= offset" << endl; l = offset - 1; } if(r < 0){ cerr << "segtree in fold:r < 0" << endl; r = 0; } if(r > offset){ cerr << "segtree in fold:r >= offset" << endl; r = offset; } l += offset; r += offset; T L=identity,R=identity; for(; l < r; l >>= 1, r >>= 1){ if(l & 1) L = op(L, node[l++]); if(r & 1) R = op(node[--r], R); } return op(L,R); } //f(l,r)=trueとなるrの最大値を取得 int max_right(const functionf, int l = 0){ if(l >= n) return n; if(l < 0){ cerr << "segtree in max_right: l < 0" << endl; l = 0; } l += offset; T sum = identity; do{ while(l % 2 == 0) l >>= 1; if(!f(op(sum, node[l]))){ while(l < offset){ l = l * 2; if(f(op(sum, node[l]))){ sum = op(sum,node[l]); ++l; } } return l - offset; } sum = op(sum, node[l]); ++l; } while ((l & -l) != l); return n; } //f(l,r)=trueとなる最小のlを取得 int min_left(const functionf, int r = -1){ if(r == 0) return 0; if(r < 0) r = n; r += offset; T sum = identity; do{ --r; while(r > 1 && (r & 1)) r >>= 1; if(!f(op(node[r], sum))){ while(r < offset){ r = r * 2 + 1; if(f(op(node[r], sum))){ sum = op(node[r], sum); --r; } } return r + 1 - offset; } sum = op(node[r], sum); } while((r & -r) != r); return 0; } }; int main(){ cout.tie()->sync_with_stdio(0); cin.tie(0); int N;ll D;cin>>N>>D; pairAB[N+1]; ll A[N+1],B[N+1],C[N+1]; vectorpress; for(int i=1;i<=N;i++){ cin>>AB[i].second>>AB[i].first; press.push_back(AB[i].first%D); } sort(AB+1,AB+N+1); sort(press.begin(),press.end()); press.erase(unique(press.begin(),press.end()),press.end()); for(int i=1;i<=N;i++){ A[i]=AB[i].second; B[i]=AB[i].first; auto it=lower_bound(press.begin(),press.end(),B[i]%D); int idx=distance(press.begin(),it); C[i]=idx+1; //cout<seg(N+1,op,0LL); for(int i=1;i<=N;i++){ seg.set(C[i],seg[C[i]]+A[i]); } ll plus=0; for(int i=1;i<=N;i++) plus+=(B[i]+D-1)/D*A[i]; ll ans=plus; for(int i=1;i<=N;i++){ seg.set(C[i],seg[C[i]]-A[i]); plus-=(B[i]+D-1)/D*A[i]; ll now=B[i]+plus; //cout<