#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

typedef long long ll, lint;
typedef long double ldouble;

#define sz(v) ((int) (v).size())
#define FOR(i, n) for (int (i) = 0; (i) < (n); (i)++)
#define For(i, n) for (int (i) = 0; (i) < (n); (i)++)
#define all(v) (v).begin(), (v).end()

#define mp make_pair
#define pb push_back
#define fst first
#define snd second

template<class T>
string to_string(T arr, int len = 1e9) {
    stringstream ss;
    int i = 0;
    for (auto item : arr) {
        ss << item << ' ';
        if (++i == len)
            break;
    }
    return ss.str();
}

#ifdef LOCAL
    #define dbg(expr) cout << "[line " << __LINE__ << "] " << (#expr) << ": " << (expr) << endl;
#else
    #define dbg(expr) (void) 0;
#endif


const lint inf = 1e18;

template <class Tnode>
struct SegTree {
	typedef Tnode (*seg_tree_func)(Tnode a, Tnode b);

	Tnode *data = nullptr;
	seg_tree_func f;
	Tnode default_val;
	int tsize;

	SegTree() {}

	SegTree(int size, Tnode _default_val, seg_tree_func _f) {
		f = _f;
		default_val = _default_val;
		tsize = 1;
		while (tsize < 2 * size)
			tsize *= 2;
		data = new Tnode[tsize];
		fill(data, data + tsize, default_val);
	}

	void put(Tnode val, int pos, int root, int lbound, int rbound) {
		if (pos < lbound || pos > rbound)
			return;
		if (lbound < rbound) {
			put(val, pos, root * 2, lbound, lbound + (rbound - lbound) / 2);
			put(val, pos, root * 2 + 1, lbound + (rbound - lbound) / 2 + 1, rbound);
			data[root] = f(data[root * 2], data[root * 2 + 1]);
		} else
			data[root] = val;
	}

	void put(Tnode val, int pos) {
		put(val, pos, 1, 0, tsize / 2 - 1);
	}

	Tnode get(int l, int r, int root, int lbound, int rbound) {
		if (r < lbound || l > rbound)
			return default_val;
		if (l <= lbound && rbound <= r)
			return data[root];
		Tnode lc_val = get(l, r, root * 2, lbound, lbound + (rbound - lbound) / 2);
		Tnode rc_val = get(l, r, root * 2 + 1, lbound + (rbound - lbound) / 2 + 1, rbound);
		return f(lc_val, rc_val);
	}

	Tnode get(int l, int r) {
		return get(l, r, 1, 0, tsize / 2 - 1);
	}

	void clear() {
		delete [] data;
	}
};

vector<lint> count_balance(const vector<lint>& x, const vector<lint>& v) {
    vector<lint> result;
    lint balance = 0;
    lint cur_x = 0;
    int n = x.size();
    For (i, n) {
        balance += v[i];
        balance -= x[i] - cur_x;
        result.push_back(balance);
    }
    return result;
}

lint count(const vector<lint>& x, const vector<lint>& v, lint c) {
    int n = x.size();
    auto tree = SegTree<lint>(n + 1, -inf, [](lint x, lint y) { return max(x, y); });
    tree.put(0, 0);
    lint eaten = 0;
    For (i, n) {
        eaten += v[i];
        tree.put(eaten - x[i], i + 1);
    }

    lint max_value = tree.get(0, n);
    eaten = 0;
    for (int i = n - 1; i >= 0; i--) {
        eaten += v[i];
        lint cur_x = c - x[i];
        lint balance = eaten - 2 * cur_x + tree.get(0, i);
        max_value = max(max_value, balance);
    }
    return max_value;
}

int main() {
#ifndef LOCAL
    cin.tie(0);
    ios_base::sync_with_stdio(false);
#endif

    int n;
    lint c;
    cin >> n >> c;
    vector<lint> x(n), v(n);
    For (i, n)
        cin >> x[i] >> v[i];

    lint max_value = count(x, v, c);
    auto r_v = v;
    reverse(all(r_v));
    vector<lint> r_x;
    for (int i = n - 1; i >= 0; i--)
        r_x.push_back(c - x[i]);
    max_value = max(max_value, count(r_x, r_v, c));
    cout << max_value << endl;
}

Measured memory_bytes: 7668