package main
import (
"fmt"
)
func main() {
var n, m, k int
if _, err := fmt.Scan(&n, &m, &k); err != nil {
return
}
dp2 := make([]int, k)
for i := range dp2 {
dp2[i] = -1
}
dp2[0] = 0
half := m / 2
for r := 0; r < n; r++ {
dp1 := make([][]int, half+1)
for i := range dp1 {
dp1[i] = make([]int, k)
for j := range dp1[i] {
dp1[i][j] = -1
}
}
dp1[0][0] = 0
for c := 0; c < m; c++ {
var x int
fmt.Scan(&x)
for i := half - 1; i >= 0; i-- {
for j := 0; j < k; j++ {
if dp1[i][j] != -1 {
val := dp1[i][j] + x
rem := val % k
if val > dp1[i+1][rem] {
dp1[i+1][rem] = val
}
}
}
}
}
rowMax := make([]int, k)
for i := range rowMax {
rowMax[i] = -1
}
for i := 0; i <= half; i++ {
for j := 0; j < k; j++ {
if dp1[i][j] > rowMax[j] {
rowMax[j] = dp1[i][j]
}
}
}
ndp2 := make([]int, k)
for i := range ndp2 {
ndp2[i] = -1
}
for u := 0; u < k; u++ {
if dp2[u] != -1 {
for v := 0; v < k; v++ {
if rowMax[v] != -1 {
val := dp2[u] + rowMax[v]
rem := val % k
if val > ndp2[rem] {
ndp2[rem] = val
}
}
}
}
}
dp2 = ndp2
}
fmt.Println(dp2[0])
}