#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 内部定数
#define D_SUSHI_MAX		100000									// 最大寿司数

// 内部構造体 - 寿司情報
typedef struct Sushi {
	long long mlLen;											// 距離
	long long mlCal;											// カロリー
	long long mlCSum;											// カロリー累計
} Sushi;

// 内部変数
static Sushi sz1SushiR[D_SUSHI_MAX];							// 寿司リスト(右側方向累計)
static Sushi sz1SushiL[D_SUSHI_MAX];							// 寿司リスト(左側方向累計)
static int siSCnt;												// 寿司リスト数
static long long slLen;											// 外周長さ
static long long slMax;											// 最大カロリー累計

// 内部変数 - テスト用
#ifdef D_TEST
	static int siRes;
	static FILE *szpFpT, *szpFpA;
#endif

// 寿司リスト - 累計セット・片側移動の最大値更新
int
fUpMaxSgl(
	Sushi *pzpSushi				// <I> 寿司リスト
)
{
	int i;

	// １つ目
	long long llLSum = pzpSushi[0].mlLen;
	long long llCSum = pzpSushi[0].mlCal - pzpSushi[0].mlLen;
	pzpSushi[0].mlCSum = llCSum;

	// 最大値更新
	if (slMax < llCSum) {
		slMax = llCSum;
	}

	// ２つ目以降
	for (i = 1; i < siSCnt; i++) {
		llLSum += pzpSushi[i].mlLen;
		llCSum += pzpSushi[i].mlCal - pzpSushi[i].mlLen + pzpSushi[i - 1].mlLen;
		if (llCSum < pzpSushi[i - 1].mlCSum) {										// 前回の寿司時点の方が高カロリーの場合
			pzpSushi[i].mlCSum = pzpSushi[i - 1].mlCSum;
		}
		else {																		// 今回の寿司が高カロリー
			pzpSushi[i].mlCSum = llCSum;

			// 最大値更新
			if (slMax < llCSum) {
				slMax = llCSum;
			}
		}
	}

	return 0;
}

// 寿司リスト - 両側移動の最大値更新
int
fUpMaxDbl(
	Sushi *pzpSushi1			// <I> 寿司リスト１
	, Sushi *pzpSushi2			// <I> 寿司リスト２
)
{
	int i;

	for (i = 0; i < siSCnt - 1; i++) {

		// リスト１方向へ
		long long llCSum = pzpSushi1[i].mlCSum;

		// 初期位置へ
		llCSum -= pzpSushi1[i].mlLen;

		// リスト２方向へ
		llCSum += pzpSushi2[siSCnt - i - 2].mlCSum;

		// 最大値更新
		if (slMax < llCSum) {
			slMax = llCSum;
		}
	}

	return 0;
}

// 実行メイン
int
fMain(
	int piTNo					// <I> テスト番号 1～
)
{
	int i;
	char lc1Buf[1024], lc1Out[1024];

	// データ初期化
	slMax = 0;													// 最大カロリー累計

	// テストファイルオープン
#ifdef D_TEST
	sprintf(lc1Buf, ".\\Test\\T%d.txt", piTNo);
	szpFpT = fopen(lc1Buf, "r");
	sprintf(lc1Buf, ".\\Test\\A%d.txt", piTNo);
	szpFpA = fopen(lc1Buf, "r");
	siRes = 0;
#endif

	// 寿司リスト数・外周長さ取得
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpT);
#else
	fgets(lc1Buf, sizeof(lc1Buf), stdin);
#endif
	sscanf(lc1Buf, "%d%lld", &siSCnt, &slLen);

	// 寿司リスト(右側方向)取得
	for (i = 0; i < siSCnt; i++) {
#ifdef D_TEST
		fgets(lc1Buf, sizeof(lc1Buf), szpFpT);
#else
		fgets(lc1Buf, sizeof(lc1Buf), stdin);
#endif
		sscanf(lc1Buf, "%lld%lld", &sz1SushiR[i].mlLen, &sz1SushiR[i].mlCal);
	}

	// 寿司リスト(左側方向)セット
	for (i = 0; i < siSCnt; i++) {
		sz1SushiL[i].mlLen = slLen - sz1SushiR[siSCnt - i - 1].mlLen;
		sz1SushiL[i].mlCal = sz1SushiR[siSCnt - i - 1].mlCal;
	}

	// 寿司リスト - 累計セット・片側移動の最大値更新
	fUpMaxSgl(sz1SushiR);
	fUpMaxSgl(sz1SushiL);

	// 寿司リスト - 両側移動の最大値更新
	fUpMaxDbl(sz1SushiR, sz1SushiL);			// 右側方向＋左側方向
	fUpMaxDbl(sz1SushiL, sz1SushiR);			// 左側方向＋右側方向

	// 結果セット
	sprintf(lc1Out, "%lld\n", slMax);

	// 結果表示
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
	if (strcmp(lc1Buf, lc1Out)) {
		siRes = -1;
	}
#else
	printf("%s", lc1Out);
#endif

	// テストファイルクローズ
#ifdef D_TEST
	fclose(szpFpT);
	fclose(szpFpA);
#endif

	// テスト結果
#ifdef D_TEST
	if (siRes == 0) {
		printf("OK %d\n", piTNo);
	}
	else {
		printf("NG %d\n", piTNo);
	}
#endif

	return 0;
}

int
main()
{

#ifdef D_TEST
	int i;
	for (i = D_TEST_SNO; i <= D_TEST_ENO; i++) {
		fMain(i);
	}
#else
	fMain(0);
#endif

	return 0;
}



Measured memory_bytes: 4864