#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 80;
long long dp[N][N][N];
long long f[2][N], b[N], a[N];
void up(long long &x, long long y) {
  if (y > x) x = y;
}
int main() {
  std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  long long n, m, K;
  cin >> n >> m >> K;
  int now = 0;
  for (int z = 1; z <= n; z++) {
    memset(dp, 0, sizeof dp);
    memset(b, 0, sizeof b);
    for (int i = 1; i <= m; cin >> a[i++])
      ;
    for (int i = 1; i <= m; i++) {
      for (int j = 1; j <= m / 2; j++)
        for (int k = 0; k < K; k++) dp[i][j][k] = dp[i - 1][j][k];
      for (int j = 1; j <= m / 2; j++)
        for (int k = 0; k < K; k++) {
          if (dp[i - 1][j - 1][k] || (j == 1 && !k))
            up(dp[i][j][(k + a[i]) % K], dp[i - 1][j - 1][k] + a[i]);
        }
    }
    for (int i = 0; i < K; i++)
      for (int j = 1; j <= m; j++) up(b[i], dp[m][j][i]);
    for (int i = 0; i < K; i++) f[now ^ 1][i] = max(b[i], f[now][i]);
    for (int i = 0; i < K; i++)
      for (int j = 0; j < K; j++)
        if (f[now][i] && b[j]) up(f[now ^ 1][(i + j) % K], f[now][i] + b[j]);
    now ^= 1;
  }
  cout << f[now][0] << '\n';
  return 0;
}
