#![allow(non_snake_case)]

#[allow(unused_macros)]
macro_rules ! read_value {($ next : expr , ($ ($ t : tt ) ,* ) ) => {($ (read_value ! ($ next , $ t ) ) ,* ) } ; ($ next : expr , [$ t : tt ; $ len : expr ] ) => {(0 ..$ len ) . map (| _ | read_value ! ($ next , $ t ) ) . collect ::< Vec < _ >> () } ; ($ next : expr , chars ) => {read_value ! ($ next , String ) . chars () . collect ::< Vec < char >> () } ; ($ next : expr , usize1 ) => {read_value ! ($ next , usize ) - 1 } ; ($ next : expr , $ t : ty ) => {$ next () . parse ::<$ t > () . expect ("Parse error" ) } ; }
#[allow(unused_macros)]
macro_rules ! input_inner {($ next : expr ) => {} ; ($ next : expr , ) => {} ; ($ next : expr , $ var : ident : $ t : tt $ ($ r : tt ) * ) => {let $ var = read_value ! ($ next , $ t ) ; input_inner ! {$ next $ ($ r ) * } } ; }
#[allow(unused_macros)]
macro_rules ! input {(source = $ s : expr , $ ($ r : tt ) * ) => {let mut iter = $ s . split_whitespace () ; let mut next = || {iter . next () . unwrap () } ; input_inner ! {next , $ ($ r ) * } } ; ($ ($ r : tt ) * ) => {let stdin = std :: io :: stdin () ; let mut bytes = std :: io :: Read :: bytes (std :: io :: BufReader :: new (stdin . lock () ) ) ; let mut next = move || -> String {bytes . by_ref () . map (| r | r . unwrap () as char ) . skip_while (| c | c . is_whitespace () ) . take_while (| c |! c . is_whitespace () ) . collect () } ; input_inner ! {next , $ ($ r ) * } } ; }

#[allow(unused_macros)]
macro_rules ! min {($ a : expr $ (, ) * ) => {{$ a } } ; ($ a : expr , $ b : expr , $ (, ) * ) => {{std :: cmp :: min ($ a , $ b ) } } ; ($ a : expr , $ ($ rest : expr ) ,+ $ (, ) * ) => {{std :: cmp :: min ($ a , min ! ($ ($ rest ) ,+ ) ) } } ; }
#[allow(unused_macros)]
macro_rules ! chmin {($ base : expr , $ ($ cmps : expr ) ,+ $ (, ) * ) => {{let cmp_min = min ! ($ ($ cmps ) ,+ ) ; if $ base > cmp_min {$ base = cmp_min ; true } else {false } } } ; }

#[allow(unused_macros)]
macro_rules ! max {($ a : expr $ (, ) * ) => {{$ a } } ; ($ a : expr , $ b : expr $ (, ) * ) => {{std :: cmp :: max ($ a , $ b ) } } ; ($ a : expr , $ ($ rest : expr ) ,+ $ (, ) * ) => {{std :: cmp :: max ($ a , max ! ($ ($ rest ) ,+ ) ) } } ; }
#[allow(unused_macros)]
macro_rules ! chmax {($ base : expr , $ ($ cmps : expr ) ,+ $ (, ) * ) => {{let cmp_max = max ! ($ ($ cmps ) ,+ ) ; if $ base < cmp_max {$ base = cmp_max ; true } else {false } } } ; }

fn solve(N: usize, C: i64, xv: &Vec<(i64, i64)>) -> i64 {
    let mut rmax = vec![0; N];
    for i in 0..N {
        if i == 0 {
            rmax[0] = xv[0].1 - xv[0].0;
        } else {
            rmax[i] = rmax[i - 1] + xv[i].1 - (xv[i].0 - xv[i - 1].0);
        }
    }
    for i in 1..N {
        rmax[i] = std::cmp::max(rmax[i], rmax[i - 1]);
    }

    let mut ret = std::cmp::max(0, rmax[N - 1]);
    let mut cost_left = 0;
    for left in (1..N).rev() {
        cost_left += xv[left].1;
        let x_prev = if left == N - 1 {
            C
        } else {
            xv[left + 1].0
        };
        cost_left -= 2 * (x_prev - xv[left].0);
        chmax!(ret, cost_left + rmax[left - 1]);
    }
    ret
}

fn main() {
    input! {
        N: usize,
        C: i64,
        xv: [(i64, i64); N],
    }

    let mut ret = solve(N, C, &xv);

    let mut rev_xv = vec![];
    for (x, v) in xv.iter() {
        rev_xv.push((C - x.clone(), v.clone()));
    }
    rev_xv.reverse();
    chmax!(ret, solve(N, C, &rev_xv));

    println!("{}", ret);
}


Measured memory_bytes: 5972