Problem:
Score : 500 points

Problem Statement

AtCoDeer is thinking of painting an infinite two-dimensional grid in a checked pattern of side K.
Here, a checked pattern of side K is a pattern where each square is painted black or white so that each connected component of each color is a K × K square.
Below is an example of a checked pattern of side 3:

AtCoDeer has N desires.
The i-th desire is represented by x_i, y_i and c_i.
If c_i is B, it means that he wants to paint the square (x_i,y_i) black; if c_i is W, he wants to paint the square (x_i,y_i) white.
At most how many desires can he satisfy at the same time?

Constraints

1 ≤ N ≤ 10^5

1 ≤ K ≤ 1000

0 ≤ x_i ≤ 10^9

0 ≤ y_i ≤ 10^9

If i ≠ j, then (x_i,y_i) ≠ (x_j,y_j).

c_i is B or W.

N, K, x_i and y_i are integers.

Input

Input is given from Standard Input in the following format:

N K
x_1 y_1 c_1
x_2 y_2 c_2
:
x_N y_N c_N

Output

Print the maximum number of desires that can be satisfied at the same time.

Sample Input 1

4 3
0 1 W
1 2 W
5 3 B
5 4 B

Sample Output 1

4

He can satisfy all his desires by painting as shown in the example above.

Sample Input 2

2 1000
0 0 B
0 1 W

Sample Output 2

2

Sample Input 3

6 2
1 2 B
2 1 W
2 2 B
1 0 B
0 6 W
4 5 W

Sample Output 3

4

Solution in Scala (2.11.7) (judge verdict: Accepted)

import java.io._
import java.util.StringTokenizer
import scala.util.control.Breaks.{breakable,break}

object Main extends App {
  val in = new InputReader(System.in)
  val pw = new PrintWriter(System.out)

  val N, K = in.next().toInt
  val MOD = 2*K
  val dp = Array.ofDim[Long](2*K, 2*K)

  for(_ <- 1 to N) {
    val _x, _y = in.next().toInt
    val c = in.next()
    var x = _x; var y = _y

    if(c == "W"){
      x += K
    }

    dp(y % MOD)(x % MOD) += 1L
  }

  val imos = Array.ofDim[Long](2*K, 2*K)
  for(y <- 0 until 2*K; x <- 0 until 2*K) {
    if(x == 0)
      imos(y)(x) = dp(y)(x)
    else
      imos(y)(x) = dp(y)(x) + imos(y)(x-1)
  }

  

  for(x <- 0 until 2*K; y <- 0 until 2*K) {
    if(y == 0)
      imos(y)(x) = imos(y)(x)
    else
      imos(y)(x) = imos(y)(x) + imos(y-1)(x)
  }


  def safeImos(x: Int, y: Int): Long = {
    if(x < 0 || y < 0) 0
    else imos(y)(x)
  }

  def calc(leftUp: (Int, Int)): Long = {
    var res: Long = 0L
    val (x, y) = leftUp
    val rightDown = (x + K-1, y + K-1)
    val (rx, ry) = rightDown

    if(rx < 2*K && ry < 2*K) {
      res += (imos(ry)(rx) - safeImos(x-1, ry) - safeImos(rx, y-1) + safeImos(x-1, y-1))
    }
    else if(rx >= 2*K && ry >= 2*K) {
      res +=
      (imos(2*K-1)(2*K-1) - safeImos(x-1, 2*K-1) - safeImos(2*K-1, y-1) + safeImos(x-1, y-1)
        + imos(ry % MOD)(rx % MOD)
        + imos(2*K-1)(rx % MOD) - safeImos(rx % MOD, y-1)
        + imos(ry % MOD)(2*K-1) - safeImos(x-1, ry % MOD)
      )
    }
    else if(rx >= 2*K) {
      val tmp = (imos(ry)(2*K-1) - safeImos(x-1, ry) - safeImos(2*K-1, y-1) + safeImos(x-1, y-1) +
        imos(ry)(rx % MOD) - safeImos(rx % MOD, y-1)
      )
      res += tmp
    }
    else if(ry >= 2*K) {
      val tmp =
        (imos(2*K-1)(rx) - safeImos(x-1, 2*K-1) - safeImos(rx, y-1) + safeImos(x-1, y-1)
          + imos(ry % MOD)(rx) - safeImos(x-1, ry % MOD)
        )
      res += tmp
    }

    res
  }

  var ans = 0L
  for(y <- 0 until 2*K; x <- 0 until 2*K) {
    val tmp = calc(x, y) + calc((x+K)%MOD, (y+K)%MOD)
    ans = Math.max(ans, tmp)
  }

  println(ans)
}


class InputReader(stream: InputStream) {
  private val reader = new BufferedReader(new InputStreamReader(stream))
  private var tokenizer: StringTokenizer = new StringTokenizer(reader.readLine())
  def next(): String = {
    while (!tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(reader.readLine())
    }
    tokenizer.nextToken()
  }
}