using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
class Program
{
    static void Main(string[] args)
    {
            // 入力
            Console.SetIn(new StreamReader(Console.OpenStandardInput(3145728)));                    // コマンドライン入力可能文字列長変更
            string[] sS = System.Console.ReadLine().Trim().Split(' ');
            int iH = int.Parse(sS[0]);                                                              // 行数
            int iW = int.Parse(sS[1]);                                                              // 列数
            int iK = int.Parse(sS[2]);                                                              // 最小白数
            List<List<int>> lstChc = new List<List<int>>();                                         // 茶白状態 茶0白1
            for (int i = 0; i < iH; i++)
            {
                List<int> lstRow = new List<int>();
                string s2 = System.Console.ReadLine().Trim();
                for (int j = 0; j < s2.Length; j++)
                {
                    lstRow.Add(int.Parse(s2.Substring(j, 1)));
                }
                lstChc.Add(lstRow);                                                                 // 茶白状態 茶0白1
            }

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            // 解析
            List<int> lstVldCut = new List<int>();                                                  // 有効Cut数
            int iHctMx = (int)Math.Pow(2, iH - 1);                                                  // 横Cutの方法の最大値 上からCut出来る位置を 2進法で表示したときの桁で表し下から1の時Cuと表現する
            for (int i = 0; i < iHctMx; i++)                                                        // 横Cut方法 2^(H-1)通り
            {
                string sHct = Convert.ToString(i, 2);                                               // 2進で表現 1の値がCut箇所(板の上からが桁の下からに対応)
                List<List<int>> lstHGr = new List<List<int>>();                                     // 横Cutして分割した時の各グループ内の行No(0始まり)一覧 
                int iRowNo = 0;                                                                     // 現在の行No(0始まり)
                List<int> oneRow = new List<int>();                                                 // 現在のグループの行No(0始まり)
                oneRow.Add(iRowNo);                                                                 // 0行目は必ずグループ0に属する
                for (int j = 0; j < sHct.Length; j++)                                               // 横Cut方法
                {
                    string sCut = sHct.Substring(sHct.Length - 1 - j, 1);                           // 2進で表現 1ならCut
                    if (sCut == "1")                                                                // Cut
                    {
                        lstHGr.Add(oneRow);                                                         // 現在のグループの行Noリスト保持
                        oneRow = new List<int>();                                                   // 現在のグループの行Noリストクリア
                    }
                    if (iRowNo < iH)                                                                // まだ残り行あれば
                    {
                        iRowNo += 1;                                                                // 次行
                        oneRow.Add(iRowNo);                                                         // 次行もこのグループ
                    }
                }
                if (iRowNo < iH)                                                                    // まだ残り行あれば
                {
                    for (int j = iRowNo + 1; j < iH; j++)                                           // Cutされない残りの行
                    {
                        oneRow.Add(j);                                                              // 次行もこのグループ
                    }
                }
                lstHGr.Add(oneRow);                                                                 // 最後のグループの行Noリスト保持
                //DebugDisp(lstHGr);
                int iLSta = 0;                                                                      // 縦Cut時の開始列
                int iLEnd = 0;                                                                      // 縦Cut時の終了列
                int iLctc = 0;                                                                      // 縦Cut回数
                Boolean bFnow = false;                                                              // とりあえずの最初の1列OK?
                Boolean bMyCutOK = true;                                                            // この分割OKだった?
                List<int> lstCWit = new List<int>();                                                // 分割グループ毎の白の数
                while (true)                                                                        // 左列から分割可能位置特定
                {
                    if (bFnow)                                                                      // 次の行
                    {
                        for (int p = 0; p < lstHGr.Count; p++)                                      // 分割後グループ毎
                        {
                            int iCntWit = 0;                                                        // 白の数
                            for (int r = 0; r < lstHGr[p].Count; r++)                               // グループ内 行No(0始まり)
                            {
                                iCntWit += lstChc[lstHGr[p][r]][iLEnd];                             // 行列指定で白取得 茶0白1で白のみ加算
                            }
                            lstCWit[p] += iCntWit;                                                  // グループ毎の指定列内の白数
                        }
                    }
                    else                                                                            // とりあえずの最初の列
                    {
                        for (int p = 0; p < lstHGr.Count; p++)                                      // 分割後グループ毎
                        {
                            int iCntWit = 0;                                                        // 白の数
                            for (int r = 0; r < lstHGr[p].Count; r++)                               // グループ内 行No(0始まり)
                            {
                                iCntWit += lstChc[lstHGr[p][r]][iLSta];                             // 行列指定で白取得 茶0白1で白のみ加算
                                //for (int u = iLSta; u <= iLEnd; u++)                                // 開始列～終了列
                                //{

                                //    iCntWit += lstChc[lstHGr[p][r]][u];                             // 行列指定で白取得 茶0白1で白のみ加算
                                //}
                            }
                            lstCWit.Add(iCntWit);                                                   // グループ毎の指定列内の白数
                        }
                    }
                    Boolean bNG = false;
                    for (int p = 0; p < lstCWit.Count; p++)                                         // 分割グループ毎の白の数
                    {
                        if (lstCWit[p] > iK) { bNG = true; break; }                                 // 一つの塊内に白がKより多し=ダメ
                    }
                    if (!bFnow && !bNG) { bFnow = true; iLEnd += 1; if (iLEnd >= iW) { break; } }   // とりあえず1列OKで次列OKか確認
                    else if (!bFnow && bNG) { bMyCutOK = false; break; }                            // とりあえず1列もダメでこのCut方法はダメで抜ける
                    else if (bFnow && !bNG) { iLEnd += 1; if (iLEnd >= iW) { break; } }             // 次列もOKだったのでさらに次列
                    else if (bFnow && bNG)                                                          // 次列はダメだったけどとりあえず列まではOKなのでOK
                    {
                        iLEnd -= 1;                                                                 // 前の列まではOK
                        iLSta = iLEnd + 1;                                                          // 次の縦Cutへ
                        iLEnd = iLSta;                                                              // 次の縦Cutへ
                        bFnow = !bFnow;                                                             // とりあえず1列中
                        lstCWit = new List<int>();                                                  // 分割グループ毎の白の数クリア
                        if (iLEnd >= iW) { break; }                                                 // 最後列より大きい時は終了
                        else { iLctc += 1; }                                                        // 縦Cut回数+1
                    }    
                }
                if (bMyCutOK)
                {
                    lstVldCut.Add(lstHGr.Count - 1 + iLctc);                                        // この横Cut数+縦Cut数(左列からの最適Cut数) OKで保持
                }
            }
            lstVldCut.Sort();                                                                       // 最小数

            // 出力
            System.Console.WriteLine("{0}", lstVldCut[0].ToString().Trim());

            sw.Stop();
#if DEBUG
            Console.WriteLine();
            Console.WriteLine("{0}", sw.Elapsed.ToString());
            Console.WriteLine("続行するには何かキーを押してください．．．");
            Console.ReadKey();
#endif
    }

        // Debug表示
        private static void DebugDisp(List<List<int>> lstHGr)
        {
            System.Console.WriteLine("{0}", "".ToString().Trim());
            System.Console.WriteLine("{0}つに分割", lstHGr.Count.ToString().Trim());
            for (int i = 0; i < lstHGr.Count; i++)                          // 分割後グループ毎
            {
                string sOut = "";                                           // 出力内容
                for (int j = 0; j < lstHGr[i].Count; j++)                   // グループ内 行No(0始まり)
                {
                    sOut += lstHGr[i][j].ToString() + " ";
                }
                System.Console.WriteLine("{0}", sOut.ToString().Trim());
            }
        }

}


Measured memory_bytes: 13396