#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define each(i,a) for (auto&& i : a)
#define FOR(i,a,b) for (ll i=(a),__last_##i=(b);i<__last_##i;i++)
#define RFOR(i,a,b) for (ll i=(b)-1,__last_##i=(a);i>=__last_##i;i--)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) RFOR(i,0,n)
#define __GET_MACRO3(_1, _2, _3, NAME, ...) NAME
#define rep(...) __GET_MACRO3(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define rrep(...) __GET_MACRO3(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define chmin(x,v) x = min(x, v)
#define chmax(x,v) x = max(x, v)

const ll linf = 1e18;
const double eps = 1e-12;
const double pi = acos(-1);

template<typename T>
istream& operator>>(istream& is, vector<T>& vec) {
    each(x,vec) is >> x;
    return is;
}
template<typename T>
ostream& operator<<(ostream& os, const vector<T>& vec) {
    rep(i,vec.size()) {
        if (i) os << " ";
        os << vec[i];
    }
    return os;
}
template<typename T>
ostream& operator<<(ostream& os, const vector< vector<T> >& vec) {
    rep(i,vec.size()) {
        if (i) os << endl;
        os << vec[i];
    }
    return os;
}
template <class Monoid>
class SegmentTree {
    using T = typename Monoid::type;
    const int size_, n;
    std::vector<T> data;
    int expand(int m) const { return m == 1 ? m : expand((m + 1) / 2) * 2; }
public:
    SegmentTree(const std::vector<T> &vec) :
        size_(vec.size()), n(expand(size_)), data(n * 2, Monoid::id()) {
        std::copy(begin(vec), end(vec), begin(data) + n);
        for (int i = n - 1; i >= 0; --i) {
            data[i] = Monoid::op(data[i * 2 + 0], data[i * 2 + 1]);
        }
    }
    SegmentTree(const int count, const T &value = Monoid::id()) :
        SegmentTree(std::vector<T>(count, value)) {}
    int size() const { return size_; }
    void update(int pos, const T &value) {
        assert (0 <= pos && pos < size_); // assertion
        data[pos += n] = value;
        while (pos /= 2) {
            data[pos] = Monoid::op(data[pos * 2], data[pos * 2 + 1]);
        }
    }
    T query(int l, int r) const {
        assert (0 <= l && l <= r && r <= size_); // assertion
        l += n; r += n;
        T res1 = Monoid::id(), res2 = Monoid::id();
        while (l != r) {
            if (l % 2) res1 = Monoid::op(res1, data[l++]);
            if (r % 2) res2 = Monoid::op(data[--r], res2);
            l /= 2; r /= 2;
        }
        return Monoid::op(res1, res2);
    }
    using value_type = T;
    using update_type = T;
};

struct Min {
    using type = ll;
    static type id() { return linf; }
    static type op(const type &l, const type &r) { return min(l, r); }
};
struct Max {
    using type = ll;
    static type id() { return -linf; }
    static type op(const type &l, const type &r) { return max(l, r); }
};
struct Sum {
    using type = ll;
    static type id() { return 0; }
    static type op(const type &l, const type &r) { return l + r; }
};

ll solve(const vector<ll>& x, const vector<ll>& v, const ll L) {
    const ll n = x.size();
    vector<ll> S(n+1, 0);
    ll px = 0;
    rep(i, n) {
        ll dx = x[i] - px;
        S[i+1] = S[i] + (v[i] - dx);
        px = x[i];
    }
    vector<ll> Sr(n+1, 0);
    px = L;
    rrep(i, n) {
        ll dx = px - x[i];
        Sr[i] = Sr[i+1] + (v[i] - dx * 2);
        px = x[i];
    }
    SegmentTree<Max> seg(n+1);
    rep(i, n+1) seg.update(i, S[i]);
    ll res = 0;
    rrep(i, n+1) {
        chmax(res, Sr[i] + seg.query(0, i+1));
    }
    return res;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n, L; cin >> n >> L;
    vector<ll> x(n), v(n);
    rep(i, n) cin >> x[i] >> v[i];
    ll ans = solve(x, v, L);
    rep(i, n) x[i] = L - x[i];
    reverse(all(x));
    reverse(all(v));
    chmax(ans, solve(x, v, L));
    cout << ans << endl;
}


Measured memory_bytes: 6272