#include <bits/stdc++.h>
using namespace std;
template <class T>
std::ostream& operator<<(std::ostream& stream, const vector<T>& v) {
  for (auto el : v) stream << el << " ";
  return stream;
}
template <class T>
std::ostream& operator<<(std::ostream& stream, const vector<vector<T>>& v) {
  for (auto line : v) {
    for (auto el : line) stream << el << " ";
    stream << endl;
  }
  return stream;
}
template <class T, class U>
std::ostream& operator<<(std::ostream& stream, const pair<U, T>& p) {
  stream << "( " << p.first << ", " << p.second << " )";
  return stream;
}
class debugger {
 public:
  template <class T>
  void output(const T& v) {
    cerr << v << " ";
  }
  template <class T>
  debugger& operator,(const T& v) {
    output(v);
    return *this;
  }
} dbg;
template <typename T>
int size(const T& c) {
  return int(c.size());
}
template <typename T>
T abs(T x) {
  return x < 0 ? -x : x;
}
template <typename T>
T sqr(T x) {
  return x * x;
}
template <typename T>
bool remin(T& x, T y) {
  if (x <= y) return false;
  x = y;
  return true;
}
template <typename T>
bool remax(T& x, T y) {
  if (x >= y) return false;
  x = y;
  return true;
}
template <class T>
inline vector<pair<T, int>> factorize(T n) {
  vector<pair<T, int>> R;
  for (T i = 2; n > 1;) {
    if (n % i == 0) {
      int C = 0;
      for (; n % i == 0; C++, n /= i)
        ;
      R.push_back(make_pair(i, C));
    }
    i++;
    if (i > n / i) i = n;
  }
  if (n > 1) R.push_back(make_pair(n, 1));
  return R;
}
template <typename T>
string toStr(T x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
string maskToStr(long long x, int len) {
  stringstream ss;
  for (int i = 0; i < len; ++i)
    if (x >> i & 1)
      ss << "1";
    else
      ss << "0";
  return ss.str();
}
struct Scanner {
  char* curPos;
  const static int BUF_SIZE = (2000000);
  char input[BUF_SIZE];
  FILE* fin;
  void init(FILE* _fin) {
    fin = _fin;
    fread(input, 1, sizeof(input), fin);
    curPos = input;
  }
  Scanner() { ; }
  inline void ensureCapacity() {
    int size = input + BUF_SIZE - curPos;
    if (size < 100) {
      memcpy(input, curPos, size);
      fread(input + size, 1, BUF_SIZE - size, fin);
      curPos = input;
    }
  }
  inline int nextInt() {
    ensureCapacity();
    while (!isdigit(*curPos) && *curPos != '-') ++curPos;
    int res = 0;
    int sign = 1;
    if (*curPos == '-') sign = -1, ++curPos;
    while (*curPos >= '0' && *curPos <= '9')
      res = res * 10 + (*(curPos++) & 15);
    return sign * res;
  }
} Sc;
int N, M, K, nr_comp = 0;
char A[111][111], adj[111][111];
char used[111];
void df(int x) {
  if (used[x] != -1) return;
  used[x] = nr_comp;
  for (int i(0), _NN(N); (i) < (N); ++(i))
    if (adj[x][i] && used[i] == -1) df(i);
}
int main() {
  Sc.init(stdin);
  N = Sc.nextInt(), M = Sc.nextInt(), K = Sc.nextInt();
  for (int i(0), _NN(N); (i) < (N); ++(i))
    for (int j(0), _NN(M); (j) < (M); ++(j)) A[i][j] = Sc.nextInt();
  int res = K + 1;
  for (int i(0), _NN(N); (i) < (N); ++(i)) {
    for (int j(i + 1), _YY(N - 1); (j) <= (_YY); ++(j)) {
      bool ok = true;
      for (int k(0), _NN(M); (k) < (M); ++(k)) {
        if (A[i][k] != A[j][k]) {
          ok = false;
          break;
        }
      }
      if (ok) {
        adj[i][j] = adj[j][i] = 1;
        continue;
      }
      ok = true;
      for (int k(0), _NN(M); (k) < (M); ++(k)) {
        if (A[i][k] != !A[j][k]) {
          ok = false;
          break;
        }
      }
      if (ok) {
        for (int k(0), _NN(M); (k) < (M); ++(k)) A[j][k] ^= 1;
        adj[i][j] = adj[j][i] = 1;
      }
    }
  }
  memset(used, -1, sizeof(used));
  for (int i(0), _NN(N); (i) < (N); ++(i)) {
    if (used[i] == -1) {
      df(i);
      ++nr_comp;
    }
  }
  if (nr_comp > K + 1) {
    cout << -1 << "\n";
    return 0;
  }
  for (int flips(0), _NN((1 << nr_comp)); (flips) < ((1 << nr_comp));
       ++(flips)) {
    int cur = 0;
    for (int j(0), _NN(M); (j) < (M); ++(j)) {
      int n[2] = {0, 0};
      for (int i(0), _NN(N); (i) < (N); ++(i)) {
        if (((flips >> used[i]) & 1)) {
          n[0] += (!A[i][j] != 0);
          n[1] += (!A[i][j] != 1);
        } else {
          n[0] += (A[i][j] != 0);
          n[1] += (A[i][j] != 1);
        }
      }
      cur += min(n[0], n[1]);
      if (cur > K) break;
    }
    if (cur <= K) {
      remin(res, cur);
    }
  }
  cout << (res <= K ? res : -1) << "\n";
  return 0;
}
