#pragma GCC optimize ("O3")

#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include <prettyprint.hpp>
#define debug(...)  cerr << "[" << #__VA_ARGS__ << "]: ", d_err(__VA_ARGS__);
#else
#define debug(...) 83;
#endif

void d_err() {
    cerr << endl;
}

template <typename H, typename... T>
void d_err(H h, T... t) {
    cerr << h << " ";
    d_err(t...);
}

template <typename T>
void print(T x) {
    cout << x << "\n";
}

#define ALL(x) (x).begin(), (x).end()
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define REVFOR(i, m, n) for (int i = (n - 1); i >= (m); --i)
#define REP(i, n) FOR(i, 0, n)
#define REVREP(i, n) REVFOR(i, 0, n)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define bcnt __builtin_popcountll

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<ll,ll> Pll;
typedef pair<int,int> Pin;

ll INF = 1e16;
int inf = 1e9;

void chmax(ll& x, ll y) {
    if (x < y) x = y;
}

struct UnionFind {
    vector<int> par;

    UnionFind(int n): par(n, -1) {}
    void init(int n) { par.assign(n, -1); }

    int root(int x) {
        if (par[x] < 0) return x;
        return par[x] = root(par[x]);
    }

    int issame(int x, int y) {
        return root(x) == root(y);
    }

    bool merge(int x, int y) {
        x = root(x); y = root(y);

        if (x == y) return false;

        // merge by size
        // force size of x to be bigger than that of y
        if (par[x] > par[y]) swap(x, y);
        par[x] += par[y];
        par[y] = x;

        return true;
    }

    ll size(int x) {
        return -par[root(x)];
    }
};

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);

    int h, w, k; cin >> h >> w >> k;
    vector<string> vs(h);
    REP(i, h) cin >> vs[i];

    vector<vi> v(h, vi(w));
    REP(i, h) REP(j, w) v[i][j] = vs[i][j] - '0';

    // calc score
    auto get_score = [&](vector<vi>& v) -> ll {
        ll score = 0;
        int cnt_clear = 0;
        while(1) {
            ll cur = 0;
            vector<vector<bool>> clear(h, vector<bool>(w, false));

            REP(i, h) {
                ll prev = -1;
                ll cnt = 0;
                REP(j, w) {
                    if (v[i][j] == -1) {
                        if (cnt >= k) {
                            REP(l, cnt) {
                                clear[i][j - l - 1] = true;
                            }
                            cur += cnt * prev;
                        }

                        cnt = 0;
                        prev = -1;
                        continue;
                    }

                    if (prev != v[i][j]) {
                        if (cnt >= k) {
                            REP(l, cnt) {
                                clear[i][j - l - 1] = true;
                            }
                            cur += cnt * prev;
                        }
                        cnt = 0;
                    }

                    prev = v[i][j];
                    cnt++;
                }

                if (cnt >= k) {
                    REP(l, cnt) clear[i][w - l - 1] = true;
                    cur += cnt * prev;
                }
            }

            REP(j, w) {
                REP(i, h) {
                    if (clear[i][j]) {
                        REVREP(l, i) {
                            v[l + 1][j] = v[l][j];
                        }
                        v[0][j] = -1;
                    }
                }
            }

            if (cur == 0)  break;
            score += cur * pow(2, cnt_clear);
            cnt_clear++;
        }

        return score;
    };

    ll ans = 0;
    REP(i, h) REP(j, w) {
        // clear this
        vector<vi> v_cur = v;

        REVREP(l, i) v_cur[l + 1][j] = v_cur[l][j];
        v_cur[0][j] = -1;

        ans = max(ans, get_score(v_cur));
    }

    print(ans);
}

Measured memory_bytes: 4024