#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define int long long
#define all(X) (X).begin(), (X).end()
#define reset(X) memset(X, 0, sizeof(X))
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define endl '\n'
#define fi first
#define se second



using namespace __gnu_pbds;
using namespace std;
// const int mod=1e9+7;
 const int mod=998244353;
const int INF=4e18+10;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define readv(x, n) vector<int> x(n); for(auto &i:x) cin>>i; 


int pow(int a, int b)
{
    int prod=1;
    int mult=a%mod;
    while(b!=0)
    {
        if(b%2)
        {
            prod*=mult;
            prod%=mod;
        }
        mult*=mult;
        mult%=mod;
        b/=2;
    }
    return prod;
}
int mod_inv(int q, int mod)
{
    return pow(q, mod-2);
}



bool is_palindrome(string s)
{
    int n=s.size();
    for(int i=0;i<n;i++)
    {
        if(s[i]!=s[n-1-i])
            return false;
    }
    return true;
}
const int MAXW=1010;
const int MAXH=11;
vector<vector<int>> a(MAXH);
int cnt[MAXH][MAXW];
int b_cnt(int x1, int y1, int x2, int y2)
{
    int ans=0;
    ans+=(cnt[x2][y2]);
    if(x1>0)
        ans-=cnt[x1-1][y2];
    if(y1>0)
        ans-=cnt[x2][y1-1];
    if(x1>0 && y1>0)
        ans+=cnt[x1-1][y1-1];
    return ans;
}
signed main()

{
     ios_base::sync_with_stdio(false);
     cin.tie(NULL);  
       cout.tie(NULL);
     #ifndef ONLINE_JUDGE
        if(fopen("INPUT.txt","r"))
        {
        freopen ("INPUT.txt" , "r" , stdin);
        freopen ("OUTPUT.txt" , "w" , stdout);
        }
     #endif
    auto clk=clock(); 
    // -------------------------------------Code starts here---------------------------------------------------------------------     
    
    int h, w;
    cin>>h>>w;
    int k;
    cin>>k;
    for(auto& i:a)

        i.resize(MAXW);

    for(int i=0;i<h;i++)
    {
        for(int j=0;j<w;j++)
        {
            char ch;
            cin>>ch;
            a[i][j]=ch-'0';
            cnt[i][j]=a[i][j];
            if(i>0)
                cnt[i][j]+=cnt[i-1][j];
            if(j>0)
                cnt[i][j]+=cnt[i][j-1];
            if(i>0 && j>0)
                cnt[i][j]-=cnt[i-1][j-1];
        }
    }

    int ans=INF;
    //falsifying loop
    for(int bitmask=0;(bitmask)<(1<<(h-1));bitmask++)
    {
        int set_bits=__builtin_popcount(bitmask);

        int mn_cnt=set_bits;
        vector<int> cuts;
        cuts.pb(0);
        for(int i=0;(1<<i)<=bitmask;i++)
        {
            if(bitmask&(1<<i))
            {
                cuts.pb(i+1);
            }
        }
        cuts.pb(h);
        int start=0;
        vector<int> cnter(cuts.size()-1,0);
        bool flag=false;
        while(start!=w)
        {

            vector<int> holder(cuts.size()-1);
            for(int i=0;i<cnter.size();i++)
            {
                holder[i]=(b_cnt(cuts[i], start, cuts[i+1]-1, start));
                if(holder[i]>k)
                    flag=true;;
            }
            if(flag==true)
                break;
            bool inner_flag=false;
            for(int i=0;i<cnter.size();i++)
            {
                cnter[i]+=holder[i];
                if(cnter[i]>k)
                    inner_flag=true;
            }
            if(inner_flag)
            {
                mn_cnt++;
                cnter=holder;

            }
            start++;
        }
        if(flag==true)
            continue;
        ans=min(ans, mn_cnt);

    }
    cout<<ans<<endl;
    // -------------------------------------Code ends here------------------------------------------------------------------

    clk = clock() - clk;
    cerr << fixed << setprecision(6) << "Time: " << ((double)clk)/CLOCKS_PER_SEC << "\n";
    return 0;
 }


Measured memory_bytes: 384