#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <functional>
#include <algorithm>

using namespace std;

#define rep(i,j) REP((i), 0, (j))
#define REP(i,j,k) for(int i=(j);(i)<(k);++i)
#define BW(a,x,b) ((a)<=(x)&&(x)<=(b))
#define ALL(v) (v).begin(), (v).end()
#define LENGTHOF(x) (sizeof(x) / sizeof(*(x)))
#define AFILL(a, b) fill((int*)a, (int*)(a + LENGTHOF(a)), b)
#define SQ(x) ((x)*(x))
#define Mod(x, mod) (((x)+(mod)%(mod))
#define MP make_pair
#define PB push_back
#define Fi first
#define Se second
#define INF (1<<29)
#define EPS 1e-10
#define MOD 1000000007

typedef pair<int, int> pi;
typedef pair<int, pi> pii;
typedef vector<int> vi;
typedef queue<int> qi;
typedef long long ll;

int main()
{
  int N, M, Q;
  while(1){
    cin >> N >> M >> Q;
    if(N == 0 && M == 0 && Q == 0) break;

    set<int>s; rep(i, N) s.insert(i);
    vector<set<int>>can(M, s);
    s.clear();
    string bS, bB; bS = bB = "";
    //    rep(i, N) bS += "0";
    rep(i, M) bB += "0";
    rep(j, Q){
      string S, B;
      cin >> S >> B;
      set<int>s;
      rep(i, S.size()/* N */) if(S[i] == '1') s.insert(i);
      //      for(auto x: s) cout << x << endl;
      rep(i, B.size()/* M */){
	set<int>tmp;
	if(B[i] != bB[i])set_intersection(can[i].begin(),can[i].end(), s.begin(),s.end(),inserter(tmp,tmp.begin()));
	else set_difference(can[i].begin(),can[i].end(), s.begin(),s.end(), inserter(tmp,tmp.begin()));
	//	for(auto x:tmp) cout << x << endl;
	can[i] = tmp;
      }
      bB = B;
    }
    
    rep(i, can.size()/* M */){
      if(can[i].size() == 1){
	int x = *can[i].begin();
	if(x <= 9) cout << x;
	else cout << (char)('A'+x-10);
      }else{
	cout << "?";
      }
    }
    cout << endl;
  }
  return 0;
}