#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll inf = 1e18;
struct rmq {
  using type = int;
  static type id() { return std::numeric_limits<type>::min(); }
  static type op(type const& l, type const& r) { return std::max(l, r); }
};
template <typename Monoid>
class segment_tree {
  using T = typename Monoid::type;

 public:
  segment_tree(std::vector<T> const& init)
      : sz(init.size()), n(expand(init.size())) {
    dat.assign(n * 2, Monoid::id());
    std::copy(begin(init), end(init), begin(dat) + n);
    for (int i = n - 1; i >= 0; --i) {
      dat[i] = Monoid::op(dat[i * 2], dat[i * 2 + 1]);
    }
  }
  segment_tree(int const n, T const& init = Monoid::id())
      : segment_tree(std::vector<T>(n, init)) {}
  void update(int p, T val) {
    assert(0 <= p && p < sz);
    dat[p += n] = val;
    while (p /= 2) {
      dat[p] = Monoid::op(dat[p * 2], dat[p * 2 + 1]);
    }
  }
  T query(int l, int r) const {
    assert(0 <= l && l <= r && r <= sz);
    l += n;
    r += n;
    T res1 = Monoid::id(), res2 = Monoid::id();
    while (l != r) {
      if (l & 1) {
        res1 = Monoid::op(res1, dat[l++]);
      }
      if (r & 1) {
        res2 = Monoid::op(dat[--r], res2);
      }
      l /= 2;
      r /= 2;
    }
    return Monoid::op(res1, res2);
  }
  int size() const { return sz; }

 private:
  int expand(int n) const {
    assert(n >= 1);
    return n == 1 ? n : expand((n + 1) / 2) * 2;
  }

 private:
  const int sz;
  const int n;
  std::vector<T> dat;
};
int main() {
  ll N, C;
  cin >> N >> C;
  vector<ll> x(N + 1), v(N + 1);
  for (int i = 1; i <= N; ++i) {
    cin >> x[i] >> v[i];
  }
  N = N + 1;
  auto rev_x = x, rev_v = v;
  reverse(begin(rev_x), end(rev_x));
  for (int i = 0; i < N; ++i) {
    rev_x[i] = C - rev_x[i];
  }
  reverse(begin(rev_v), end(rev_v));
  vector<ll> dp1(N + 1, -inf), rev_dp1(N + 1, -inf);
  vector<ll> dp2(N + 1, -inf), rev_dp2(N + 1, -inf);
  dp1[0] = rev_dp1[0] = 0;
  dp2[0] = rev_dp2[0] = 0;
  for (int i = 0; i < N; ++i) {
    dp1[i + 1] = (i != 0 ? dp1[i] + x[i - 1] : 0) + v[i] - x[i];
    dp2[i + 1] = (i != 0 ? dp2[i] + 2 * x[i - 1] : 0) + v[i] - 2 * x[i];
    rev_dp1[i + 1] =
        (i != 0 ? rev_dp1[i] + rev_x[i - 1] : 0) + rev_v[i] - rev_x[i];
    rev_dp2[i + 1] =
        (i != 0 ? rev_dp2[i] + 2 * rev_x[i - 1] : 0) + rev_v[i] - 2 * rev_x[i];
  }
  ll ans = 0;
  for (int i = 0; i < N; ++i) {
    dp1[i + 1] = max(dp1[i + 1], dp1[i]);
    dp2[i + 1] = max(dp2[i + 1], dp2[i]);
    ans = max({ans, dp1[i + 1], dp2[i + 1], rev_dp1[i + 1], rev_dp2[i + 1]});
  }
  for (int i = 1; i < N; ++i) {
    ll t1 = rev_dp1[i], t2 = rev_dp2[i];
    const int rev_pos = N - i - 1;
    const int sep = lower_bound(begin(x), end(x), C - rev_x[i]) - begin(x);
    if (rev_pos >= 0) {
      t1 += max(dp2[rev_pos], 0LL);
    }
    if (sep <= N) {
      t2 += max(dp1[sep], 0LL);
    }
    ans = max({ans, t1, t2});
  }
  cout << ans << endl;
}
