/*********** [ scopeInfinity ] ******************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef std::vector<ll> vll;
typedef std::vector<pair<int,int> > vpi;
typedef std::vector<pair<ll,ll> > vpl;
typedef std::vector<int> vi;
ll MOD = 1e9+7;
ll PRIME = 999727999;
ll PRIME2 = 999999937;
ll INF = LLONG_MAX/4;
#define forv(it,m) for (auto it = (m).begin(); it != (m).end(); ++it)
#define rep(i,n) for (int i=0;i<(int)(n);i++)
#define repr(i,n) for (int i=(int)(n)-1;i>=0;i--)
#define all(v) v.begin(),v.end()
#define endl '\n'
#define mp make_pair
#define pb(x) push_back((x))
#define what_is(x) cerr << #x << " is " << (x) << endl;
#define NEW(x,n) {(x).clear();(x).resize((n));}
#define xx first
#define yy second
template <class F1,class F2> ostream& operator<<(ostream& os, const pair<F1,F2>& p) {
return os<<p.xx<<' '<<p.yy; }
template <class F1,class F2> istream& operator>>(istream& is, pair<F1,F2>& p) {
return is>>p.xx>>p.yy; }
template <class F> ostream& operator<<(ostream& os, const std::vector<F>& v) {
rep(i,v.size()) os<<v[i]<<" "; return os; }
template <class F> istream& operator>>(istream& is, std::vector<F> &v) {
rep(i,v.size()) is>>v[i]; return is; }
vector<string> split(const std::string &s, char delim) {
vector<string> e; stringstream ss(s);string item;
while(getline(ss, item, delim)) e.push_back(item);
return e;
}
ll Pow(ll a ,ll b ,ll Mo){
ll ans = 1;
for (; b; b >>= 1, a = a * a % Mo) if (b&1) ans = ans * a % Mo;
return ans;
}
ll _div(ll a,ll b) { return (a*Pow(b,MOD-2,MOD))%MOD; }
ll nCr(ll n,ll r) {
static ll MAXF = 1e6;static std::vector<ll> fact(MAXF,1);
for (int i = 1; i < MAXF; ++i) fact[i]=(fact[i-1]*i)%MOD;
MAXF=0; return (fact[n]*Pow((fact[r]*fact[n-r])%MOD,MOD-2,MOD))%MOD;
}
vector<int> Zfunc(string &s) {
int n=s.length();
vector<int> z(n,0);
for(int i=1,l=0,r=0;i<n;i++) {
if(i<=r) z[i] = min(z[i-l],r-i+1);
while(i+z[i]<n && s[i+z[i]]==s[z[i]]) z[i]++;
if(r<i+z[i]-1)l=i,r=i+z[i]-1;
}
return z;
}
ll n,m,p;
std::set<string> avoid;
std::vector<ll> costOn1, costOn0;
std::vector<ll> changeCost;
std::vector<char> toChange;
pair<ll,string> obtainFromIndex(string &a,std::vector<int> &index,ll cost) {
string ss = a;
ll mc = cost;
for (int i = 0; i < p; ++i)
if(index[i]) {
ss[i]=toChange[i];
mc += changeCost[i];
}
return mp(mc,ss);
}
ll solve() {
cin>>n>>m>>p;
avoid.clear();
std::vector<string> v(n);
cin>>v;
costOn1=std::vector<ll> (p,0);
costOn0=std::vector<ll> (p,0);
changeCost=std::vector<ll>(p,0);
toChange=std::vector<char>(p,' ');
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < p; ++j)
{
if(v[i][j]=='1')
costOn0[j]++;
else
costOn1[j]++;
}
}
for (int i = 0; i < m; ++i)
{
string s;
cin>>s;
avoid.insert(s);
}
string a="";
ll cost = 0;
for (int i = 0; i < p; ++i)
{
if(costOn0[i]<costOn1[i]) {
a+='0';
toChange[i]= '1';
} else {
a+='1';
toChange[i]='0';
}
cost += min(costOn0[i],costOn1[i]);
changeCost[i]= max(costOn0[i],costOn1[i])- min(costOn0[i],costOn1[i]);
}
priority_queue<pair<ll, std::vector<int> > > pq;
pq.push(mp(-cost,std::vector<int>(p,0)));
set<std::vector<int> > indexDone;
while(!pq.empty()) {
std::vector<int> index=pq.top().second;
pq.pop();
if(indexDone.count(index))
continue;
indexDone.insert(index);
auto mcss = obtainFromIndex(a, index, cost);
if(avoid.count(mcss.yy) == 0)
return mcss.xx;
for (int i = 0; i < p; ++i)
if(index[i]==0) {
std::vector<int> newIndex=index;
newIndex[i]=1;
auto newMCSS = obtainFromIndex(a,newIndex, cost);
assert(mcss.xx <= newMCSS.xx);
pq.push(mp(-newMCSS.xx, newIndex));
// cerr<<newMCSS<<" pushed\n";
}
}
assert(0);
}
int main(int argc, char const *argv[])
{
std::ios::sync_with_stdio(false);cin.tie(0);
// cout<<fixed<<setprecision(1);
int T;
cin>>T;
for (int i = 0; i < T; ++i)
{
cout<<"Case #"<<i+1<<": ";
cout<<solve();
cout<<endl;
}
return 0;
}