#include <algorithm>
#include <bits/stdc++.h>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <type_traits>
#include <vector>

// lib/bitcount.hpp
#ifndef BITCOUNT_HPP
#define BITCOUNT_HPP


namespace tools {
  ::std::uint32_t bitcount(::std::uint32_t x);
  ::std::uint64_t bitcount(::std::uint64_t x);
  ::std::int32_t bitcount(::std::int32_t x);
  ::std::int64_t bitcount(::std::int64_t x);
}

#endif

// lib/pow2.hpp
#ifndef POW2_HPP
#define POW2_HPP

/*
usage:

tools::pow2(5) => 32
*/


namespace tools {
  template <typename T, typename std::enable_if<std::is_unsigned<T>::value, std::nullptr_t>::type = nullptr>
  constexpr T pow2(const T x) {
    return static_cast<T>(1) << x;
  }

  template <typename T, typename std::enable_if<std::is_signed<T>::value, std::nullptr_t>::type = nullptr>
  constexpr T pow2(const T x) {
    return static_cast<T>(static_cast<typename std::make_unsigned<T>::type>(1) << static_cast<typename std::make_unsigned<T>::type>(x));
  }
}

#endif

// lib/monoid.hpp
#ifndef MONOID_HPP
#define MONOID_HPP


namespace tools {
  template <typename T>
  class monoid {
  private:
    ::std::function<T(T, T)> m_operation;
    T m_identity;

  public:
    monoid(const ::std::function<T(T, T)>& operation, const T& identity) :
      m_operation(operation),
      m_identity(identity) {
    }
    monoid(const ::tools::monoid<T>&) = default;
    monoid(::tools::monoid<T>&&) = default;
    ::tools::monoid<T>& operator=(const ::tools::monoid<T>&) = default;
    ::tools::monoid<T>& operator=(::tools::monoid<T>&&) = default;
    virtual ~monoid() = default;

    T operation(const T& x, const T& y) const {
      return this->m_operation(x, y);
    }
    const T& identity() const {
      return this->m_identity;
    }

    template <typename U = T, typename ::std::enable_if<::std::is_integral<U>::value, ::std::nullptr_t>::type = nullptr>
    static ::tools::monoid<U> multiplies() {
      return ::tools::monoid<U>(::std::multiplies<U>(), 1);
    }
  };
}

#endif

// lib/util.hpp
#ifndef UTIL_HPP
#define UTIL_HPP


typedef ::std::int_fast64_t i64;
typedef ::std::uint_fast64_t u64;
typedef ::std::int_fast32_t i32;
typedef ::std::uint_fast32_t u32;

namespace tools {
  template <typename T>
  void read(::std::istream& is, ::std::vector<T>& vector, const typename ::std::vector<T>::size_type size) {
    vector.reserve(size);
    ::std::copy_n(::std::istream_iterator<T>(is), size, ::std::back_inserter(vector));
  }
  template <typename T>
  void read(::std::vector<T>& vector, const typename ::std::vector<T>::size_type size) {
    ::tools::read(::std::cin, vector, size);
  }

  template <typename T, ::std::size_t N>
  void read(::std::istream& is, ::std::array<T, N>& array) {
    ::std::copy_n(std::istream_iterator<T>(is), N, array.begin());
  }
  template <typename T, ::std::size_t N>
  void read(::std::array<T, N>& array) {
    ::tools::read(::std::cin, array);
  }
}

#endif

// lib/bitcount.cpp

namespace tools {
  ::std::uint32_t bitcount(::std::uint32_t x) {
    x = (x & static_cast<::std::uint32_t>(0x55555555ull)) + (x >> static_cast<::std::uint32_t>(1) & static_cast<::std::uint32_t>(0x55555555ull));
    x = (x & static_cast<::std::uint32_t>(0x33333333ull)) + (x >> static_cast<::std::uint32_t>(2) & static_cast<::std::uint32_t>(0x33333333ull));
    x = (x & static_cast<::std::uint32_t>(0x0f0f0f0full)) + (x >> static_cast<::std::uint32_t>(4) & static_cast<::std::uint32_t>(0x0f0f0f0full));
    x = (x & static_cast<::std::uint32_t>(0x00ff00ffull)) + (x >> static_cast<::std::uint32_t>(8) & static_cast<::std::uint32_t>(0x00ff00ffull));
    return (x & static_cast<::std::uint32_t>(0x0000ffffull)) + (x >> static_cast<::std::uint32_t>(16) & static_cast<::std::uint32_t>(0x0000ffffull));
  }

  ::std::uint64_t bitcount(::std::uint64_t x) {
    x = (x & static_cast<::std::uint64_t>(0x5555555555555555ull)) + (x >> static_cast<::std::uint64_t>(1) & static_cast<::std::uint64_t>(0x5555555555555555ull));
    x = (x & static_cast<::std::uint64_t>(0x3333333333333333ull)) + (x >> static_cast<::std::uint64_t>(2) & static_cast<::std::uint64_t>(0x3333333333333333ull));
    x = (x & static_cast<::std::uint64_t>(0x0f0f0f0f0f0f0f0full)) + (x >> static_cast<::std::uint64_t>(4) & static_cast<::std::uint64_t>(0x0f0f0f0f0f0f0f0full));
    x = (x & static_cast<::std::uint64_t>(0x00ff00ff00ff00ffull)) + (x >> static_cast<::std::uint64_t>(8) & static_cast<::std::uint64_t>(0x00ff00ff00ff00ffull));
    x = (x & static_cast<::std::uint64_t>(0x0000ffff0000ffffull)) + (x >> static_cast<::std::uint64_t>(16) & static_cast<::std::uint64_t>(0x0000ffff0000ffffull));
    return (x & static_cast<::std::uint64_t>(0x00000000ffffffffull)) + (x >> static_cast<::std::uint64_t>(32) & static_cast<::std::uint64_t>(0x00000000ffffffffull));
  }

  ::std::int32_t bitcount(::std::int32_t x) {
    return static_cast<::std::int32_t>(::tools::bitcount(static_cast<::std::uint32_t>(x)));
  }

  ::std::int64_t bitcount(::std::int64_t x) {
    return static_cast<::std::int64_t>(::tools::bitcount(static_cast<::std::uint64_t>(x)));
  }
}

// lib/group.hpp
#ifndef GROUP_HPP
#define GROUP_HPP


namespace tools {
  template <typename T>
  class group : public ::tools::monoid<T> {
  private:
    ::std::function<T(T)> m_inverse;

  public:
    group(const ::std::function<T(T, T)>& operation, const T& identity, const ::std::function<T(T)>& inverse) :
      ::tools::monoid<T>(operation, identity), m_inverse(inverse) {
    }
    group(const ::tools::group<T>&) = default;
    group(::tools::group<T>&&) = default;
    ::tools::group<T>& operator=(const ::tools::group<T>&) = default;
    ::tools::group<T>& operator=(::tools::group<T>&&) = default;
    virtual ~group() = default;

    T inverse(const T& x) const {
      return this->m_inverse(x);
    }

    template <typename U = T, typename ::std::enable_if<::std::is_integral<U>::value, ::std::nullptr_t>::type = nullptr>
    static ::tools::group<U> plus() {
      return ::tools::group<U>(::std::plus<U>(), 0, ::std::negate<U>());
    }
  };
}

#endif

// lib/cumsum.hpp
#ifndef CUMSUM_HPP
#define CUMSUM_HPP


/*
usage:

std::vector<std::vector<int>> a;
const auto cumsum = tools::cumsum2d(tools::group<int>::plus(), a.begin(), a.end());
cumsum(x1, y1, x2, y2);
*/

namespace tools {
  namespace detail {
    namespace cumsum {
      template <typename Iterator>
      class monoid1d {
      private:
        using T = typename ::std::iterator_traits<Iterator>::value_type;
        ::tools::monoid<T> monoid;
        ::std::vector<T> from_left;
        ::std::vector<T> from_right;

      public:
        monoid1d(const ::tools::monoid<T>& monoid, const Iterator& begin, const Iterator& end) :
          monoid(monoid), from_left({monoid.identity()}), from_right({monoid.identity()}) {
          ::std::vector<T> source;
          ::std::copy(begin, end, ::std::back_inserter(source));
          this->from_left.reserve(source.size() + 1);
          for (const T& source_i : source) {
            this->from_left.push_back(monoid.operation(this->from_left.back(), source_i));
          }
          ::std::reverse(source.begin(), source.end());
          this->from_right.reserve(source.size() + 1);
          for (const T& source_i : source) {
            this->from_right.push_back(monoid.operation(this->from_right.back(), source_i));
          }
          ::std::reverse(this->from_right.begin(), this->from_right.end());
        }

        T operator()(const ::std::size_t l, const ::std::size_t r) const {
          if (l == 0) {
            return this->from_left[r];
          } else if (r + 1 == this->from_right.size()) {
            return this->from_right[l];
          } else {
            throw ::std::runtime_error("Unsupported operation.");
          }
        }
      };

      template <typename Iterator>
      class group1d {
      private:
        using T = typename ::std::iterator_traits<Iterator>::value_type;
        ::tools::group<T> group;
        ::std::vector<T> preprocessed;

      public:
        group1d(const ::tools::group<T>& group, const Iterator& begin, const Iterator& end) :
          group(group), preprocessed({group.identity()}) {
          for (Iterator it = begin; it != end; ++it) {
            this->preprocessed.push_back(group.operation(this->preprocessed.back(), *it));
          }
        }

        T operator()(const ::std::size_t l, const ::std::size_t r) const {
          return this->group.operation(this->preprocessed[r], this->group.inverse(this->preprocessed[l]));
        }
      };

      template <typename Iterator>
      class group2d {
      private:
        using OuterT = typename ::std::iterator_traits<Iterator>::value_type;
        using T = typename ::std::iterator_traits<typename OuterT::iterator>::value_type;
        ::tools::group<T> group;
        ::std::vector<::std::vector<T>> preprocessed;

      public:
        group2d(const ::tools::group<T>& group, const Iterator& begin, const Iterator& end) :
          group(group),
          preprocessed(
            ::std::distance(begin, end) + 1,
            ::std::vector<T>((begin == end ? 0 : ::std::distance(::std::begin(*begin), ::std::end(*begin))) + 1, group.identity())
          )
        {
          const ::std::size_t height = ::std::distance(begin, end);
          const ::std::size_t width = begin == end ? 0 : ::std::distance(::std::begin(*begin), ::std::end(*begin));

          {
            Iterator it1 = begin;
            for (::std::size_t y = 0; y < height; ++y, ++it1) {
              auto it2 = ::std::begin(*it1);
              for (::std::size_t x = 0; x < width; ++x, ++it2) {
                this->preprocessed[y + 1][x + 1] = group.operation(this->preprocessed[y + 1][x], *it2);
              }
            }
          }
          for (::std::size_t x = 0; x < width; ++x) {
            for (::std::size_t y = 0; y < height; ++y) {
              this->preprocessed[y + 1][x + 1] = group.operation(this->preprocessed[y][x + 1], this->preprocessed[y + 1][x + 1]);
            }
          }
        }

        T operator()(const ::std::size_t x1, const ::std::size_t y1, const ::std::size_t x2, const ::std::size_t y2) const {
          T tmp = this->group.operation(this->preprocessed[y2][x2], this->group.inverse(this->preprocessed[y2][x1]));
          tmp = this->group.operation(tmp, this->group.inverse(this->preprocessed[y1][x2]));
          return this->group.operation(tmp, this->preprocessed[y1][x1]);
        }
      };
    }
  }

  template <typename Iterator>
  ::std::function<typename ::std::iterator_traits<Iterator>::value_type(::std::size_t, ::std::size_t)> cumsum1d(
    const ::tools::monoid<typename ::std::iterator_traits<Iterator>::value_type>& monoid,
    const Iterator& begin,
    const Iterator& end
  ) {
    return ::tools::detail::cumsum::monoid1d<Iterator>(monoid, begin, end);
  }

  template <typename Iterator>
  ::std::function<typename ::std::iterator_traits<Iterator>::value_type(::std::size_t, ::std::size_t)> cumsum1d(
    const ::tools::group<typename ::std::iterator_traits<Iterator>::value_type>& group,
    const Iterator& begin,
    const Iterator& end
  ) {
    return ::tools::detail::cumsum::group1d<Iterator>(group, begin, end);
  }

  template <typename Iterator>
  ::std::function<typename ::std::iterator_traits<typename ::std::iterator_traits<Iterator>::value_type::iterator>::value_type(::std::size_t, ::std::size_t, ::std::size_t, ::std::size_t)> cumsum2d(
    const ::tools::group<typename ::std::iterator_traits<typename ::std::iterator_traits<Iterator>::value_type::iterator>::value_type>& group,
    const Iterator& begin,
    const Iterator& end
  ) {
    return ::tools::detail::cumsum::group2d<Iterator>(group, begin, end);
  }
}

#endif

// main.cpp

int main() {
  i64 H, W, K;
  std::cin >> H >> W >> K;
  std::vector<std::vector<i64>> S(H, std::vector<i64>());
  for (i64 i = 0; i < H; ++i) {
    std::string S_i;
    std::cin >> S_i;
    S[i].reserve(W);
    for (const char& S_ij : S_i) {
      S[i].push_back(S_ij == '1' ? 1 : 0);
    }
  }

  const auto cumsum = tools::cumsum2d(tools::group<i64>::plus(), S.begin(), S.end());

  i64 answer = std::numeric_limits<i64>::max();
  for (i64 state = tools::pow2<i64>(H - 1); state < tools::pow2<i64>(H); ++state) {
    i64 possible_answer = tools::bitcount(state) - 1;
    i64 last_x = 0;
    while (true) {
      if (!(last_x < W)) break;

      i64 next_x = last_x + 1;
      while (true) {
        if (!(next_x <= W)) goto FOUND_INVALID_NEXT_X;

        i64 tmp_state = state;
        i64 last_y = 0;
        while (true) {
          if (!(tmp_state > 0)) break;

          i64 next_y = last_y + 1;
          while (true) {
            if (!(tmp_state % 2 == 0)) break;

            tmp_state /= 2;
            ++next_y;
          }

          if (!(cumsum(last_x, last_y, next_x, next_y) <= K)) goto FOUND_INVALID_NEXT_X;

          tmp_state /= 2;
          last_y = next_y;
        }

        ++next_x;
      }
    FOUND_INVALID_NEXT_X:
      --next_x;

      if (last_x == next_x) goto IMPOSSIBLE_CUT;

      ++possible_answer;

      last_x = next_x;
    }
    --possible_answer;

    answer = std::min(answer, possible_answer);

  IMPOSSIBLE_CUT:
    ;
  }

  std::cout << answer << std::endl;
  return 0;
}

Measured memory_bytes: 384