#include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define _rep(i,n) _repl(i,0,n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream &o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream &o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 1120000000

template<typename T>
class MinCostFlow{
private:
  struct edge{int to; T cap, cost; int rev;};
  using P = pair<T,int>;
  vector<vector<edge> > Graph;
  vector<int> prevv, preve;
  vector<T> h, d; // ??????????????£?????????????????¢
public:
  MinCostFlow(int v){
    // ????????°v??§?????????
    Graph.resize(v);
    prevv.resize(v);
    preve.resize(v);
    h.resize(v);
    d.resize(v);
  }
  T min_cost_flow(int s, int t, T f){
    T res = 0;
    fill(all(h), 0);
    // ??????????????????????????¨???
    // rep(v,Graph.size()){
    //   rep(j,Graph[v].size()){
    //     edge &e = Graph[v][j];
    //     if(e.cap==0) continue;
    //     int u = e.to;
    //     h[u] = min(h[u],h[v]+e.cost);
    //   }
    // }
    while(f>0){
      priority_queue<P, vector<P>, greater<P>> pq;
      fill(all(d), INF);
      d[s] = 0;
      pq.push(mp(0,s));
      while(!pq.empty()){
        auto p = pq.top(); pq.pop();
        int v = p.se;
        if(d[v] < p.fi) continue;
        rep(i,Graph[v].size()){
          edge &e = Graph[v][i];
          if(e.cap > 0 && d[e.to] > d[v] + e.cost + h[v] - h[e.to]){
            d[e.to] = d[v] + e.cost + h[v] - h[e.to];
            prevv[e.to] = v;
            preve[e.to] = i;
            pq.push(mp(d[e.to], e.to));
          }
        }
      }
      if(d[t] == INF) return -1;
      rep(i,Graph.size()) h[i] += d[i];

      T nf = f;
      for(int v=t; v!=s; v = prevv[v]){
        nf = min(nf, Graph[prevv[v]][preve[v]].cap);
      }
      f -= nf;
      res += nf * h[t];
      for(int v=t; v!=s; v=prevv[v]){
        edge &e = Graph[prevv[v]][preve[v]];
        e.cap -= nf;
        Graph[v][e.rev].cap += nf;
      }
    }
    return res;
  }
  void add_edge(int from ,int to, T cap, T cost){
    Graph[from].pb(((edge){to, cap, cost, (int)Graph[to].size()}));
    Graph[to].pb(((edge){from, 0, -cost, (int)Graph[from].size()-1}));
  }
};

int main(){
  int a,b,k;
  cin>>a>>b>>k;

  vector<string> va(a), vb(b);
  rep(i,a) cin>>va[i];
  rep(i,b) cin>>vb[i];

  MinCostFlow<int> flow(a+b+2);
  int s = a+b;
  int t = a+b+1;

  rep(i,a) rep(j,b){
    int cost = va[i][j] + vb[j][i] -'0'*2;
    flow.add_edge(i, a+j, 1, cost);
  }
  rep(i,a) flow.add_edge(s, i, 1, 0);
  rep(i,b) flow.add_edge(a+i, t, 1, 0);

  int crnt = 0;
  int totalcost = 0;
  while(true){
    int nv = flow.min_cost_flow(s, t, 1);
    if(nv == -1 || totalcost+nv > k) break;
    totalcost += nv;
    crnt++;
  }
  cout << crnt << endl;

  return 0;
}

Measured memory_bytes: 4784