Vasya got really tired of these credits (from problem F) and now wants to earn the money himself! He decided to make a contest to gain a profit.

Vasya has n problems to choose from. They are numbered from 1 to n. The difficulty of the i-th problem is d_i. Moreover, the problems are given in the increasing order by their difficulties. The difficulties of all tasks are pairwise distinct. In order to add the i-th problem to the contest you need to pay c_i burles to its author. For each problem in the contest Vasya gets a burles.

In order to create a contest he needs to choose a consecutive subsegment of tasks.

So the total earnings for the contest are calculated as follows: 

  * if Vasya takes problem i to the contest, he needs to pay c_i to its author; 
  * for each problem in the contest Vasya gets a burles; 
  * let gap(l, r) = max_{l ≤ i < r} (d_{i + 1} - d_i)^2. If Vasya takes all the tasks with indices from l to r to the contest, he also needs to pay gap(l, r). If l = r then gap(l, r) = 0. 



Calculate the maximum profit that Vasya can earn by taking a consecutive segment of tasks.

Input

The first line contains two integers n and a (1 ≤ n ≤ 3 ⋅ 10^5, 1 ≤ a ≤ 10^9) — the number of proposed tasks and the profit for a single problem, respectively.

Each of the next n lines contains two integers d_i and c_i (1 ≤ d_i, c_i ≤ 10^9, d_i < d_{i+1}).

Output

Print one integer — maximum amount of burles Vasya can earn.

Examples

Input


5 10
1 15
5 3
6 11
7 2
11 22


Output


13


Input


3 5
1 8
2 19
3 11


Output


0
import java.io.*;
import java.util.*;

public class G implements Runnable{
	public static void main (String[] args) {new Thread(null, new G(), "_cf", 1 << 28).start();}

	public void run() {
//		try { new TestGen(); } catch (Exception e) {}
		FastScanner fs = new FastScanner();
//		try { fs = new FastScanner("testdata.out"); } catch (Exception e) {}
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("Go!");

		int n = fs.nextInt();
		int a = fs.nextInt();
		int[][] data = new int[n][2];
		for(int i = 0; i < n; i++) {
			data[i] = fs.nextIntArray(2);
		}
		
		if(n == 1) {
			long res = Math.max(0, a - data[0][1]);
			System.out.println(res);
			return;
		}
		
		int[][] diffs = new int[n-1][];
		for(int i = 0; i < n-1; i++) {
			int diff = data[i+1][0] - data[i][0];
			int[] arr = {diff, i, i+1};
			diffs[i] = arr;
		}
		Arrays.sort(diffs, 
		(x, y) -> Integer.compare(x[0], y[0]) == 0 ? Integer.compare(x[1], y[1]) : Integer.compare(x[0], y[0]));
		
		long[] pref = new long[n];
		for(int i = 0; i < n; i++) {
			pref[i] = a - data[i][1];
			if(i > 0) pref[i] += pref[i-1];
		}
		
		long oo = (long)1e18;
		int log = Integer.numberOfTrailingZeros(Integer.highestOneBit(n))+1;
		long[][] best = new long[log][n];
		long[][] min = new long[log][n];
		long[][] max = new long[log][n];
		for(int i = 0; i < n; i++) {
			best[0][i] = -oo;
			min[0][i] = pref[i];
			max[0][i] = pref[i];
		}
		for(int lg = 1, lastRange = 1; lg < log; lg++) {
			for(int i = 0; i < n; i++) {
				int nxt = Math.min(n-1, i+lastRange);
				best[lg][i] = Math.max(best[lg-1][i], best[lg-1][nxt]);
				best[lg][i] = Math.max(best[lg][i], max[lg-1][nxt] - min[lg-1][i]);
				max[lg][i] = Math.max(max[lg-1][i], max[lg-1][nxt]);
				min[lg][i] = Math.min(min[lg-1][i], min[lg-1][nxt]);
			}
			lastRange *= 2;
		}
		
//		System.out.println(Arrays.toString(pref));
		
		long res = 0;
		DSU ds = new DSU(n);
		for(int i = 0; i < diffs.length; i++) {
			int x = diffs[i][1], y = diffs[i][2];
			long val = (long)diffs[i][0] * diffs[i][0];
			ds.union(x, y);
			if(x > 0) {
				long d1 = data[x][0]-data[x-1][0];
				if(d1*d1 <= val)
					ds.union(x, x-1);
			}
			if(y + 1 < n) {
				long d1 = data[y+1][0]-data[y][0];
				if(d1*d1 <= val)
					ds.union(y, y+1);
			}
			int par = ds.find(x);
			int lf = ds.min[par];
			int rg = ds.max[par];
//			System.out.println(lf + " " + rg);
			long ret = 0;
			int dist = rg-lf+1;
			int b1 = Integer.highestOneBit(dist);
			int lg = Integer.numberOfTrailingZeros(b1);
			ret = Math.max(best[lg][lf], best[lg][rg-b1+1]);
//			System.out.println("R " + ret + " " + best[lg][lf] + " " + best[lg][rg-b1+1]);
			long mn = min[lg][lf];
			long mx = -oo;
			lf += b1; dist -= b1;
			while(dist > 0) {
				b1 = Integer.highestOneBit(dist);
				lg = Integer.numberOfTrailingZeros(b1);
				mx = Math.max(mx, max[lg][lf]);
				lf += b1; dist -= b1;
			}
//			System.out.println("M " + mn + " " + mx);
			ret = Math.max(ret, mx-mn);
			{
				lf = ds.min[par];
				rg = ds.max[par];
				dist = rg-lf+1;
				b1 = Integer.highestOneBit(dist);
				lg = Integer.numberOfTrailingZeros(b1);
				mx = Math.max(max[lg][lf], max[lg][rg-b1+1]);
				if(ds.min[par] > 0) mx -= pref[ds.min[par]-1];
				ret = Math.max(ret, mx);
			}
			ret -= val;
//			System.out.println(Arrays.toString(diffs[i]) + " " + ret);
			res = Math.max(res, ret);
			
//			System.out.println();
		}
		for(int i = 0; i < n; i++) {
			res = Math.max(res, a - data[i][1]);
		}
		out.println(res);
//		out.println(brute(data, a));
		out.close();
	}
	
	long brute(int[][] data, long a) {
		int n = data.length;
		long res = 0;
		for(int i = 0; i < n; i++) {
			for(int j = i; j < n; j++) {
				if(i == j) res = Math.max(res, a - data[i][1]);
				long max = 0;
				long sum = 0;
				for(int k = i; k <= j; k++) sum += a - data[k][1];
				for(int k = i+1; k <= j; k++) {
					max = Math.max(max, data[k][0]-data[k-1][0]);
				}
				res = Math.max(res, sum - max*max);
			}
		}
		
		return res;
	}
	
	class DSU {
		int n, par[], rank[];
		int[] min, max;
		DSU(int a) {
			n = a;
			par = new int[n];
			rank = new int[n];
			min = new int[n];
			max = new int[n];
			for(int i = 0; i < n; i++) {
				par[i] = i;
				min[i] = i;
				max[i] = i;
			}
		}
		int find(int u) {
			return par[u] == u ? u : (par[u] = find(par[u]));
		}
		void union(int u, int v) {
			int pu = find(u), pv = find(v);
			if(pu == pv) return;
			if(rank[pu] >= rank[pu]) {
				if(rank[pu] == rank[pv]) rank[pu]++;
				par[pv] = pu;
				min[pu] = Math.min(min[pu], min[pv]);
				max[pu] = Math.max(max[pu], max[pv]);
			}
			else {
				par[pu] = pv;
				min[pv] = Math.min(min[pu], min[pv]);
				max[pv] = Math.max(max[pu], max[pv]);
			}
		}
		
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}                
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}
		
		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}
		
	}

}