//#define NDEBUG
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <limits>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
constexpr double PI = 3.1415926535897932;

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::int_fast64_t;
using intl32 = std::int_least32_t;
using intl64 = std::int_least64_t;
using uintl32 = std::uint_least32_t;
using uintl64 = std::uint_least64_t;
#include <cassert>
#include <functional>
#include <vector>

template <typename Monoid> class SegmentTree {
public:
	using value_type = Monoid;
	using reference = value_type &;
	using const_reference = const value_type &;
	using container_type = std::vector<value_type>;
	using size_type = typename container_type::size_type;

private:
	const size_type size_, capacity;
	container_type tree;
	static size_type getsize(const size_type &size) noexcept {
		size_type ret = 1;
		while (ret < size)
			ret <<= 1;
		return ret;
	}
	void recalc(const size_type &index) {
		tree[index] = tree[index << 1] + tree[index << 1 | 1];
	}

public:
	explicit SegmentTree(const size_type &size)
		: size_(size), capacity(getsize(size_)), tree(capacity << 1) {}
	void update(size_type index,
		const std::function<value_type(const_reference)> &f) {
		assert(index < size());
		index += capacity;
		tree[index] = f(tree[index]);
		while (index >>= 1)
			recalc(index);
	}
	void update(const size_type &index, const_reference data) {
		update(index, [&data](const_reference x) { return data; });
	}
	value_type range(size_type begin, size_type end) const {
		assert(begin <= end);
		assert(begin <= size());
		assert(end <= size());
		value_type retL, retR;
		for (begin += capacity, end += capacity; begin < end;
			begin >>= 1, end >>= 1) {
			if (begin & 1)
				retL = retL + tree[begin++];
			if (end & 1)
				retR = tree[end - 1] + retR;
		}
		return retL + retR;
	}
	size_type search(const std::function<bool(const_reference)> &b) const {
		if (b(value_type()))
			return 0;
		if (!b(tree[1]))
			return size() + 1;
		value_type acc;
		size_type i = 1;
		while (i < capacity)
			if (!b(acc + tree[i <<= 1]))
				acc = acc + tree[i++];
		return i - capacity + 1;
	}
	const_reference operator[](const size_type &index) const {
		assert(index < size());
		return tree[index + capacity];
	}
	size_type size() const noexcept { return size_; }
	bool empty() const noexcept { return !size_; }
};


const char *yes(bool c) { return c ? "yes" : "no"; }
const char *Yes(bool c) { return c ? "Yes" : "No"; }
const char *YES(bool c) { return c ? "YES" : "NO"; }
const char *pos(bool c) { return c ? "possible" : "impossible"; }
const char *Pos(bool c) { return c ? "Possible" : "Impossible"; }
const char *POS(bool c) { return c ? "POSSIBLE" : "IMPOSSIBLE"; }
template<class T>bool bmaxi(T&a, const T&b) { if (b<a)return 0;a = b;return 1; }
template<class T>bool bmini(T&a, const T&b) { if (a<b)return 0;a = b;return 1; }
template<class T>bool nmaxi(T&a, const T&b) { if (a<b) { a = b;return 1; }return 0; }
template<class T>bool nmini(T&a, const T&b) { if (b<a) { a = b;return 1; }return 0; }
template<typename T>auto scan(T&d)->typename std::enable_if<std::is_signed<T>::value>::type
{
	d = 0;int c = fgetc(stdin);bool f = 0;while (c<'0' || '9'<c) { if (c == '-')f = 1;c = fgetc(stdin); }
	while (c != ' '&&c != '\n') { d = d * 10 + c - '0';c = fgetc(stdin); }if (f)d = -d;
}
template<typename T>auto scan(T&d)->typename std::enable_if<!std::is_signed<T>::value>::type
{
	d = 0;int c = fgetc(stdin);while (c == ' ' || c == '\n')c = fgetc(stdin);
	while (c != ' '&&c != '\n') { d = d * 10 + c - '0';c = fgetc(stdin); }
}
void scan(char&d) { d = fgetc(stdin);while (d == ' ' || d == '\n')d = fgetc(stdin); }
void scan(double&d) { scanf("%lf", &d); }void scan(std::string&d) {
	d.clear();int c = fgetc(stdin);
	while (c == ' ' || c == '\n')c = fgetc(stdin);while (c != ' '&&c != '\n') { d.push_back(c);c = fgetc(stdin); }
}
template<typename F, typename...R>void scan(F&f, R&...r) { scan(f);scan(r...); }
template<typename T>T input() { T d;scan(d);return d; }
template <typename T>auto print(T d)->typename std::enable_if<std::is_signed<T>::value>::type
{
	static int c[20];int i = 0;bool f = 0;if (d<0) { f = 1;d = -d; }while (d) { c[i++] = d % 10;d /= 10; }
	if (!i)c[i++] = 0;if (f)fputc('-', stdout);while (i--)fputc(c[i] + '0', stdout);
}
template<typename T>auto print(T d)->typename std::enable_if<!std::is_signed<T>::value>::type
{
	static int c[20];int i = 0;while (d) { c[i++] = d % 10;d /= 10; }
	if (!i)c[i++] = 0;while (i--)fputc(c[i] + '0', stdout);
}
template<>void print<char>(char d) { fputc(d, stdout); }
template<>void print<double>(double d) { printf("%f", d); }
void print(const char *c) { while (*c != '\0')fputc(*(c++), stdout); }void print() {}
template<typename F, typename...R>void print(F f, R...r) { print(f);print(r...); }
template<typename...R>void println(R...r) { print(r...);fputc('\n', stdout); }
template<typename...R>int END(R...r) { println(r...);return 0; }

#include <algorithm>
#include <limits>
template <typename T> struct Maxi {
	using value_type = T;
	T a;
	explicit Maxi(const T &x = std::numeric_limits<T>::min()) : a(x) {}
	Maxi operator+(const Maxi &o) const { return Maxi(std::max(a, o.a)); }
};
using M = Maxi<uint64>;

int main() {
	uint32 n;
	uint64 c;
	scan(n, c);
	std::vector<uint64> x(n),y(n);
	std::vector<uint32> v(n);
	for (uint32 i = 0;i < n;++i)
		scan(x[i], v[i]);
	for (uint32 i = 0;i < n;++i) {
		y[i] = c - x[n - i - 1];
	}
	std::vector<uint64> r(n + 1), l(n + 1);
	for (uint32 i = 0;i < n;++i) {
		r[i + 1] = r[i] + v[i];
		l[i + 1] = l[i] + v[n - i - 1];
	}
	uint64 ans = 0;
	//uint64 rans = 0, lans = 0;
	for (uint32 i = 0;i < n;++i) {
		bmaxi(ans, r[i + 1] - x[i]);
		bmaxi(ans, l[i + 1] - y[i]);
	}
	SegmentTree<M> R(n+1),L(n+1);
	R.update(0, M(0));
	L.update(0, M(0));
	for (uint32 i = 0;i < n;++i) {
		R.update(i + 1, M(r[i + 1] - x[i]));
		L.update(i + 1, M(l[i + 1] - y[i]));
	}
	for (uint32 i = 0;i < n;++i) {
		bmaxi(ans, r[i + 1] - x[i] * 2 + L.range(0, n  - i).a);
		bmaxi(ans, l[i + 1] - y[i] * 2 + R.range(0, n  - i).a);
	}
	println(ans);
	return 0;
}

Measured memory_bytes: 8320