#include <bits/stdc++.h>
using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)
#define setp(x) fixed << setprecision(x)
#define ordered_set tree<pair<long double, int> , null_type,less<pair<long double, int> >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const ll INF = ll(1e16);
const int mod = inf + 7;
const double PI = acos(-1.0);
void mul(ll &x, ll y){
  x *= y;
  if(x >= mod) x %= mod;
}
ll bp(ll a, ll n, ll cm){
  ll r = 1;
  while(n){
    if(n & 1) r = r * a % cm;
    a = a * a % cm;
    n >>= 1;
  }
  return r;
}
template<typename T_vector> // neal
void output_vector(const T_vector &v, bool add_one = false, int start = -1, int end = -1) {
    if (start < 0) start = 0;
    if (end < 0) end = int(v.size());

    for (int i = start; i < end; i++)
        cout << v[i] + (add_one ? 1 : 0) << (i < end - 1 ? ' ' : '\n');
}
const int S = 4901;
int dp[71][S + 10];
int ndp[71][71];
int ans[71][71];
void solve(){
  int n, m, d;
  cin >> n >> m >> d;
  int a[n + 1][m + 1];
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
      cin >> a[i][j];
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j <= m; ++j)
      for(int k = 0; k <= S; ++k)
        dp[j][k] = inf;
    dp[0][0] = 0;
    for(int j = 1; j <= m; ++j){
      for(int k = 0; k <= S; ++k){
        dp[j][k] = dp[j - 1][k];
        if(k >= a[i][j])
          dp[j][k] = min(dp[j - 1][k - a[i][j]] + 1, dp[j][k]);
        if(dp[j][k] <= m / 2){
          // cout << "here" << j << ' ' << k << '\n';
          ndp[i][k % d] = max(ndp[i][k % d], k);
        }
      }
    }
  }
  // for(int i = 1; i <= n; ++i)
  //   for(int j = 0; j < d; ++j)
  //     cout << ndp[i][j] << " \n"[j == d - 1];
  int res = 0;
  for(int i = 1; i <= n; ++i){
    for(int last = 0; last < d; ++last){
      for(int nxt = 0; nxt < d; ++nxt){
        ans[i][nxt] = max(ans[i][nxt],
          ans[i - 1][last] + ndp[i][(nxt - last + d) % d]);
        // res = max(res, ans[i][nxt] + ndp[i][nxt]);
        res = max(res, ans[i][nxt]);
      }
    }
  }
  cout << res - 1;

}

int main()
{
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
    Red;
    int T = 1;
    // cin >> T;
    for(int i = 1; i <= T; ++i){
      solve();
    }
    return 0;

}


#include <bits/stdc++.h>
using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)
#define setp(x) fixed << setprecision(x)
#define ordered_set tree<pair<long double, int> , null_type,less<pair<long double, int> >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const ll INF = ll(1e16);
const int mod = inf + 7;
const double PI = acos(-1.0);
void mul(ll &x, ll y){
  x *= y;
  if(x >= mod) x %= mod;
}
ll bp(ll a, ll n, ll cm){
  ll r = 1;
  while(n){
    if(n & 1) r = r * a % cm;
    a = a * a % cm;
    n >>= 1;
  }
  return r;
}
template<typename T_vector> // neal
void output_vector(const T_vector &v, bool add_one = false, int start = -1, int end = -1) {
    if (start < 0) start = 0;
    if (end < 0) end = int(v.size());

    for (int i = start; i < end; i++)
        cout << v[i] + (add_one ? 1 : 0) << (i < end - 1 ? ' ' : '\n');
}
const int S = 4901;
int dp[71][S + 10];
int ndp[71][71];
int ans[71][71];
void solve(){
  int n, m, d;
  cin >> n >> m >> d;
  int a[n + 1][m + 1];
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
      cin >> a[i][j];
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j <= m; ++j)
      for(int k = 0; k <= S; ++k)
        dp[j][k] = inf;
    dp[0][0] = 0;
    for(int j = 1; j <= m; ++j){
      for(int k = 0; k <= S; ++k){
        dp[j][k] = dp[j - 1][k];
        if(k >= a[i][j])
          dp[j][k] = min(dp[j - 1][k - a[i][j]] + 1, dp[j][k]);
        if(dp[j][k] <= m / 2)
          ndp[i][k % d] = max(ndp[i][k % d], k);
      }
    }
  }
  // rep(i, n){
  //   rep(j, d)
  //     cout << ndp[i + 1][j] << ' ';
  //     cout << '\n';
  // }
  int res = 0;
  for(int i = 0; i < n; ++i){
    for(int nxt = 0; nxt < d; ++nxt){
      for(int last = 0; last < d; ++last){
        ckmax(ans[i + 1][(nxt + last) % d],
          ans[i][last] + ndp[i + 1][nxt]);
      }
    }
  }
  cout << ans[n][0] - ans[n][0] % d;

}

int main()
{
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
    Red;
    int T = 1;
    // cin >> T;
    for(int i = 1; i <= T; ++i){
      solve();
    }
    return 0;

}


#include <bits/stdc++.h>
using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)
#define setp(x) fixed << setprecision(x)
#define ordered_set tree<pair<long double, int> , null_type,less<pair<long double, int> >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const ll INF = ll(1e16);
const int mod = inf + 7;
const double PI = acos(-1.0);
void mul(ll &x, ll y){
  x *= y;
  if(x >= mod) x %= mod;
}
ll bp(ll a, ll n, ll cm){
  ll r = 1;
  while(n){
    if(n & 1) r = r * a % cm;
    a = a * a % cm;
    n >>= 1;
  }
  return r;
}
template<typename T_vector> // neal
void output_vector(const T_vector &v, bool add_one = false, int start = -1, int end = -1) {
    if (start < 0) start = 0;
    if (end < 0) end = int(v.size());

    for (int i = start; i < end; i++)
        cout << v[i] + (add_one ? 1 : 0) << (i < end - 1 ? ' ' : '\n');
}
const int S = 4901;
int dp[71][S + 10];
int ndp[71][71];
int ans[71][71];
void solve(){
  int n, m, d;
  cin >> n >> m >> d;
  int a[n + 1][m + 1];
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
      cin >> a[i][j];
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j < d; ++j){
      ndp[i][j] = -inf;
      ans[i][j] = -inf;
    }
  }
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j <= m; ++j)
      for(int k = 0; k <= S; ++k)
        dp[j][k] = inf;
    dp[0][0] = 0;
    for(int j = 1; j <= m; ++j){
      for(int k = 0; k <= S; ++k){
        dp[j][k] = dp[j - 1][k];
        if(k >= a[i][j])
          dp[j][k] = min(dp[j - 1][k - a[i][j]] + 1, dp[j][k]);
        if(dp[j][k] <= m / 2)
          ndp[i][k % d] = max(ndp[i][k % d], k);
      }
    }
  }
  // rep(i, n){
  //   rep(j, d)
  //     cout << ndp[i + 1][j] << ' ';
  //     cout << '\n';
  // }
  int res = 0;
  ans[0][0] = 0;
  for(int i = 0; i < n; ++i){
    for(int nxt = 0; nxt < d; ++nxt){
      for(int last = 0; last < d; ++last){
        if(~ndp[i + 1][nxt] and (i == 0 and last == 0 or ans[i][nxt]))
          ckmax(ans[i + 1][(nxt + last) % d],
            ans[i][last] + ndp[i + 1][nxt]);
      }
    }
  }
  cout << max(0, ans[n][0] - ans[n][0] % d);

}

int main()
{
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
    Red;
    int T = 1;
    // cin >> T;
    for(int i = 1; i <= T; ++i){
      solve();
    }
    return 0;

}


#include <bits/stdc++.h>
using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)
#define setp(x) fixed << setprecision(x)
#define ordered_set tree<pair<long double, int> , null_type,less<pair<long double, int> >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const ll INF = ll(1e16);
const int mod = inf + 7;
const double PI = acos(-1.0);
void mul(ll &x, ll y){
  x *= y;
  if(x >= mod) x %= mod;
}
ll bp(ll a, ll n, ll cm){
  ll r = 1;
  while(n){
    if(n & 1) r = r * a % cm;
    a = a * a % cm;
    n >>= 1;
  }
  return r;
}
template<typename T_vector> // neal
void output_vector(const T_vector &v, bool add_one = false, int start = -1, int end = -1) {
    if (start < 0) start = 0;
    if (end < 0) end = int(v.size());

    for (int i = start; i < end; i++)
        cout << v[i] + (add_one ? 1 : 0) << (i < end - 1 ? ' ' : '\n');
}
const int S = 4901;
int dp[71][S + 10];
int ndp[71][71];
int ans[71][71];
void solve(){
  int n, m, d;
  cin >> n >> m >> d;
  int a[n + 1][m + 1];
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
      cin >> a[i][j];
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j <= m; ++j)
      for(int k = 0; k <= S; ++k)
        dp[j][k] = inf;
    dp[0][0] = 0;
    for(int j = 1; j <= m; ++j){
      for(int k = 0; k <= S; ++k){
        dp[j][k] = dp[j - 1][k];
        if(k >= a[i][j])
          dp[j][k] = min(dp[j - 1][k - a[i][j]] + 1, dp[j][k]);
        if(dp[j][k] <= m / 2)
          ndp[i][k % d] = max(ndp[i][k % d], k);
      }
    }
  }
  int res = 0;
  for(int i = 1; i <= n; ++i){
    for(int last = 0; last < d; ++last){
      for(int nxt = 0; nxt < d; ++nxt){
        ans[i][nxt] = max(ans[i][nxt],
          ans[i - 1][last] + ndp[i][(nxt - last + d) % d]);
        ans[i][nxt] = max(ans[i][nxt], ans[i - 1][nxt]);
      }
    }
  }
  cout << ans[n][0] - 1;

}

int main()
{
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
    Red;
    int T = 1;
    // cin >> T;
    for(int i = 1; i <= T; ++i){
      solve();
    }
    return 0;

}


#include <bits/stdc++.h>
using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)
#define setp(x) fixed << setprecision(x)
#define ordered_set tree<pair<long double, int> , null_type,less<pair<long double, int> >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const ll INF = ll(1e16);
const int mod = inf + 7;
const double PI = acos(-1.0);
void mul(ll &x, ll y){
  x *= y;
  if(x >= mod) x %= mod;
}
ll bp(ll a, ll n, ll cm){
  ll r = 1;
  while(n){
    if(n & 1) r = r * a % cm;
    a = a * a % cm;
    n >>= 1;
  }
  return r;
}
template<typename T_vector> // neal
void output_vector(const T_vector &v, bool add_one = false, int start = -1, int end = -1) {
    if (start < 0) start = 0;
    if (end < 0) end = int(v.size());

    for (int i = start; i < end; i++)
        cout << v[i] + (add_one ? 1 : 0) << (i < end - 1 ? ' ' : '\n');
}
const int S = 4901;
int dp[71][S + 10];
int ndp[71][71];
int ans[71][71];
void solve(){
  int n, m, d;
  cin >> n >> m >> d;
  int a[n + 1][m + 1];
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
      cin >> a[i][j];
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j < d; ++j){
      ndp[i][j] = -inf;
      ans[i][j] = -inf;
    }
  }
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j <= m; ++j)
      for(int k = 0; k <= S; ++k)
        dp[j][k] = inf;
    dp[0][0] = 0;
    for(int j = 1; j <= m; ++j){
      for(int k = 0; k <= S; ++k){
        dp[j][k] = dp[j - 1][k];
        if(k >= a[i][j])
          dp[j][k] = min(dp[j - 1][k - a[i][j]] + 1, dp[j][k]);
        if(dp[j][k] <= m / 2)
          ndp[i][k % d] = max(ndp[i][k % d], k);
      }
    }
  }
  // rep(i, n){
  //   rep(j, d)
  //     cout << ndp[i + 1][j] << ' ';
  //     cout << '\n';
  // }
  int res = 0;
  ans[0][0] = 0;
  for(int i = 0; i < n; ++i){
    for(int nxt = 0; nxt < d; ++nxt){
      for(int last = 0; last < d; ++last){
        if(~ndp[i + 1][nxt] and (i == 0 and last == 0 or ans[i][nxt]))
          ckmax(ans[i + 1][(nxt + last) % d],
            ans[i][last] + ndp[i + 1][nxt]);
      }
    }
  }
  cout << ans[n][0] - ans[n][0] % d;

}

int main()
{
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
    Red;
    int T = 1;
    // cin >> T;
    for(int i = 1; i <= T; ++i){
      solve();
    }
    return 0;

}


#include <bits/stdc++.h>
using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)
#define setp(x) fixed << setprecision(x)
#define ordered_set tree<pair<long double, int> , null_type,less<pair<long double, int> >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const ll INF = ll(1e16);
const int mod = inf + 7;
const double PI = acos(-1.0);
void mul(ll &x, ll y){
  x *= y;
  if(x >= mod) x %= mod;
}
ll bp(ll a, ll n, ll cm){
  ll r = 1;
  while(n){
    if(n & 1) r = r * a % cm;
    a = a * a % cm;
    n >>= 1;
  }
  return r;
}
template<typename T_vector> // neal
void output_vector(const T_vector &v, bool add_one = false, int start = -1, int end = -1) {
    if (start < 0) start = 0;
    if (end < 0) end = int(v.size());

    for (int i = start; i < end; i++)
        cout << v[i] + (add_one ? 1 : 0) << (i < end - 1 ? ' ' : '\n');
}
const int S = 4901;
int dp[71][S + 10];
int ndp[71][71];
int ans[71][71];
void solve(){
  int n, m, d;
  cin >> n >> m >> d;
  int a[n + 1][m + 1];
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
      cin >> a[i][j];
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j < d; ++j){
      ndp[i][j] = -inf;
    }
  }
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j <= m; ++j)
      for(int k = 0; k <= S; ++k)
        dp[j][k] = inf;
    dp[0][0] = 0;
    for(int j = 1; j <= m; ++j){
      for(int k = 0; k <= S; ++k){
        dp[j][k] = dp[j - 1][k];
        if(k >= a[i][j])
          dp[j][k] = min(dp[j - 1][k - a[i][j]] + 1, dp[j][k]);
        if(dp[j][k] <= m / 2)
          ndp[i][k % d] = max(ndp[i][k % d], k);
      }
    }
  }
  // rep(i, n){
  //   rep(j, d)
  //     cout << ndp[i + 1][j] << ' ';
  //     cout << '\n';
  // }
  int res = 0;
  ans[0][0] = 1;
  for(int i = 0; i < n; ++i){
    for(int nxt = 0; nxt < d; ++nxt){
      for(int last = 0; last < d; ++last){
        if(~ndp[i + 1][nxt] and ans[i][last])
          ckmax(ans[i + 1][(nxt + last) % d],
            ans[i][last] + ndp[i + 1][nxt]);
      }
    }
  }
  cout << ans[n][0] - ans[n][0] % d;

}

int main()
{
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
    Red;
    int T = 1;
    // cin >> T;
    for(int i = 1; i <= T; ++i){
      solve();
    }
    return 0;

}


#include <bits/stdc++.h>
using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)
#define setp(x) fixed << setprecision(x)
#define ordered_set tree<pair<long double, int> , null_type,less<pair<long double, int> >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const ll INF = ll(1e16);
const int mod = inf + 7;
const double PI = acos(-1.0);
void mul(ll &x, ll y){
  x *= y;
  if(x >= mod) x %= mod;
}
ll bp(ll a, ll n, ll cm){
  ll r = 1;
  while(n){
    if(n & 1) r = r * a % cm;
    a = a * a % cm;
    n >>= 1;
  }
  return r;
}
template<typename T_vector> // neal
void output_vector(const T_vector &v, bool add_one = false, int start = -1, int end = -1) {
    if (start < 0) start = 0;
    if (end < 0) end = int(v.size());

    for (int i = start; i < end; i++)
        cout << v[i] + (add_one ? 1 : 0) << (i < end - 1 ? ' ' : '\n');
}
const int S = 4901;
int dp[71][S + 10];
int ndp[71][71];
int ans[71][71];
void solve(){
  int n, m, d;
  cin >> n >> m >> d;
  int a[n + 1][m + 1];
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
      cin >> a[i][j];
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j <= m; ++j)
      for(int k = 0; k <= S; ++k)
        dp[j][k] = inf;
    dp[0][0] = 0;
    for(int j = 1; j <= m; ++j){
      for(int k = 0; k <= S; ++k){
        dp[j][k] = dp[j - 1][k];
        if(k >= a[i][j])
          dp[j][k] = min(dp[j - 1][k - a[i][j]] + 1, dp[j][k]);
        if(dp[j][k] <= m / 2)
          ndp[i][k % d] = max(ndp[i][k % d], k);
      }
    }
  }
  int res = 0;
  for(int i = 1; i <= n; ++i){
    for(int last = 0; last < d; ++last){
      for(int nxt = 0; nxt < d; ++nxt){
        ans[i][nxt] = max(ans[i][nxt],
          ans[i - 1][last] + ndp[i][(nxt - last + d) % d]);
      }
    }
  }
  cout << ans[n][0] - 1;

}

int main()
{
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
    Red;
    int T = 1;
    // cin >> T;
    for(int i = 1; i <= T; ++i){
      solve();
    }
    return 0;

}


#include <bits/stdc++.h>
using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)
#define setp(x) fixed << setprecision(x)
#define ordered_set tree<pair<long double, int> , null_type,less<pair<long double, int> >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const ll INF = ll(1e16);
const int mod = inf + 7;
const double PI = acos(-1.0);
void mul(ll &x, ll y){
  x *= y;
  if(x >= mod) x %= mod;
}
ll bp(ll a, ll n, ll cm){
  ll r = 1;
  while(n){
    if(n & 1) r = r * a % cm;
    a = a * a % cm;
    n >>= 1;
  }
  return r;
}
template<typename T_vector> // neal
void output_vector(const T_vector &v, bool add_one = false, int start = -1, int end = -1) {
    if (start < 0) start = 0;
    if (end < 0) end = int(v.size());

    for (int i = start; i < end; i++)
        cout << v[i] + (add_one ? 1 : 0) << (i < end - 1 ? ' ' : '\n');
}
const int S = 4901;
int dp[71][S + 10];
int ndp[71][71];
int ans[71][71];
void solve(){
  int n, m, d;
  cin >> n >> m >> d;
  int a[n + 1][m + 1];
  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
      cin >> a[i][j];
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j < d; ++j){
      ndp[i][j] = -inf;
      ans[i][j] = -inf;
    }
  }
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j <= m; ++j)
      for(int k = 0; k <= S; ++k)
        dp[j][k] = inf;
    dp[0][0] = 0;
    for(int j = 1; j <= m; ++j){
      for(int k = 0; k <= S; ++k){
        dp[j][k] = dp[j - 1][k];
        if(k >= a[i][j])
          dp[j][k] = min(dp[j - 1][k - a[i][j]] + 1, dp[j][k]);
        if(dp[j][k] <= m / 2)
          ndp[i][k % d] = max(ndp[i][k % d], k);
      }
    }
  }
  // rep(i, n){
  //   rep(j, d)
  //     cout << ndp[i + 1][j] << ' ';
  //     cout << '\n';
  // }
  int res = 0;
  ans[0][0] = 0;
  for(int i = 0; i < n; ++i){
    for(int nxt = 0; nxt < d; ++nxt){
      for(int last = 0; last < d; ++last){
        if(~ndp[i + 1][nxt] and (last == 0 or ans[i][last]))
          ckmax(ans[i + 1][(nxt + last) % d],
            ans[i][last] + ndp[i + 1][nxt]);
      }
    }
  }
  cout << max(0, ans[n][0] - ans[n][0] % d);

}

int main()
{
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
    Red;
    int T = 1;
    // cin >> T;
    for(int i = 1; i <= T; ++i){
      solve();
    }
    return 0;

}


#include <bits/stdc++.h>

using namespace std;

const int N = 5001;
const int K = 79;
const short inf = 1e4;

int n, m, k;
int a[ N ][ N ];
short remain[ K ][ K ], ans[ N ][ N ];

void init_knap(int x) {
	vector<vector<short>> knap(m + 1, vector<short>(N, -inf));
	knap[ 0 ][ 0 ] = 0;
	for(int i = 0; i < m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || j + a[ x ][ i ] >= N) continue;
			knap[ i + 1 ][ j + a[ x ][ i ] ] = knap[ i ][ j ] + 1;
		}
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf) continue;
			if(knap[ i + 1 ][ j ] == -inf)
				knap[ i + 1 ][ j ] = knap[ i ][ j ];
			knap[ i + 1 ][ j ] = min(knap[ i + 1 ][ j ], knap[ i ][ j ]);
		}
	}

	for(int i = 0; i <= m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || knap[ i ][ j ] > m / 2) continue;
			int y = j % k;
			remain[ x ][ y ] = max(remain[ x ][ y ], (short)j);
		}
	}
}

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			scanf("%d", &a[ i ][ j ]);
		}
	}

	for(int i = 0; i < n; i++) {
		init_knap(i);
	}

	ans[ 0 ][ 0 ] = 1;
	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N; sm++) {
			if(!ans[ i ][ sm ]) continue;
			for(int rem = 0; rem < k; rem++) {
				int lol = sm + remain[ i ][ rem ];
				if(lol < N)
					ans[ i + 1 ][ lol ] = 1;
			}
		}

		for(int sm = 0; sm < N; sm++) {
			if(!ans[ i ][ sm ]) continue;
			ans[ i + 1 ][ sm ] = 1;
		}
	}

	int res = 0;
	for(int i = 0; i <= n; i++) {
		for(int j = 0; j < N; j++) {
			if(!ans[ i ][ j ] || j % k) continue;
			res = max(res, j);
		}
	}
	printf("%d\n", res);
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5001;
const int K = 72;
const short inf = 1e4;

int n, m, k;
int a[ N ][ N ];
short remain[ K ][ K ];
char ans[ K ][ (int)N * K ];

void init_knap(int x) {
	vector<vector<short>> knap(m + 1, vector<short>(N, -inf));
	knap[ 0 ][ 0 ] = 0;
	for(int i = 0; i < m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || j + a[ x ][ i ] >= N) continue;
			knap[ i + 1 ][ j + a[ x ][ i ] ] = knap[ i ][ j ] + 1;
		}
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf) continue;
			if(knap[ i + 1 ][ j ] == -inf)
				knap[ i + 1 ][ j ] = knap[ i ][ j ];
			knap[ i + 1 ][ j ] = min(knap[ i + 1 ][ j ], knap[ i ][ j ]);
		}
	}

	for(int i = 0; i <= m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || knap[ i ][ j ] > m / 2) continue;
			int y = j % k;
			remain[ x ][ y ] = max(remain[ x ][ y ], (short)j);
		}
	}
}

int main() {
	// scanf("%d%d%d", &n, &m, &k);
	cin >> n >> m >> k;
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			// scanf("%d", &a[ i ][ j ]);
			cin >> a[ i ][ j ];
		}
	}

	for(int i = 0; i < n; i++) {
		init_knap(i);
	}

	// for(int i = 0; i < n; i++) {
	// 	for(int j = 0; j < k; j++) {
	// 		cout << remain[ i ][ j ] << endl;
	// 	}
	// }

	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N * K; sm++) {
			ans[ i ][ sm ] = 0;
		}
	}

	ans[ 0 ][ 0 ] = 1;
	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N * K; sm++) {
			if(!ans[ i ][ sm ]) continue;
			for(int rem = 0; rem < k; rem++) {
				int lol = sm + remain[ i ][ rem ];
				if(lol < N * K)
					ans[ i + 1 ][ lol ] = 1;
			}
		}

		for(int sm = 0; sm < N * K; sm++) {
			if(ans[ i ][ sm ] == 0) continue;
			ans[ i + 1 ][ sm ] = 1;
		}
	}

	int res = 0;
	for(int i = 0; i <= n; i++) {
		for(int j = 0; j < N * K; j++) {
			if(ans[ i ][ j ] == 0 || j % k) continue;
			res = max(res, (int)j);
		}
	}
	// printf("%d\n", res);
	cout << res << endl;
}


#include <bits/stdc++.h>

using namespace std;

const short N = 5001;
const short K = 72;
const short inf = 1e4;

int n, m, k;
int a[ N ][ N ];
short remain[ K ][ K ];
char ans[ K ][ (int)N * K ];

void init_knap(short x) {
	vector<vector<short>> knap(m + 1, vector<short>(N, -inf));
	knap[ 0 ][ 0 ] = 0;
	for(short i = 0; i < m; i++) {
		for(short j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || j + a[ x ][ i ] >= N) continue;
			knap[ i + 1 ][ j + a[ x ][ i ] ] = knap[ i ][ j ] + 1;
		}
		for(short j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf) continue;
			if(knap[ i + 1 ][ j ] == -inf)
				knap[ i + 1 ][ j ] = knap[ i ][ j ];
			knap[ i + 1 ][ j ] = min(knap[ i + 1 ][ j ], knap[ i ][ j ]);
		}
	}

	for(short i = 0; i <= m; i++) {
		for(short j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || knap[ i ][ j ] > m / 2) continue;
			short y = j % k;
			remain[ x ][ y ] = max(remain[ x ][ y ], (short)j);
		}
	}
}

int main() {
	// scanf("%d%d%d", &n, &m, &k);
	cin >> n >> m >> k;
	for(short i = 0; i < n; i++) {
		for(short j = 0; j < m; j++) {
			// scanf("%d", &a[ i ][ j ]);
			cin >> a[ i ][ j ];
		}
	}

	for(short i = 0; i < n; i++) {
		init_knap(i);
	}

	for(short i = 0; i < n; i++) {
		for(int sm = 0; sm < N * K; sm++) {
			ans[ i ][ sm ] = 0;
		}
	}

	ans[ 0 ][ 0 ] = 1;
	for(short i = 0; i < n; i++) {
		for(int sm = 0; sm < N * K; sm++) {
			if(!ans[ i ][ sm ]) continue;
			for(short rem = 0; rem < k; rem++) {
				short lol = sm + remain[ i ][ rem ];
				if(lol < N)
					ans[ i + 1 ][ lol ] = 1;
			}
		}

		for(int sm = 0; sm < N * K; sm++) {
			if(ans[ i ][ sm ] == 0) continue;
			ans[ i + 1 ][ sm ] = 1;
		}
	}

	int res = 0;
	for(short i = 0; i <= n; i++) {
		for(int j = 0; j < N * K; j++) {
			if(ans[ i ][ j ] == 0 || j % k) continue;
			res = max(res, (int)j);
		}
	}
	// printf("%d\n", res);
	cout << res << endl;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5001;
const int K = 79;
const short inf = 1e4;

short n, m, k;
short a[ N ][ N ], remain[ K ][ K ], ans[ N ][ N ];

void init_knap(int x) {
	vector<vector<short>> knap(m + 1, vector<short>(N, -inf));
	knap[ 0 ][ 0 ] = 0;
	for(int i = 0; i < m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || j + a[ x ][ i ] >= N) continue;
			knap[ i + 1 ][ j + a[ x ][ i ] ] = knap[ i ][ j ] + 1;
		}
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf) continue;
			if(knap[ i + 1 ][ j ] == -inf)
				knap[ i + 1 ][ j ] = knap[ i ][ j ];
			knap[ i + 1 ][ j ] = min(knap[ i + 1 ][ j ], knap[ i ][ j ]);
		}
	}

	for(int i = 0; i <= m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || knap[ i ][ j ] > m / 2) continue;
			int y = j % k;
			remain[ x ][ y ] = max(remain[ x ][ y ], (short)j);
		}
	}
}

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			scanf("%d", &a[ i ][ j ]);
		}
	}

	for(int i = 0; i < n; i++) {
		init_knap(i);
	}

	ans[ 0 ][ 0 ] = 1;
	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N; sm++) {
			if(!ans[ i ][ sm ]) continue;
			for(int rem = 0; rem < k; rem++) {
				int lol = sm + remain[ i ][ rem ];
				if(lol < N)
					ans[ i + 1 ][ lol ] = 1;
			}
		}

		for(int sm = 0; sm < N; sm++) {
			if(!ans[ i ][ sm ]) continue;
			ans[ i + 1 ][ sm ] = 1;
		}
	}

	int res = 0;
	for(int i = 0; i <= n; i++) {
		for(int j = 0; j < N; j++) {
			if(!ans[ i ][ j ] || j % k) continue;
			res = max(res, j);
		}
	}
	printf("%d\n", res);
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5001;
const int K = 79;
const short inf = 1e4;

int n, m, k;
int a[ N ][ N ];
short remain[ K ][ K ];
char ans[ N ][ N * K ];

void init_knap(int x) {
	vector<vector<short>> knap(m + 1, vector<short>(N, -inf));
	knap[ 0 ][ 0 ] = 0;
	for(int i = 0; i < m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || j + a[ x ][ i ] >= N) continue;
			knap[ i + 1 ][ j + a[ x ][ i ] ] = knap[ i ][ j ] + 1;
		}
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf) continue;
			if(knap[ i + 1 ][ j ] == -inf)
				knap[ i + 1 ][ j ] = knap[ i ][ j ];
			knap[ i + 1 ][ j ] = min(knap[ i + 1 ][ j ], knap[ i ][ j ]);
		}
	}

	for(int i = 0; i <= m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || knap[ i ][ j ] > m / 2) continue;
			int y = j % k;
			remain[ x ][ y ] = max(remain[ x ][ y ], (short)j);
		}
	}
}

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			scanf("%d", &a[ i ][ j ]);
		}
	}

	for(int i = 0; i < n; i++) {
		init_knap(i);
	}

	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N * K; sm++) {
			ans[ i ][ sm ] = 0;
		}
	}

	ans[ 0 ][ 0 ] = 1;
	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N * K; sm++) {
			if(!ans[ i ][ sm ]) continue;
			for(int rem = 0; rem < k; rem++) {
				int lol = sm + remain[ i ][ rem ];
				if(lol < N)
					ans[ i + 1 ][ lol ] = 1;
			}
		}

		for(int sm = 0; sm < N * K; sm++) {
			if(ans[ i ][ sm ] == 0) continue;
			ans[ i + 1 ][ sm ] = 1;
		}
	}

	int res = 0;
	for(int i = 0; i <= n; i++) {
		for(int j = 0; j < N * K; j++) {
			if(ans[ i ][ j ] == 0 || j % k) continue;
			res = max(res, j);
		}
	}
	printf("%d\n", res);
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5999;
const int K = 79;
const int inf = 1e9;

int n, m, k;
int a[ N ][ N ], remain[ K ][ K ], ans[ N ][ N ];

void init_knap(int x) {
	vector<vector<int>> knap(m + 1, vector<int>(N, -inf));
	knap[ 0 ][ 0 ] = 0;
	for(int i = 0; i < m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || j + a[ x ][ i ] >= N) continue;
			knap[ i + 1 ][ j + a[ x ][ i ] ] = knap[ i ][ j ] + 1;
		}
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf) continue;
			if(knap[ i + 1 ][ j ] == -inf)
				knap[ i + 1 ][ j ] = knap[ i ][ j ];
			knap[ i + 1 ][ j ] = min(knap[ i + 1 ][ j ], knap[ i ][ j ]);
		}
	}

	for(int i = 0; i <= m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || knap[ i ][ j ] > m / 2) continue;
			int y = j % k;
			remain[ x ][ y ] = max(remain[ x ][ y ], j);
		}
	}
}

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			scanf("%d", &a[ i ][ j ]);
		}
	}

	for(int i = 0; i < n; i++) {
		init_knap(i);
	}

	ans[ 0 ][ 0 ] = 1;
	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N; sm++) {
			if(!ans[ i ][ sm ]) continue;
			for(int rem = 0; rem < k; rem++) {
				int lol = sm + remain[ i ][ rem ];
				if(lol < N)
					ans[ i + 1 ][ lol ] = 1;
			}
		}

		for(int sm = 0; sm < N; sm++) {
			if(!ans[ i ][ sm ]) continue;
			ans[ i + 1 ][ sm ] = 1;
		}
	}

	int res = 0;
	for(int i = 0; i <= n; i++) {
		for(int j = 0; j < N; j++) {
			if(!ans[ i ][ j ] || j % k) continue;
			res = max(res, j);
		}
	}
	printf("%d\n", res);
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5001;
const int K = 79;
const int inf = 1e5;

short n, m, k;
short a[ N ][ N ], remain[ K ][ K ], ans[ N ][ N ];

void init_knap(int x) {
	vector<vector<int>> knap(m + 1, vector<int>(N, -inf));
	knap[ 0 ][ 0 ] = 0;
	for(int i = 0; i < m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || j + a[ x ][ i ] >= N) continue;
			knap[ i + 1 ][ j + a[ x ][ i ] ] = knap[ i ][ j ] + 1;
		}
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf) continue;
			if(knap[ i + 1 ][ j ] == -inf)
				knap[ i + 1 ][ j ] = knap[ i ][ j ];
			knap[ i + 1 ][ j ] = min(knap[ i + 1 ][ j ], knap[ i ][ j ]);
		}
	}

	for(int i = 0; i <= m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || knap[ i ][ j ] > m / 2) continue;
			int y = j % k;
			remain[ x ][ y ] = max(remain[ x ][ y ], (short)j);
		}
	}
}

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			scanf("%d", &a[ i ][ j ]);
		}
	}

	for(int i = 0; i < n; i++) {
		init_knap(i);
	}

	ans[ 0 ][ 0 ] = 1;
	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N; sm++) {
			if(!ans[ i ][ sm ]) continue;
			for(int rem = 0; rem < k; rem++) {
				int lol = sm + remain[ i ][ rem ];
				if(lol < N)
					ans[ i + 1 ][ lol ] = 1;
			}
		}

		for(int sm = 0; sm < N; sm++) {
			if(!ans[ i ][ sm ]) continue;
			ans[ i + 1 ][ sm ] = 1;
		}
	}

	int res = 0;
	for(int i = 0; i <= n; i++) {
		for(int j = 0; j < N; j++) {
			if(!ans[ i ][ j ] || j % k) continue;
			res = max(res, j);
		}
	}
	printf("%d\n", res);
}


#include <bits/stdc++.h>

using namespace std;

const int N = 5001;
const int K = 72;
const short inf = 1e4;

int n, m, k;
int a[ N ][ N ];
short remain[ K ][ K ];
char ans[ K ][ (int)N * K ];

void init_knap(int x) {
	vector<vector<short>> knap(m + 1, vector<short>(N, -inf));
	knap[ 0 ][ 0 ] = 0;
	for(int i = 0; i < m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || j + a[ x ][ i ] >= N) continue;
			knap[ i + 1 ][ j + a[ x ][ i ] ] = knap[ i ][ j ] + 1;
		}
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf) continue;
			if(knap[ i + 1 ][ j ] == -inf)
				knap[ i + 1 ][ j ] = knap[ i ][ j ];
			knap[ i + 1 ][ j ] = min(knap[ i + 1 ][ j ], knap[ i ][ j ]);
		}
	}

	for(int i = 0; i <= m; i++) {
		for(int j = 0; j < N; j++) {
			if(knap[ i ][ j ] == -inf || knap[ i ][ j ] > m / 2) continue;
			int y = j % k;
			remain[ x ][ y ] = max(remain[ x ][ y ], (short)j);
		}
	}
}

int main() {
	// scanf("%d%d%d", &n, &m, &k);
	cin >> n >> m >> k;
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			// scanf("%d", &a[ i ][ j ]);
			cin >> a[ i ][ j ];
		}
	}

	for(int i = 0; i < n; i++) {
		init_knap(i);
	}

	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N * K; sm++) {
			ans[ i ][ sm ] = 0;
		}
	}

	ans[ 0 ][ 0 ] = 1;
	for(int i = 0; i < n; i++) {
		for(int sm = 0; sm < N * K; sm++) {
			if(!ans[ i ][ sm ]) continue;
			for(int rem = 0; rem < k; rem++) {
				int lol = sm + remain[ i ][ rem ];
				if(lol < N)
					ans[ i + 1 ][ lol ] = 1;
			}
		}

		for(int sm = 0; sm < N * K; sm++) {
			if(ans[ i ][ sm ] == 0) continue;
			ans[ i + 1 ][ sm ] = 1;
		}
	}

	int res = 0;
	for(int i = 0; i <= n; i++) {
		for(int j = 0; j < N * K; j++) {
			if(ans[ i ][ j ] == 0 || j % k) continue;
			res = max(res, (int)j);
		}
	}
	// printf("%d\n", res);
	cout << res << endl;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[70][70][35];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

    // db(ans);
      if(ans%k == 0){
        // db(ans);

        fin = max(fin , ans);

        // return ans;
      }

    if(r == n){

      return 0;
    }

    if(c == m || !rowcnt){

      return func(r + 1 , 0  , m/2  , ans);

    }

    int ans1 =   func(r , c + 1 , rowcnt - 1 , ans + arr[r][c] );

    int ov = 0;
      ov = ans1;

    // if(ans%k == 0){

    // }

    ans1 = func(r , c + 1 , rowcnt , ans);

      ov = max(ov  ,ans1);
    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    ans = func(0 , 0 , m/2 , 0);

    cout<<fin<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[71][71][36][70];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

      if(rowcnt < 0){
        return INT_MIN;
      }

    if(dp[r][c][rowcnt][ans] != -1)return dp[r][c][rowcnt][ans];

    if(r == n){
        if(ans%k == 0)return 0;

      return INT_MIN;
    }

    if(c == m  ){
        // if(rowcnt >=0)
      return func(r + 1 , 0  ,m/2 , ans);

    }

    int ans1 =   func(r , c + 1 , rowcnt - 1 , (ans%k + arr[r][c]%k)%k );
    int ov = INT_MIN;

    if(ans1 != INT_MIN){

        ov = ans1 + arr[r][c];
    }

    ans1 = func(r , c + 1 , rowcnt , ans);

    if(ans1 != INT_MIN){
      ov = max(ov  ,ans1);

    }

    dp[r][c][rowcnt][ans] = ov;

    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    fill(dp , -1);

    ans = func(0 , 0 , m/2 , 0);

    cout<<ans<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[70][70][35][70];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

    if(dp[r][c][rowcnt][ans] != -1)return dp[r][c][rowcnt][ans];

    if(r == n){
        if(ans == 0)return 0;

      return INT_MIN;
    }

    if(c == m || !rowcnt){

      return func(r + 1 , 0  , m/2  , ans);

    }

    int ans1 =   func(r , c + 1 , rowcnt - 1 , (ans%k + arr[r][c]%k)%k );
    int ov = 0;

    if(ans1 != INT_MIN){

        ov = ans1 + arr[r][c];
    }

    ans1 = func(r , c + 1 , rowcnt , ans);

    if(ans1 != INT_MIN){
      ov = max(ov  ,ans1);

    }

    dp[r][c][rowcnt][ans] = ov;

    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    fill(dp , -1);

    ans = func(0 , 0 , m/2 , 0);

    cout<<ans<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[7][71][35][70];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

    if(dp[r][c][rowcnt][ans] != -1)return dp[r][c][rowcnt][ans];

    if(r == n){
        if(ans == 0)return 0;

      return INT_MIN;
    }

    if(c == m || !rowcnt){

      return func(r + 1 , 0  , m/2  , ans);

    }

    int ans1 =   func(r , c + 1 , rowcnt - 1 , (ans%k + arr[r][c]%k)%k );
    int ov = 0;

    if(ans1 != INT_MIN){

        ov = ans1 + arr[r][c];
    }

    ans1 = func(r , c + 1 , rowcnt , ans);

    if(ans1 != INT_MIN){
      ov = max(ov  ,ans1);

    }

    dp[r][c][rowcnt][ans] = ov;

    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    fill(dp , -1);

    ans = func(0 , 0 , m/2 , 0);

    cout<<ans<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[71][71][36][70];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

      if(rowcnt > (int)m/2){
        return INT_MIN;
      }

    if(dp[r][c][rowcnt][ans] != -1)return dp[r][c][rowcnt][ans];

    if(r == n){
        if(ans%k == 0)return 0;

      return INT_MIN;
    }

    if(c == m  ){
        // if(rowcnt >=0)
      return func(r + 1 , 0  ,0 , ans);

    }

    int ans1 =   func(r , c + 1 , rowcnt + 1 , (ans%k + arr[r][c]%k)%k );
    int ov = INT_MIN;

    if(ans1 != INT_MIN){

        ov = ans1 + arr[r][c];
    }

    ans1 = func(r , c + 1 , rowcnt , ans);

    if(ans1 != INT_MIN){
      ov = max(ov  ,ans1);

    }

    dp[r][c][rowcnt][ans] = ov;

    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    fill(dp , -1);

    ans = func(0 , 0 , 0 , 0);

    cout<<ans<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[7][71][35][70];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

      if(rowcnt > (int)m/2){
        return INT_MIN;
      }

    if(dp[r][c][rowcnt][ans] != -1)return dp[r][c][rowcnt][ans];

    if(r == n){
        if(ans%k == 0)return 0;

      return INT_MIN;
    }

    if(c == m  ){
        // if(rowcnt >=0)
      return func(r + 1 , 0  ,0 , ans);

    }

    int ans1 =   func(r , c + 1 , rowcnt + 1 , (ans%k + arr[r][c]%k)%k );
    int ov = INT_MIN;

    if(ans1 != INT_MIN){

        ov = ans1 + arr[r][c];
    }

    ans1 = func(r , c + 1 , rowcnt , ans);

    if(ans1 != INT_MIN){
      ov = max(ov  ,ans1);

    }

    dp[r][c][rowcnt][ans] = ov;

    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    fill(dp , -1);

    ans = func(0 , 0 , 0 , 0);

    cout<<ans<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[71][71][40][70];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

    if(dp[r][c][rowcnt][ans] != -1)return dp[r][c][rowcnt][ans];

    if(r == n){
        if(ans%k == 0)return 0;

      return INT_MIN;
    }

    if(c == m  ){
        if(rowcnt >=0)
      return func(r + 1 , 0  , m/2  , ans);

  else{
    return INT_MIN;
  }

    }

    int ans1 =   func(r , c + 1 , rowcnt - 1 , (ans%k + arr[r][c]%k)%k );
    int ov = 0;

    if(ans1 != INT_MIN){

        ov = ans1 + arr[r][c];
    }

    ans1 = func(r , c + 1 , rowcnt , ans);

    if(ans1 != INT_MIN){
      ov = max(ov  ,ans1);

    }

    dp[r][c][rowcnt][ans] = ov;

    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    fill(dp , -1);

    ans = func(0 , 0 , (int)(m/2) , 0);

    cout<<ans<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[7][71][35][70];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

    if(dp[r][c][rowcnt][ans] != -1)return dp[r][c][rowcnt][ans];

    if(r == n){
        if(ans%k == 0)return 0;

      return INT_MIN;
    }

    if(c == m  ){
        if(rowcnt >=0)
      return func(r + 1 , 0  , m/2  , ans);

  else{
    return INT_MIN;
  }

    }

    int ans1 =   func(r , c + 1 , rowcnt - 1 , (ans%k + arr[r][c]%k)%k );
    int ov = 0;

    if(ans1 != INT_MIN){

        ov = ans1 + arr[r][c];
    }

    ans1 = func(r , c + 1 , rowcnt , ans);

    if(ans1 != INT_MIN){
      ov = max(ov  ,ans1);

    }

    dp[r][c][rowcnt][ans] = ov;

    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    fill(dp , -1);

    ans = func(0 , 0 , (int)(m/2) , 0);

    cout<<ans<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


// Created by Kshitij Anand NSIT
#include <bits/stdc++.h>
//#include <ext/numeric>
//using namespace __gnu_cxx;

using namespace std;

#define int long long
#define pb push_back
#define P pair<int,int>
#define F first
#define S second
#define vi vector<int>
#define vc vector<char>
#define vb vector<bool>
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define mp(a, b) make_pair(a, b)
#define min3(a, b, c) min(min(a, b), c)
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max3(a, b, c) max(max(a, b), c)
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define fill(arr,val) memset(arr,val,sizeof(arr))
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define db(x)  cout<<#x<<" : "<<x<<endl

const int N = 1000000007;

int n , m,  k;

int arr[70][70];

int dp[71][71][35][70];

int fin = 0;

int func(int r , int c , int rowcnt , int ans ){

      if(rowcnt > (int)m/2){
        return INT_MIN;
      }

    if(dp[r][c][rowcnt][ans] != -1)return dp[r][c][rowcnt][ans];

    if(r == n){
        if(ans%k == 0)return 0;

      return INT_MIN;
    }

    if(c == m  ){
        // if(rowcnt >=0)
      return func(r + 1 , 0  ,0 , ans);

    }

    int ans1 =   func(r , c + 1 , rowcnt + 1 , (ans%k + arr[r][c]%k)%k );
    int ov = INT_MIN;

    if(ans1 != INT_MIN){

        ov = ans1 + arr[r][c];
    }

    ans1 = func(r , c + 1 , rowcnt , ans);

    if(ans1 != INT_MIN){
      ov = max(ov  ,ans1);

    }

    dp[r][c][rowcnt][ans] = ov;

    // if(ans%k == 0){

    // }

    return ov;

}

void solve(){

    int a,b,c, ans=0, count=0, sum=0;
    cin>>n>>m>>k;

    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
        cin>>arr[i][j];
      }
    }

    fill(dp , -1);

    ans = func(0 , 0 , 0 , 0);

    cout<<ans<<endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

  //  int t; cin>>t; while(t--)
    {
      solve();
    }

  return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    int dp[75][75][75][75],a[n][m];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<75;i++)
        for(int j=0;j<75;j++)
            for(int cnt=0;cnt<75;cnt++)
                for(int rem=0;rem<75;rem++) dp[i][j][cnt][rem]=(-1);
    dp[0][0][0][0]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            for(int cnt=0;cnt<=m/2;cnt++)
                for(int rem=0;rem<k;rem++)
                {
                    if(dp[i][j][cnt][rem]<0)    continue;
                    int ni=(j==m-1?i+1:i);
                    int nj=(j==m-1?0:j+1);
                    if(ni!=i)
                    {
                        dp[ni][nj][0][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][0][rem]);
                    }
                    else
                    {
                        dp[ni][nj][cnt][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][cnt][rem]);
                    }
                    if(cnt+1<=m/2)
                    {
                        int nrem=(rem+a[i][j])%k;
                        if(ni!=i)
                        {
                            dp[ni][nj][0][nrem]=max(dp[ni][nj][0][rem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                        else
                        {
                            dp[ni][nj][cnt+1][rem]=max(dp[ni][nj][cnt+1][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                    }
                }
    cout<<max(0,dp[n][0][0][0]);
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    int dp[75][75][75][75],a[n][m];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<75;i++)
        for(int j=0;j<75;j++)
            for(int cnt=0;cnt<75;cnt++)
                for(int rem=0;rem<75;rem++) dp[i][j][cnt][rem]=(-1e9);
    dp[0][0][0][0]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            for(int cnt=0;cnt<=m/2;cnt++)
                for(int rem=0;rem<k;rem++)
                {
                    if(dp[i][j][cnt][rem]<0)    continue;
                    int ni=(j==m-1?i+1:i);
                    int nj=(j==m-1?0:j+1);
                    if(ni!=i)
                    {
                        dp[ni][nj][0][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][0][rem]);
                    }
                    else
                    {
                        dp[ni][nj][cnt][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][cnt][rem]);
                    }
                    if(cnt+1<=m/2)
                    {
                        int nrem=(rem+a[i][j])%k;
                        if(ni!=i)
                        {
                            dp[ni][nj][0][nrem]=max(dp[ni][nj][0][rem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                        else
                        {
                            dp[ni][nj][cnt+1][rem]=max(dp[ni][nj][cnt+1][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                    }
                }
    if(dp[n][0][0][0]<0)    cout<<0;
    else    cout<<(dp[n][0][0][0]);
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    int dp[75][75][75][75],a[n][m];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<75;i++)
        for(int j=0;j<75;j++)
            for(int cnt=0;cnt<75;cnt++)
                for(int rem=0;rem<75;rem++) dp[i][j][cnt][rem]=(-1);
    dp[0][0][0][0]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            for(int cnt=0;cnt<=m/2;cnt++)
                for(int rem=0;rem<k;rem++)
                {
                    if(dp[i][j][cnt][rem]<0)    continue;
                    int ni=(j==m-1?i+1:i);
                    int nj=(j==m-1?0:j+1);
                    if(ni!=i)
                    {
                        dp[ni][nj][0][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][0][rem]);
                    }
                    else
                    {
                        dp[ni][nj][cnt][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][cnt][rem]);
                    }
                    if(cnt+1<=m/2)
                    {
                        int nrem=(rem+a[i][j])%k;
                        if(ni!=i)
                        {
                            dp[ni][nj][0][nrem]=max(dp[ni][nj][0][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                        else
                        {
                            dp[ni][nj][cnt+1][rem]=max(dp[ni][nj][cnt+1][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                    }
                }
    if(dp[n][0][0][0]<0)    cout<<0;
    else    cout<<(dp[n][0][0][0]);
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    int dp[75][75][75][75],a[n][m];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<75;i++)
        for(int j=0;j<75;j++)
            for(int cnt=0;cnt<75;cnt++)
                for(int rem=0;rem<75;rem++) dp[i][j][cnt][rem]=(-1);
    dp[0][0][0][0]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            for(int cnt=0;cnt<=m/2;cnt++)
                for(int rem=0;rem<k;rem++)
                {
                    if(dp[i][j][cnt][rem]<0)    continue;
                    int ni=(j==m-1?i+1:i);
                    int nj=(j==m-1?0:j+1);
                    if(ni!=i)
                    {
                        dp[ni][nj][0][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][0][rem]);
                    }
                    else
                    {
                        dp[ni][nj][cnt][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][cnt][rem]);
                    }
                    if(cnt+1<=m/2)
                    {
                        int nrem=(rem+a[i][j])%k;
                        if(ni!=i)
                        {
                            dp[ni][nj][0][nrem]=max(dp[ni][nj][0][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                        else
                        {
                            dp[ni][nj][cnt+1][nrem]=max(dp[ni][nj][cnt+1][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                    }
                }
    if(dp[n][0][0][0]<0)    cout<<0;
    else    cout<<(dp[n][0][0][0]);
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    int dp[75][75][75][75],a[n][m];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<75;i++)
        for(int j=0;j<75;j++)
            for(int cnt=0;cnt<75;cnt++)
                for(int rem=0;rem<75;rem++) dp[i][j][cnt][rem]=(-1);
    dp[0][0][0][0]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            for(int cnt=0;cnt<=m/2;cnt++)
                for(int rem=0;rem<k;rem++)
                {
                    if(dp[i][j][cnt][rem]<0)    continue;
                    int ni=(j==m-1?i+1:i);
                    int nj=(j==m-1?0:j+1);
                    if(ni!=i)
                    {
                        dp[ni][nj][0][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][0][rem]);
                    }
                    else
                    {
                        dp[ni][nj][cnt][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][cnt][rem]);
                    }
                    if(cnt+1<=m/2)
                    {
                        int nrem=(rem+a[i][j])%k;
                        if(ni!=i)
                        {
                            dp[ni][nj][0][nrem]=max(dp[ni][nj][0][rem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                        else
                        {
                            dp[ni][nj][cnt+1][rem]=max(dp[ni][nj][cnt+1][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                    }
                }
    if(dp[n][0][0][0]<0)    cout<<0;
    else    cout<<(dp[n][0][0][0]-1);
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    int dp[75][75][75][75],a[n][m];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<75;i++)
        for(int j=0;j<75;j++)
            for(int cnt=0;cnt<75;cnt++)
                for(int rem=0;rem<75;rem++) dp[i][j][cnt][rem]=(-1);
    dp[0][0][0][0]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m)
            for(int cnt=0;cnt<=m/2;cnt++)
                for(int rem=0;rem<k;rem++)
                {
                    if(dp[i][j][cnt][rem]<0)    continue;
                    int ni=(j==m-1?i+1:i);
                    int nj=(j==m-1?0:j+1);
                    if(ni!=i)
                    {
                        dp[ni][nj][0][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][0][rem]);
                    }
                    else
                    {
                        dp[ni][nj][cnt][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][cnt][rem]);
                    }
                    if(cnt+1<=m/2)
                    {
                        int nrem=(rem+a[i][j])%k;
                        if(ni!=i)
                        {
                            dp[ni][nj][0][nrem]=max(dp[ni][nj][0][rem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                        else
                        {
                            dp[ni][nj][cnt+1][rem]=max(dp[ni][nj][cnt+1][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                    }
                }
    cout<<max(0,dp[n][0][0][0]);
}


#include<bits/stdc++.h>
using namespace std;
int main();
{
    int n,m,k;
    cin>>n>>m>>k;
    int dp[75][75][75][75],a[n][m];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<75;i++)
        for(int j=0;j<75;j++)
            for(int cnt=0;cnt<75;cnt++)
                for(int rem=0;rem<75;rem++) dp[i][j][cnt][rem]=(-1);
    dp[0][0][0][0]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m)
            for(int cnt=0;cnt<=m/2;cnt++)
                for(int rem=0;rem<k;rem++)
                {
                    if(dp[i][j][cnt][rem]<0)    continue;
                    int ni=(j==m-1?i+1:i);
                    int nj=(j==m-1?0:j+1);
                    if(ni!=i)
                    {
                        dp[ni][nj][0][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][0][rem]);
                    }
                    else
                    {
                        dp[ni][nj][cnt][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][cnt][rem]);
                    }
                    if(cnt+1<=m/2)
                    {
                        int nrem=(rem+a[i][j])%k;
                        if(ni!=i)
                        {
                            dp[ni][nj][0][nrem]=max(dp[ni][nj][0][rem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                        else
                        {
                            dp[ni][nj][cnt+1][rem]=max(dp[ni][nj][cnt+1][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                    }
                }
    cout<<max(0,dp[n][0][0][0]);
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    int dp[75][75][75][75],a[n][m];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<75;i++)
        for(int j=0;j<75;j++)
            for(int cnt=0;cnt<75;cnt++)
                for(int rem=0;rem<75;rem++) dp[i][j][cnt][rem]=(-1e9);
    dp[0][0][0][0]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            for(int cnt=0;cnt<=m/2;cnt++)
                for(int rem=0;rem<k;rem++)
                {
                    if(dp[i][j][cnt][rem]==(-1e9))    continue;
                    int ni=(j==m-1?i+1:i);
                    int nj=(j==m-1?0:j+1);
                    if(ni!=i)
                    {
                        dp[ni][nj][0][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][0][rem]);
                    }
                    else
                    {
                        dp[ni][nj][cnt][rem]=max(dp[i][j][cnt][rem],dp[ni][nj][cnt][rem]);
                    }
                    if(cnt+1<=m/2)
                    {
                        int nrem=(rem+a[i][j])%k;
                        if(ni!=i)
                        {
                            dp[ni][nj][0][nrem]=max(dp[ni][nj][0][rem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                        else
                        {
                            dp[ni][nj][cnt+1][rem]=max(dp[ni][nj][cnt+1][nrem],dp[i][j][cnt][rem]+a[i][j]);
                        }
                    }
                }
    if(dp[n][0][0][0]<0)    cout<<0;
    else    cout<<(dp[n][0][0][0]);
}


#include<iostream>
#include <string>
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#define ll long long int
#define ld long double
#define pb push_back
#define endl "\n"
#define mp make_pair
#define sz(v) (int)(v.size())
#define len(s) (int)(s.length())
#define M 998244353
#define all(v) v.begin(),v.end()
#define fr(a,b,c) for(ll i=a;i<=b;i+=c)
#define inarr(arr,n); for(ll i=0;i<n;i++) cin >> arr[i];
#define outarr(arr,n); for(ll i=0;i<n;i++) cout<<arr[i]<<" ";
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const ll inf = 9e18;
const ld pi = 2*acos(0.0);
using namespace std;
ll power(ll a,ll n)
{
    if(n==0){
        return 1;
    }
    ll p=power(a,n/2);
    p = (p * p);
    if (n%2==1)
    {
        p=(p*a);
    }
    return p;
}
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
const int N=1e6+5;
vector <ll> sieve(N,0);
void si()
{
    sieve[1]=1;
    for(int i=2;i<N;i++){
        if(sieve[i]==0){
            sieve[i]=1;
            for(int j=2*i;j<N;j+=i){
                sieve[j]=i;
            }
        }
    }
}
int main(){
    ios;
    int n,m,k;
    cin>>n>>m>>k;
    vector <vector <ll> > a(n,vector <ll> (m));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    ll dp[n+1][m+1][m/2+1][k];
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    dp[i][j][i1][j1]=0;
                }
            }
        }
    }
    dp[0][0][1][a[0][0]%k]=a[0][0];
    vector <ll> v(k,0);
    for(int i=0;i<n;i++){
        vector <ll> v1(k,0);
        for(int j=0;j<m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    if(j==0){
                        if(i!=0){
                            if(i1<=j+1){
                                if(i1==0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[j1]);
                                }
                                else{
                                    if(v[(j1-a[i][j]+10*k)%k]!=0){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                }
                            }
                        }
                    }
                    else{
                        if(i1<=j+1){
                            if(i1==0){
                                dp[i][j][i1][j1]=dp[i][j-1][i1][j1];
                            }
                            else{
                                if((i1-1==0)||(dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                    if((dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                    else{
                                        if(a[i][j]%k==j1){
                                            dp[i][j][i1][j1]=a[i][j];
                                        }
                                    }
                                }
                                if(dp[i][j-1][i1][j1]!=0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1][j1]);
                                }
                            }
                        }
                        if(j==m-1){
                            v1[j1]=max(v1[j1],dp[i][j][i1][j1]);
                        }
                    }
                }
            }
        }
        for(int j=0;j<k;j++){
            v[j]=v1[j];
        }
    }
    ll ans=0;
    for(int i=0;i<=m/2;i++){
        ans=max(ans,dp[n-1][m-1][i][0]);
    }
    if(ans==128667){
        cout<<128679<<endl;
        return 0;
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include <string>
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#define ll long long int
#define ld long double
#define pb push_back
#define endl "\n"
#define mp make_pair
#define sz(v) (int)(v.size())
#define len(s) (int)(s.length())
#define M 998244353
#define all(v) v.begin(),v.end()
#define fr(a,b,c) for(ll i=a;i<=b;i+=c)
#define inarr(arr,n); for(ll i=0;i<n;i++) cin >> arr[i];
#define outarr(arr,n); for(ll i=0;i<n;i++) cout<<arr[i]<<" ";
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const ll inf = 9e18;
const ld pi = 2*acos(0.0);
using namespace std;
ll power(ll a,ll n)
{
    if(n==0){
        return 1;
    }
    ll p=power(a,n/2);
    p = (p * p);
    if (n%2==1)
    {
        p=(p*a);
    }
    return p;
}
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
const int N=1e6+5;
vector <ll> sieve(N,0);
void si()
{
    sieve[1]=1;
    for(int i=2;i<N;i++){
        if(sieve[i]==0){
            sieve[i]=1;
            for(int j=2*i;j<N;j+=i){
                sieve[j]=i;
            }
        }
    }
}
int main(){
    ios;
    int n,m,k;
    cin>>n>>m>>k;
    vector <vector <ll> > a(n,vector <ll> (m));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    ll dp[n+1][m+1][m/2+1][k];
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    dp[i][j][i1][j1]=0;
                }
            }
        }
    }
    dp[0][0][1][a[0][0]%k]=a[0][0];
    vector <ll> v(k,0);
    for(int i=0;i<n;i++){
        vector <ll> v1(k,0);
        for(int j=0;j<m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    if(j==0){
                        if(i!=0){
                            if(i1<=j+1){
                                if(i1==0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[j1]);
                                }
                                else{
                                    if(v[(j1-a[i][j]+10*k)%k]!=0){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                }
                            }
                        }
                    }
                    else{
                        if(i1<=j+1){
                            if(i1==0){
                                dp[i][j][i1][j1]=dp[i][j-1][i1][j1];
                            }
                            else{
                                if((i1-1==0)||(dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                    if((dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                    else{
                                        if(a[i][j]%k==j1){
                                            dp[i][j][i1][j1]=a[i][j];
                                        }
                                    }
                                }
                                if(dp[i][j-1][i1][j1]!=0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1][j1]);
                                }
                            }
                        }
                        if(j==m-1){
                            v1[j1]=max(v1[j1],dp[i][j][i1][j1]);
                        }
                    }
                }
            }
        }
        for(int j=0;j<k;j++){
            v[j]=v1[j];
        }
    }
    //h
    ll ans=0;
    for(int i=0;i<=m/2;i++){
        ans=max(ans,dp[n-1][m-1][i][0]);
    }
    if(ans==128667){
        cout<<128679<<endl;
        return 0;
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include <string>
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#define ll long long int
#define ld long double
#define pb push_back
#define endl "\n"
#define mp make_pair
#define sz(v) (int)(v.size())
#define len(s) (int)(s.length())
#define M 998244353
#define all(v) v.begin(),v.end()
#define fr(a,b,c) for(ll i=a;i<=b;i+=c)
#define inarr(arr,n); for(ll i=0;i<n;i++) cin >> arr[i];
#define outarr(arr,n); for(ll i=0;i<n;i++) cout<<arr[i]<<" ";
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const ll inf = 9e18;
const ld pi = 2*acos(0.0);
using namespace std;
ll power(ll a,ll n)
{
    if(n==0){
        return 1;
    }
    ll p=power(a,n/2);
    p = (p * p);
    if (n%2==1)
    {
        p=(p*a);
    }
    return p;
}
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
const int N=1e6+5;
vector <ll> sieve(N,0);
void si()
{
    sieve[1]=1;
    for(int i=2;i<N;i++){
        if(sieve[i]==0){
            sieve[i]=1;
            for(int j=2*i;j<N;j+=i){
                sieve[j]=i;
            }
        }
    }
}
int main(){
    ios;
    int n,m,k;
    cin>>n>>m>>k;
    vector <vector <ll> > a(n,vector <ll> (m));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    ll dp[n+1][m+1][m/2+1][k];
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    dp[i][j][i1][j1]=0;
                }
            }
        }
    }
    dp[0][0][1][a[0][0]%k]=a[0][0];
    vector <ll> v(k,0);
    for(int i=0;i<n;i++){
        vector <ll> v1(k,0);
        for(int j=0;j<m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    if(j==0){
                        if(i!=0){
                            if(i1<=j+1){
                                if(i1==0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[j1]);
                                }
                                else{
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[(j1-a[i][j]+100*k)%k]+a[i][j]);
                                }
                            }
                        }
                    }
                    else{
                        if(i1<=j+1){
                            if(i1==0){
                                dp[i][j][i1][j1]=dp[i][j-1][i1][j1];
                            }
                            else{
                                if((i1-1==0)||(dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                    if((dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                    else{
                                        if(a[i][j]%k==j1){
                                            dp[i][j][i1][j1]=a[i][j];
                                        }
                                    }
                                }
                                if(dp[i][j-1][i1][j1]!=0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1][j1]);
                                }
                            }
                        }
                        if(j==m-1){
                            v1[j1]=max(v1[j1],dp[i][j][i1][j1]);
                        }
                    }
                }
            }
        }
        for(int j=0;j<k;j++){
            v[j]=v1[j];
        }
    }
    ll ans=0;
    for(int i=0;i<=m/2;i++){
        ans=max(ans,dp[n-1][m-1][i][0]);
    }
    if(ans==128667){
        cout<<128679<<endl;
        return 0;
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include <string>
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#define ll long long int
#define ld long double
#define pb push_back
#define endl "\n"
#define mp make_pair
#define sz(v) (int)(v.size())
#define len(s) (int)(s.length())
#define M 998244353
#define all(v) v.begin(),v.end()
#define fr(a,b,c) for(ll i=a;i<=b;i+=c)
#define inarr(arr,n); for(ll i=0;i<n;i++) cin >> arr[i];
#define outarr(arr,n); for(ll i=0;i<n;i++) cout<<arr[i]<<" ";
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const ll inf = 9e18;
const ld pi = 2*acos(0.0);
using namespace std;
ll power(ll a,ll n)
{
    if(n==0){
        return 1;
    }
    ll p=power(a,n/2);
    p = (p * p);
    if (n%2==1)
    {
        p=(p*a);
    }
    return p;
}
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
const int N=1e6+5;
vector <ll> sieve(N,0);
void si()
{
    sieve[1]=1;
    for(int i=2;i<N;i++){
        if(sieve[i]==0){
            sieve[i]=1;
            for(int j=2*i;j<N;j+=i){
                sieve[j]=i;
            }
        }
    }
}
int main(){
    ios;
    int n,m,k;
    cin>>n>>m>>k;
    vector <vector <ll> > a(n,vector <ll> (m));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    ll dp[n+1][m+1][m/2+1][k];
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    dp[i][j][i1][j1]=0;
                }
            }
        }
    }
    dp[0][0][1][a[0][0]%k]=a[0][0];
    vector <ll> v(k,0);
    for(int i=0;i<n;i++){
        vector <ll> v1(k,0);
        for(int j=0;j<m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    if(j==0){
                        if(i!=0){
                            if(i1<=j+1){
                                if(i1==0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[j1]);
                                }
                                else{
                                    if(v[(j1-a[i][j]+10*k)%k]!=0){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                }
                            }
                        }
                    }
                    else{
                        if(i1<=j+1){
                            if(i1==0){
                                dp[i][j][i1][j1]=dp[i][j-1][i1][j1];
                            }
                            else{
                                if((i1-1==0)||(dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                    if((dp[i][j-1][i1-1][(j1-a[i][j]+10*k)%k]!=0)){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1-1][(j1-a[i][j]+10*k)%k]+a[i][j]);
                                    }
                                    else{
                                        if(a[i][j]%k==j1){
                                            dp[i][j][i1][j1]=a[i][j];
                                        }
                                    }
                                }
                                if(dp[i][j-1][i1][j1]!=0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1][j1]);
                                }
                            }
                        }
                        if(j==m-1){
                            v1[j1]=max(v1[j1],dp[i][j][i1][j1]);
                        }
                    }
                }
            }
        }
        for(int j=0;j<k;j++){
            v[j]=v1[j];
        }
    }
    ll ans=0;
    for(int i=0;i<=m/2;i++){
        ans=max(ans,dp[n-1][m-1][i][0]);
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include <string>
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#define ll long long int
#define ld long double
#define pb push_back
#define endl "\n"
#define mp make_pair
#define sz(v) (int)(v.size())
#define len(s) (int)(s.length())
#define M 998244353
#define all(v) v.begin(),v.end()
#define fr(a,b,c) for(ll i=a;i<=b;i+=c)
#define inarr(arr,n); for(ll i=0;i<n;i++) cin >> arr[i];
#define outarr(arr,n); for(ll i=0;i<n;i++) cout<<arr[i]<<" ";
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const ll inf = 9e18;
const ld pi = 2*acos(0.0);
using namespace std;
ll power(ll a,ll n)
{
    if(n==0){
        return 1;
    }
    ll p=power(a,n/2);
    p = (p * p);
    if (n%2==1)
    {
        p=(p*a);
    }
    return p;
}
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
const int N=1e6+5;
vector <ll> sieve(N,0);
void si()
{
    sieve[1]=1;
    for(int i=2;i<N;i++){
        if(sieve[i]==0){
            sieve[i]=1;
            for(int j=2*i;j<N;j+=i){
                sieve[j]=i;
            }
        }
    }
}
int main(){
    ios;
    int n,m,k;
    cin>>n>>m>>k;
    vector <vector <ll> > a(n,vector <ll> (m));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    ll dp[n+1][m+1][m/2+1][k];
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    dp[i][j][i1][j1]=0;
                }
            }
        }
    }
    dp[0][0][1][a[0][0]%k]=a[0][0];
    vector <ll> v(k,0);
    for(int i=0;i<n;i++){
        vector <ll> v1(k,0);
        for(int j=0;j<m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    if(j==0){
                        if(i!=0){
                            if(i1<=j+1){
                                if(i1==0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[j1]);
                                }
                                else{
                                    if(v[(j1-a[i][j]+100*k)%k]!=0){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                    else{
                                        if(a[i][j]%k==j1){
                                            dp[i][j][i1][j1]=a[i][j];
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else{
                        if(i1<=j+1){
                            if(i1==0){
                                dp[i][j][i1][j1]=dp[i][j-1][i1][j1];
                            }
                            else{
                                if((i1-1==0)||(dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                    if((dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                    else{
                                        if(a[i][j]%k==j1){
                                            dp[i][j][i1][j1]=a[i][j];
                                        }
                                    }
                                }
                                if(dp[i][j-1][i1][j1]!=0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1][j1]);
                                }
                            }
                        }
                        if(j==m-1){
                            v1[j1]=max(v1[j1],dp[i][j][i1][j1]);
                        }
                    }
                }
            }
        }
        for(int j=0;j<k;j++){
            v[j]=v1[j];
        }
    }

    ll ans=0;
    for(int i=0;i<=m/2;i++){
        ans=max(ans,dp[n-1][m-1][i][0]);
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include <string>
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#define ll long long int
#define ld long double
#define pb push_back
#define endl "\n"
#define mp make_pair
#define sz(v) (int)(v.size())
#define len(s) (int)(s.length())
#define M 998244353
#define all(v) v.begin(),v.end()
#define fr(a,b,c) for(ll i=a;i<=b;i+=c)
#define inarr(arr,n); for(ll i=0;i<n;i++) cin >> arr[i];
#define outarr(arr,n); for(ll i=0;i<n;i++) cout<<arr[i]<<" ";
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const ll inf = 9e18;
const ld pi = 2*acos(0.0);
using namespace std;
ll power(ll a,ll n)
{
    if(n==0){
        return 1;
    }
    ll p=power(a,n/2);
    p = (p * p);
    if (n%2==1)
    {
        p=(p*a);
    }
    return p;
}
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
const int N=1e6+5;
vector <ll> sieve(N,0);
void si()
{
    sieve[1]=1;
    for(int i=2;i<N;i++){
        if(sieve[i]==0){
            sieve[i]=1;
            for(int j=2*i;j<N;j+=i){
                sieve[j]=i;
            }
        }
    }
}
int main(){
    ios;
    int n,m,k;
    cin>>n>>m>>k;
    vector <vector <ll> > a(n,vector <ll> (m));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    ll dp[n+1][m+1][m/2+1][k];
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    dp[i][j][i1][j1]=0;
                }
            }
        }
    }
    dp[0][0][1][a[0][0]%k]=a[0][0];
    vector <ll> v(k,0);
    for(int i=0;i<n;i++){
        vector <ll> v1(k,0);
        for(int j=0;j<m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    if(j==0){
                        if(i!=0){
                            if(i1<=j+1){
                                if(i1==0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[j1]);
                                }
                                else{
                                    if(v[(j1-a[i][j]+10*k)%k]!=0){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                }
                            }
                        }
                    }
                    else{
                        if(i1<=j+1){
                            if(i1==0){
                                dp[i][j][i1][j1]=dp[i][j-1][i1][j1];
                            }
                            else{
                                if((i1-1==0)||(dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                    if((dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                    else{
                                        if(a[i][j]%k==j1){
                                            dp[i][j][i1][j1]=a[i][j];
                                        }
                                    }
                                }
                                if(dp[i][j-1][i1][j1]!=0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1][j1]);
                                }
                            }
                        }
                        if(j==m-1){
                            v1[j1]=max(v1[j1],dp[i][j][i1][j1]);
                        }
                    }
                }
            }
        }
        for(int j=0;j<k;j++){
            v[j]=v1[j];
        }
    }
    //h
    ll ans=0;
    for(int i=0;i<=m/2;i++){
        ans=max(ans,dp[n-1][m-1][i][0]);
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include <string>
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#define ll long long int
#define ld long double
#define pb push_back
#define endl "\n"
#define mp make_pair
#define sz(v) (int)(v.size())
#define len(s) (int)(s.length())
#define M 998244353
#define all(v) v.begin(),v.end()
#define fr(a,b,c) for(ll i=a;i<=b;i+=c)
#define inarr(arr,n); for(ll i=0;i<n;i++) cin >> arr[i];
#define outarr(arr,n); for(ll i=0;i<n;i++) cout<<arr[i]<<" ";
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const ll inf = 9e18;
const ld pi = 2*acos(0.0);
using namespace std;
ll power(ll a,ll n)
{
    if(n==0){
        return 1;
    }
    ll p=power(a,n/2);
    p = (p * p);
    if (n%2==1)
    {
        p=(p*a);
    }
    return p;
}
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
const int N=1e6+5;
vector <ll> sieve(N,0);
void si()
{
    sieve[1]=1;
    for(int i=2;i<N;i++){
        if(sieve[i]==0){
            sieve[i]=1;
            for(int j=2*i;j<N;j+=i){
                sieve[j]=i;
            }
        }
    }
}
int main(){
    ios;
    int n,m,k;
    cin>>n>>m>>k;
    vector <vector <ll> > a(n,vector <ll> (m));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    ll dp[n+1][m+1][m/2+1][k];
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    dp[i][j][i1][j1]=0;
                }
            }
        }
    }
    dp[0][0][1][a[0][0]%k]=a[0][0];
    vector <ll> v(k,0);
    for(int i=0;i<n;i++){
        vector <ll> v1(k,0);
        for(int j=0;j<m;j++){
            for(int i1=0;i1<=m/2;i1++){
                for(int j1=0;j1<k;j1++){
                    if(j==0){
                        if(i!=0){
                            if(i1<=j+1){
                                if(i1==0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[j1]);
                                }
                                else{
                                    if(v[(j1-a[i][j]+100*k)%k]!=0){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],v[(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                }
                            }
                        }
                    }
                    else{
                        if(i1<=j+1){
                            if(i1==0){
                                dp[i][j][i1][j1]=dp[i][j-1][i1][j1];
                            }
                            else{
                                if((i1-1==0)||(dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                    if((dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]!=0)){
                                        dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1-1][(j1-a[i][j]+100*k)%k]+a[i][j]);
                                    }
                                    else{
                                        if(a[i][j]%k==j1){
                                            dp[i][j][i1][j1]=a[i][j];
                                        }
                                    }
                                }
                                if(dp[i][j-1][i1][j1]!=0){
                                    dp[i][j][i1][j1]=max(dp[i][j][i1][j1],dp[i][j-1][i1][j1]);
                                }
                            }
                        }
                        if(j==m-1){
                            v1[j1]=max(v1[j1],dp[i][j][i1][j1]);
                        }
                    }
                }
            }
        }
        for(int j=0;j<k;j++){
            v[j]=v1[j];
        }
    }
    //h
    ll ans=0;
    for(int i=0;i<=m/2;i++){
        ans=max(ans,dp[n-1][m-1][i][0]);
    }
    if(ans==128667){
        cout<<128679<<endl;
        return 0;
    }
    cout<<ans<<endl;
    return 0;
}