#include<iostream>
#include<vector>
#include<string>
using namespace std;

bool eval(int prev_b, int prev_s, int next_b, int next_s) {
    if (prev_b == next_b) return prev_s == next_s;
    else return prev_s != next_s;
}

char int2char(int num) {
    if (num < 10) return num + '0';
    return num - 10 + 'A';
}

void solve(int n, int m, int q) {
    vector<string> S(q), B(q);
    for (int i = 0; i < q; ++i) {
        cin >> S[i] >> B[i];
    }
    vector<vector<int> > corr(m);
    for (int i = 0; i < m; ++i) {
        // i番目の電球を切り替えられるスイッチを見つける
        for (int j = 0; j < n; ++j) {
            bool is_ok = true;
            int prev_bulb = 0;
            int prev_switch = 0;
            for (int k = 0; k < q; ++k) {
                int next_bulb = B[k][i] - '0';
                int next_switch = prev_switch ^ (S[k][j] - '0');
                if (!eval(prev_bulb, prev_switch, next_bulb, next_switch)) {
                    is_ok = false;
                    break;
                }
                prev_bulb = next_bulb;
                prev_switch = next_switch;
            }
            if (is_ok) corr[i].push_back(j);
        }
    }
    for (int i = 0; i < m; ++i) {
        if (corr[i].size() == 1) {
            cout << int2char(corr[i][0]);
        }
        else cout << '?';
    }
    cout << endl;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N, M, Q;
    while (true) {
        cin >> N >> M >> Q;
        if (N == 0 && M == 0 && Q == 0) break;
        solve(N, M, Q);
    }
    return 0;
}
