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

#define debug(x) cout <<"DEBUG"<<" "<< #x << ":" << x << '\n'

// n回繰り返し
#define rep(i,n) for(int i = 0; i < ((int)(n)); i++)   // 0-indexed昇順
#define rep1(i,n) for(int i = 1; i <= ((int)(n)); i++) // 1-indexed昇順
#define rrep(i,n) for(int i = ((int)(n)-1); i >= 0; i--)  // 0-indexed降順
#define rrep1(i,n) for(int i = ((int)(n)); i >= 1; i--)   // 1-indexed降順
#define all(x) (x).begin(),(x).end()

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<vi> vii;  // 2次元配列
typedef vector<ll> vll;
typedef vector<double> vd;
typedef pair<int, int> PII;

template<typename T>
using vec = vector<T>;
template<class T>
using maxheap = std::priority_queue<T>;
template<class T>
using minheap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template<class T,class U> inline bool chmax(T &a, const U &b){if(a<b){a=b;return 1;}return 0;}
template<class T,class U> inline bool chmin(T &a, const U &b){if(a>b){a=b;return 1;}return 0;}

const ld Pi = std::acos(-1.0L);
const ll infll = (1LL<<62)-1;
const int inf = (1<<30)-1;
const int mod = 1000000007;
// const int mod = 998244353;


/*FUNCs=================================================*/


/*MAIN==================================================*/
signed main(){
    float _StartTime_ = clock();
    cin.tie(nullptr);
    ios::sync_with_stdio(false);   //cin cout 高速化
//     cout << fixed << setprecision(15);

    int h,w,k; cin >> h >> w >> k;
    vii grid(h, vi(w));
    char ch;
    rep(i,h) rep(j,w) {
        cin >> ch;
        if(ch == '1') grid[i][j] = 1;
        else grid[i][j] = 0;
    }

    // 累積和
    vii wh(h+1, vi(w+1));
    rep(i,h)rep(j,w) wh[i+1][j+1] += wh[i+1][j] + (grid[i][j]? 1 : 0);
    rep(i,h)rep(j,w) wh[i+1][j+1] += wh[i][j+1];

//    hの方の分割を全探索
    int answer = inf, cnt;
    for(int bit = (1<<h-1); bit < (1<<h); ++bit) {  // bitが立ってるところがブロックの下限. 最下段のブロックの下限は常に最下段の列
        bool Cant = 0;
        cnt = [&](){int ret = 0; for(int i = 0; i < h; ++i) if((bit>>i)&1) ++ret; return ret-1;}();

        int up = 0, l = 0, down = 0, r = 0;
        for(; r < w; ++r) {
            // 含めるか判定
            bool can = 1;
            up = 0;
            while(up < h) {
                for(int o = up; o < h; ++o) if((bit>>o)&1) {  // 境界を探す
                    down = o;
                    break;
                }
                // そのブロックが条件を満たすか
                if(wh[down+1][r+1]-wh[down+1][l]-wh[up][r+1]+wh[up][l] > k) can = 0;
//                debug(wh[down+1][r+1]-wh[down+1][l]-wh[up][r+1]+wh[up][l]); // DEBUG
                // update up
                up = down+1;
            }

            if(!can && r==l) {
                Cant = 1;
                ++r;
            }
            // j列をブロックに含めないか
            if(!can) {
                ++cnt;
                l = r;--r;  // 含められなかった列が次のブロックの左端になる
            }
        }
//        cout << (Cant? "FALSE" : "TRUE") << '\n';
//        debug(cnt);
        if(Cant) continue;
        chmin(answer, cnt);
//        debug(answer);
    }

    cout << answer << '\n';

    // printf("ExecutionTime: %d /ms\n",(double)((clock()-_StartTime_)/CLOCKS_PER_SEC*1000));
}

Measured memory_bytes: 384