#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000009;
const long long INFLL = 0x1f1f1f1f1f1f1f1fLL;
template <class A, class B>
inline ostream& operator<<(ostream& st, const pair<A, B>& P) {
  return st << "(" << P.first << ", " << P.second << ")";
};
template <class A, class B>
inline pair<A, B> operator+(const pair<A, B>& P, const pair<A, B>& Q) {
  return pair<A, B>(P.first + Q.first, P.second + Q.second);
};
template <class A, class B>
inline pair<A, B> operator-(const pair<A, B>& P, const pair<A, B>& Q) {
  return pair<A, B>(P.first - Q.first, P.second - Q.second);
};
template <typename monoid>
struct segment_tree {
  using M = monoid;
  using T = typename M::value_type;
  std::size_t sz;
  std::vector<T> x;
  segment_tree(std::size_t n = 0) {
    sz = 1;
    while (sz < n) sz *= 2;
    x.assign(sz * 2, M::id());
    initialize();
  }
  template <typename iterator>
  segment_tree(iterator first, iterator last) {
    sz = 1;
    std::size_t n = std::distance(first, last);
    while (sz < n) sz *= 2;
    x.assign(sz * 2, M::id());
    std::copy(first, last, x.begin() + sz);
    initialize();
  }
  void fill(const T& val) {
    std::fill(x.begin() + sz, x.end(), val);
    initialize();
  }
  void initialize() {
    for (int i = (int)sz - 1; i >= 1; --i) {
      x[i] = M::op(x[i * 2 + 0], x[i * 2 + 1]);
    }
  }
  T accumulate(std::size_t l, std::size_t r) const {
    T al = M::id(), ar = M::id();
    for (l += sz, r += sz; l < r; l /= 2, r /= 2) {
      if (l & 1) al = M::op(al, x[l++]);
      if (r & 1) ar = M::op(x[--r], ar);
    }
    return M::op(al, ar);
  }
  void update(std::size_t i, const T& val) {
    x[i += sz] = val;
    while (i > 1) {
      x[i / 2] = M::op(x[i], x[i ^ 1]);
      i /= 2;
    }
  }
  T operator[](std::size_t i) const { return x[sz + i]; }
};
template <typename T>
struct max_monoid {
  using value_type = T;
  static constexpr value_type id() {
    return std::numeric_limits<value_type>::min();
  }
  static value_type op(const value_type& a, const value_type& b) {
    return std::max(a, b);
  }
};
template <typename value_type>
using rmq = segment_tree<max_monoid<value_type>>;
long long x[100005];
long long v[100005];
int main() {
  long long n, c;
  rmq<long long> s0(131072);
  rmq<long long> s1(131072);
  long long ret0 = 0;
  long long ret0i = 0;
  cin >> n >> c;
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> v[i];
  }
  long long s = 0;
  for (int i = 0; i < n; i++) {
    s += v[i];
    s0.update(i, s - x[i] * 2);
    if (ret0 < s - x[i]) {
      ret0 = s - x[i];
      ret0i = i;
    }
  }
  long long ret1 = 0;
  long long ret1i = 0;
  s = 0;
  for (int i = n - 1; i >= 0; i--) {
    s += v[i];
    s1.update(i, s - (c - x[i]) * 2);
    if (ret1 < s - (c - x[i])) {
      ret1 = s - (c - x[i]);
      ret1i = i;
    }
  }
  long long ret2 = 0;
  s = 0;
  for (int i = 0; i < n; i++) {
    s += v[i];
    ret2 = max(ret2, s - x[i] + s1.accumulate(i + 1, n));
  }
  long long ret3 = 0;
  s = 0;
  for (int i = n - 1; i >= 0; i--) {
    s += v[i];
    ret3 = max(ret3, s - (c - x[i]) + s0.accumulate(0, i));
  }
  cout << max(max(ret0, ret1), max(ret2, ret3)) << endl;
}
