Problem:
矢印

　

$L$個のマスが左右に一列に並んでいます。いくつかのマスの上に駒が置いてあります。駒には左向きか右向きの矢印が書いてあります。なお、一つのマスに二つ以上の駒を置くことはできません。

どのマスにいる駒も、駒が置かれていないマスに動かすことができます。ただし、一度に動けるのは隣のマスまでで、一度に動かせるのは一つの駒だけです。駒は、矢印の向きにかかわらず、左にも右にも動かすことができます。ただし、駒を矢印の方向に一回動かすと点数が１点もらえますが、矢印とは逆方向に一回動かすと１点減点されてしまいます。なお、どのような状況から始めたとしても、得られる点数には必ず最大値があることがわかっています。

マスの個数と駒の状況が与えられたとき、得られる最大の点数を計算するプログラムを作成せよ。ただし、マスには列の左端から順番に1から$L$までの番号が割り当てられているものとする。

入力

入力は以下の形式で与えられる。

$N$ $L$
$p_1$ $d_1$
$p_2$ $d_2$
:
$p_N$ $d_N$

１行目に駒の数$N$ ($1 \leq N \leq 10^5$)とマスの数$L$ ($N \leq L \leq 10^9$)が与えられる。続く$N$行に駒が置かれたマスの番号$p_i$ ($1 \leq p_i \leq L$)と駒に書かれた矢印の向き$d_i$ (0または1)が与えられる。ただし、$d_i$が0のときは矢印が左向き、1のときは右向きを表す。同じマスの番号は与えられない（$i \ne j$について、$p_i \ne p_j$）。

出力

得られる最大の点数を１行に出力する。

入出力例

入力例１

2 10
3 0
6 1

出力例１

6

入力例２

2 8
2 1
8 0

出力例２

5

入力例３

2 8
1 0
8 1

出力例３

0

Solution in Scala (judge verdict: Accepted)

object Main extends App {
  import scala.io.StdIn._
  val Array(n, l) = readLine.trim.split(' ').map(_.toInt)
  val pawns = Array.fill(n){
    readLine.trim.split(' ').map(_.toInt) match {
      case Array(pos, 0) ⇒ Left(pos)
      case Array(pos, 1) ⇒ Right(pos)
    }
  }.sortBy(_.position)
  var currentScore = 0L
  val forward = Array.fill(n){0L}
  for (i ← pawns.indices) {
    pawns(i) match {
      case Left(pos) ⇒
        currentScore += pos - i - 1
      case Right(pos) ⇒
        currentScore += i - pos + 1
    }
    forward(i) = currentScore
  }
  currentScore = 0L
  val backward = Array.fill(n){0L}
  for (i ← pawns.indices.reverse) {
    pawns(i) match {
      case Left(pos) ⇒
        currentScore += pos - (l - (n - i - 1))
      case Right(pos) ⇒
        currentScore += (l - (n - i - 1)) - pos
    }
    backward(i) = currentScore
  }
  var min = math.max(forward.last, backward.head)
  for (i ← pawns.indices.tail) {
    min = math.max(min, forward(i - 1) + backward(i))
  }
  println(min)
  sealed class Pawn(val position: Int)
  case class Left(override val position: Int) extends Pawn(position)
  case class Right(override val position: Int) extends Pawn(position)
}