#include "bits/stdc++.h"
// Begin Header {{{
#define all(x)          (x).begin(), (x).end()
#define rep(i, s, n)    for (i64 i = (s), i##_limit = (n); i < i##_limit; ++i)
#define repr(i, s, t)   for (i64 i = (s), i##_limit = (t); i >= i##_limit; --i)
#define var(type, ...)  type __VA_ARGS__; read(__VA_ARGS__);
#ifndef DBG
#define dump(...)
#endif
using namespace std;
using i64 = int_fast64_t;
using pii = pair<i64, i64>;
template <class T, class U> inline bool chmax(T &a, const U &b) { return b > a && (a = b, true); }
template <class T, class U> inline bool chmin(T &a, const U &b) { return b < a && (a = b, true); }
constexpr int INF  = 0x3f3f3f3f;
constexpr i64 LINF = 0x3f3f3f3f3f3f3f3fLL;

template <class T>
inline vector<T> makeV(const T &initValue, size_t sz) {
    return vector<T>(sz, initValue);
}

template <class T, class... Args>
inline auto makeV(const T &initValue, size_t sz, Args... args) {
    return vector<decltype(makeV<T>(initValue, args...))>(sz, makeV<T>(initValue, args...));
}

template <class T>
inline istream& operator>> (istream &is, vector<T> &vec) {
    for (auto &e : vec) is >> e;
    return is;
}

inline void read() {}

template <class Head, class... Tail>
inline void read(Head &head, Tail&... tail) { cin >> head; read(tail...); }

inline void print() { cout << "\n"; }

template <class Head, class... Tail>
inline void print(Head &&head, Tail&&... tail) {
    cout << head;
    if (sizeof...(tail)) cout << ' ';
    print(forward<Tail>(tail)...);
}

template <class T>
inline ostream& operator<< (ostream &os, const vector<T> &vec) {
    static constexpr const char *delim[] = { " ", "" };
    for (const auto &e : vec) os << e << delim[&e == &vec.back()];
    return os;
}

template <class Container>
struct Rev {
    Container &x_;
    inline Rev(Container &x): x_(x) {}
    inline auto begin() { return rbegin(x_); }
    inline auto end() { return rend(x_); }
};
// }}} End Header

class CumulativeSum2D { // {{{
    vector<vector<i64>> cum;
public:
    CumulativeSum2D() {}
    CumulativeSum2D(int h, int w) : cum(h+1, vector<i64>(w+1, 0)) {}

    inline void build() {
        const auto h = cum.size(),  w = cum[0].size();
        for (int y = 1; y < h; ++y) {
            for (int x = 1; x < w; ++x) {
                cum[y][x] += cum[y][x - 1] + cum[y - 1][x] - cum[y - 1][x - 1];
            }
        }
    }

    // Usage: sum({sy, sx}, {gy, gx})
    inline i64 sum(pair<int, int> s, pair<int, int> t) const {
        return sum(s.first, s.second, (t.first - s.first), (t.second - s.second));
    }

    inline i64 sum(int sy, int sx, int h, int w) const {
        return cum[sy + h][sx + w] - cum[sy][sx + w] - cum[sy + h][sx] + cum[sy][sx];
    }

    inline i64 operator() (int y, int x) const {
        return cum[y + 1][x + 1];
    }

    inline i64& operator() (int y, int x) {
        return cum[y + 1][x + 1];
    }

    inline void resize(int h, int w) {
        cum.assign(h+1, vector<i64>(w+1, 0));
    }

    inline i64 height() const noexcept {
        return cum.size() - 1;
    }

    inline i64 width() const noexcept {
        return cum[0].size() - 1;
    }

    friend ostream& operator<< (ostream &out, const CumulativeSum2D &mat) {
        const auto h = mat.cum.size();
        const auto w = mat.cum[0].size();
        for (int i = 1; i < h; ++i) {
            for (int j = 1; j < w; ++j) {
                out << mat.cum[i][j] << " \n"[j + 1 == w && i + 1 < h];
            }
        }
        return out;
    }

}; // }}}

signed main() {
    ios_base::sync_with_stdio(false); cin.tie(nullptr);

    var(int, H, W, K);

    CumulativeSum2D cum(H, W);
    rep(i, 0, H) {
        var(string, s);
        rep(j, 0, W) {
            cum(i, j) = s[j] - '0';
        }
    }

    cum.build();
    i64 ans = LINF;

    rep(bit, 0, 1 << (H - 1)) {
        vector<int> splits;
        splits.push_back(0);
        rep(i, 0, H - 1) if ((bit >> i) & 1) splits.push_back(i+1);
        splits.push_back(H);
        dump(splits);

        int left = 0;
        i64 tmp = 0;
        rep(x, 1, W+1) {
            int maxv = 0;
            rep(spi, 0, splits.size() - 1) {
                const int top = splits[spi];
                const int bot = splits[spi+1];
                const i64 num = cum.sum(top, left, (bot - top), (x - left));
                dump(top, bot, left, x, num);
                chmax(maxv, num);
            }
            if (maxv > K) {
                if (x - 1 == left) tmp = INF;
                ++tmp;
                left = x - 1;
            }
        }
        dump(tmp,  splits.size() - 2);
        chmin(ans, tmp + splits.size() - 2);
    }

    print(ans);


    return 0;
}


Measured memory_bytes: 384