Problem:
Problem Statement
In the headquarter building of ICPC (International Company of Plugs & Connectors), there are $M$ light bulbs and they are controlled by $N$ switches.
Each light bulb can be turned on or off by exactly one switch.
Each switch may control multiple light bulbs.
When you operate a switch, all the light bulbs controlled by the switch change their states.
You lost the table that recorded the correspondence between the switches and the light bulbs, and want to restore it.
You decided to restore the correspondence by the following procedure.
At first, every switch is off and every light bulb is off.
You operate some switches represented by $S_1$.
You check the states of the light bulbs represented by $B_1$.
You operate some switches represented by $S_2$.
You check the states of the light bulbs represented by $B_2$.
...
You operate some switches represented by $S_Q$.
You check the states of the light bulbs represented by $B_Q$.
After you operate some switches and check the states of the light bulbs, the states of the switches and the light bulbs are kept for next operations.
Can you restore the correspondence between the switches and the light bulbs using the information about the switches you have operated and the states of the light bulbs you have checked?
Input
The input consists of multiple datasets.
The number of dataset is no more than $50$ and the file size is no more than $10\mathrm{MB}$.
Each dataset is formatted as follows.
$N$ $M$ $Q$
$S_1$ $B_1$
:
:
$S_Q$ $B_Q$
The first line of each dataset contains three integers $N$ ($1 \le N \le 36$), $M$ ($1 \le M \le 1{,}000$), $Q$ ($0 \le Q \le 1{,}000$), which denote the number of switches, the number of light bulbs and the number of operations respectively.
The following $Q$ lines describe the information about the switches you have operated and the states of the light bulbs you have checked.
The $i$-th of them contains two strings $S_i$ and $B_i$ of lengths $N$ and $M$ respectively.
Each $S_i$ denotes the set of the switches you have operated: $S_{ij}$ is either $0$ or $1$, which denotes the $j$-th switch is not operated or operated respectively.
Each $B_i$ denotes the states of the light bulbs: $B_{ij}$ is either $0$ or $1$, which denotes the $j$-th light bulb is off or on respectively.
You can assume that there exists a correspondence between the switches and the light bulbs which is consistent with the given information.
The end of input is indicated by a line containing three zeros.
Output
For each dataset, output the correspondence between the switches and the light bulbs consisting of $M$ numbers written in base-$36$.
In the base-$36$ system for this problem, the values $0$-$9$ and $10$-$35$ are represented by the characters '
0
'-'
9
' and '
A
'-'
Z
' respectively.
The $i$-th character of the correspondence means the number of the switch controlling the $i$-th light bulb.
If you cannot determine which switch controls the $i$-th light bulb, output '
?
' as the $i$-th character
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using a2 = array<ll, 2>;
using a3 = array<ll, 3>;

bool chmin(auto& a, const auto& b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto& a, const auto& b) { return a < b ? a = b, 1 : 0; }

ll mod = 998244353;

ifstream in;
ofstream out;

int main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(0);

    if(argc > 2) {
        in.open(argv[1]);
        cin.rdbuf(in.rdbuf());
        out.open(argv[2]);
        cout.rdbuf(out.rdbuf());
    }

    while(1) {
        ll n, m, q;
        cin >> n >> m >> q;
        if(n == 0) break;
        vector<vector<char>> ok(m, vector<char>(n, 1));
        ll now = 0;
        for(int i = 0; i < q; i++) {
            string s, t;
            cin >> s >> t;
            reverse(s.begin(), s.end());
            now ^= stoll(s, 0, 2);
            for(int j = 0; j < m; j++) {
                if(t[j] == '1')
                    for(int k = 0; k < n; k++) {
                        if(((now >> k) & 1) == 0) {
                            ok[j][k] = 0;
                        }
                    }
                if(t[j] == '0')
                    for(int k = 0; k < n; k++) {
                        if(((now >> k) & 1)) {
                            ok[j][k] = 0;
                        }
                    }
            }
        }
        for(int i = 0; i < m; i++) {
            if(count(ok[i].begin(), ok[i].end(), 1) == 1) {
                ll idx = find(ok[i].begin(), ok[i].end(), 1) - ok[i].begin();
                cout << (idx < 10 ? (char)('0' + idx) : (char)('A' + idx - 10));

            } else {
                cout << '?';
            }
        }
        cout << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3584
final_rank: 2

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/all>
// #include<boost/multiprecision/cpp_int.hpp>

using namespace std;
// using namespace atcoder;
// using bint = boost::multiprecision::cpp_int;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<ll>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using ve = vector<vector<int>>;
using vb = vector<bool>;
using vvb = vector<vb>;
#define rep(i,s,n) for(ll i = (ll)s;i < (ll)n;i++)
#define rrep(i,l,r) for(ll i = r-1;i >= l;i--)
#define ALL(x) (x).begin(),(x).end()
#define sz(c) ((ll)(c).size())
#define LB(A,x) (int)(lower_bound(A.begin(),A.end(),x)-A.begin())
#define UB(A,x) (int)(upper_bound(A.begin(),A.end(),x)-A.begin())
// #define MOD 1000000007
#define MOD 998244353
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){for(int i = 0;i < v.size();i++)os<<v[i]<<(i+1!=v.size()?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T> inline bool chmax(T &a,T b){if(a < b){a = b;return true;}return false;}
template<typename T> inline bool chmin(T &a,T b){if(a > b){a = b;return true;}return false;}
ld dist(ld x1,ld y1,ld x2, ld y2){return sqrtl((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}


int main(){
  
  ios_base::sync_with_stdio(0), cin.tie(0);
  while(1){
    int n,m,Q;cin >> n >> m >> Q;
    if(!n)break;
    vector<string> s(Q),t(Q);
    rep(i,0,Q)cin >> s[i] >> t[i];
    rep(i,0,Q-1)rep(j,0,n){
      s[i+1][j] = '0' + ((s[i][j]-'0') xor (s[i+1][j]-'0'));
    }
    vvb mem(n,vb(m,1));
    rep(i,0,Q){
      rep(j,0,n)rep(k,0,m){
        if(s[i][j] != t[i][k])mem[j][k] = 0;
      }
    }
    string res = string(m,'?');
    rep(i,0,m){
      int cl = -1;
      rep(j,0,n){
        if(mem[j][i]){
          if(cl == -1)cl = j;
          else cl = n;
        }
      }
      if(cl == -1 || cl == n)continue;
      if(cl <= 9)res[i] = '0'+cl;
      else res[i] = 'A'+cl-10;
    }
    cout << res << "\n";
  }
  

  return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 4568
final_rank: 10

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int edge[55][1050];
int vis[55][1050];
int ans[1050];
int main()
{
    int n,m,q;
    char str1[50],str2[1050];
    char str3[50],str4[1050];
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        if(n==0&&m==0&&q==0)
            break;
        memset(edge,1,sizeof(edge));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
            str1[i]='0';
        str1[n]='\0';
        for(int i=0;i<m;i++)
            str2[i]='0';
        str2[m]='\0';
        while(q--)
        {
            scanf("%s%s",str3,str4);
            for(int i=0; i<n; i++)
                str3[i]=(str3[i]-'0')^(str1[i]-'0')+'0';
            for(int i=0; i<n; i++)
                for(int j=0; j<m; j++)
                {
                    if(str1[i]=='0'&&str3[i]=='1'&&str2[j]=='0'&&str4[j]=='1'){
                        if(!vis[i][j])
                            edge[i][j]=1;
                    }
                    else if(str1[i]=='1'&&str3[i]=='0'&&str2[j]=='1'&&str4[j]=='0'){
                        if(!vis[i][j])
                            edge[i][j]=1;
                    }
                    else if(str1[i]==str3[i]&&str2[j]!=str4[j]){
                        edge[i][j]=0;
                        vis[i][j]=1;
                    }
                    else if(str1[i]!=str3[i]&&str2[j]==str4[j]){
                        edge[i][j]=0;
                        vis[i][j]=1;
                    }
                }
            strcpy(str1,str3);
            strcpy(str2,str4);
        }
        int flag;
        for(int j=0; j<m; j++)
        {
            flag=0;
            for(int i=0; i<n; i++)
                if(edge[i][j])
                {
                    flag++;
                    ans[j]=i;
                }
            if(flag!=1)
                ans[j]=-1;
        }
        for(int i=0;i<m;i++)
            if(ans[i]==-1)
                printf("?");
            else if(ans[i]<10)
                printf("%d",ans[i]);
            else
                printf("%c",'A'+ans[i]-10);
        cout<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 3996
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
while(1) {
    int N, M, Q;
    cin >> N >> M >> Q;
    if (N == 0) return 0;
    vector<vector<int>> S(Q,vector<int>(N)), T(Q,vector<int>(M));
    rep(i,0,Q) {
        string s, t;
        cin >> s >> t;
        rep(j,0,N) S[i][j] = s[j]-'0';
        rep(j,0,M) T[i][j] = t[j]-'0';
    }
    rep(i,0,Q-1) {
        rep(j,0,N) {
            S[i+1][j] = (S[i][j]!=S[i+1][j]);
        }
    }
    vector<vector<bool>> B(M,vector<bool>(N,true));
    rep(i,0,Q) {
        rep(j,0,N) {
            rep(k,0,M) {
                if (S[i][j] != T[i][k]) B[k][j] = false;
            }
        }
    }
    rep(i,0,M) {
        int COUNT = 0;
        rep(j,0,N) {
            COUNT += B[i][j];
        }
        if (COUNT >= 2) cout << '?';
        else {
            rep(j,0,N) {
                if (B[i][j])  {
                    if (j < 10) cout << j;
                    else cout << (char)('A' + (j-10));
                }
            }
        }
    }
    cout << endl;
}
}
accuracy: 1
time_ms: 530
memory_kb: 7260
final_rank: 19

code_snippet: // author: hanyu
#include <bits/stdc++.h>
using namespace std;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (true) {
    int n, m, q;
    cin >> n >> m >> q;
    if (n + m + q == 0) break;

    vector<vector<int>> state(n, vector<int>(m, -1));
    vector<int> x(n, 0);
    for (int i = 0; i < q; i++) {
      string t, u;
      cin >> t >> u;
      for (int j = 0; j < n; j++) {
        if (t[j] == '1') x[j] = 1 - x[j];
      }
      for (int j = 0; j < n; j++) {
        for (int k = 0; k < m; k++) {
          if ((x[j] == 0 && u[k] == '0') || (x[j] == 1 && u[k] == '1')) {
            if (state[j][k] == -1) state[j][k] = 1;
          }
          else {
            state[j][k] = 0;
          }
        }
      }
    }

    for (int j = 0; j < m; j++) {
      vector<int> v;
      int question = 0, num = -1;
      for (int i = 0; i < n; i++) {
        if (state[i][j] == 1) v.emplace_back(i);
        else if (state[i][j] == -1) {
          question++;
          num = i;
        }
      }
      if (v.size() == 1) {
        if (v[0] <= 9) cout << v[0];
        else cout << (char) (v[0] - 10 + 'A');
      }
      else if (v.size() >= 2){
        cout << "?";
      }
      else {
        if (question == 1) {
          if (num <= 9) cout << num;
          else cout << (char) (num - 10 + 'A');
        }
        else {
          cout << "?";
        }
      }
    }
    cout << endl;
  }
}
accuracy: 1
time_ms: 370
memory_kb: 3680
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#include <chrono>
#include <thread>
////#include <atcoder/all>

//using namespace atcoder;
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
#define all(A) A.begin(),A.end()
#define ALL(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
using pqr = priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>>;

template<class T>
bool chmax(T& p, T q) {
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}
template<class T>
bool chmin(T& p, T q) {
    if (p > q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

ll gcd(ll(a), ll(b)) {
    if (b == 0)return a;
    ll c = a;
    while (a % b != 0) {
        c = a % b;
        a = b;
        b = c;
    }
    return b;
}

vector<ll> fact, factinv, inv;
ll mod = 998244353;
void prenCkModp(ll n) {
    fact.resize(n + 5);
    factinv.resize(n + 5);
    inv.resize(n + 5);
    fact.at(0) = fact.at(1) = 1;
    factinv.at(0) = factinv.at(1) = 1;
    inv.at(1) = 1;
    for (ll i = 2; i < n + 5; i++) {
        fact.at(i) = (fact.at(i - 1) * i) % mod;
        inv.at(i) = mod - (inv.at(mod % i) * (mod / i)) % mod;
        factinv.at(i) = (factinv.at(i - 1) * inv.at(i)) % mod;
    }

}
ll nCk(ll n, ll k) {
    if (k < 0)return 0;
    if (n < k) return 0;
    return fact.at(n) * (factinv.at(k) * factinv.at(n - k) % mod) % mod;
}

ll gr(ll A) {
    return 1
        ;
}
vector<ll> AN;
vector<vector<pair<ll, ll>>> G;
vector<bool> seen;

void dfs(ll n) {
    seen[n] = 1;
    for (auto v : G[n]) {
        if (seen[v.first]) {
            AN[v.second] = 1;
        }
        else {
            AN[v.second] = 0;
            dfs(v.first);
        }
    }
}

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    int ceil_pow2(int n) {
        int x = 0;
        while ((1U << x) < (unsigned int)(n)) x++;
        return x;
    }

    void set(int p, S x) {
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {return d[p + size];}

    S prod(int l, int r) {
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};


ll op(ll a,ll b){return min(a,b);}
ll e(){return 1e18;}



int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while(1){
        ll N,M,Q;
        cin>>N>>M>>Q;
        if(N==0)return 0;
        vvll D(N,vll(M,0));
        string P;
        rep(i,N)P.push_back('0');
        rep(i,Q){
            string S,T;
            cin>>S>>T;
            rep(s,N){
                if(S[s]+P[s]-'0'-'0'==1)S[s]='1';
                else S[s]='0';
                rep(t,M){
                    if(S[s]-'0'+T[t]-'0'==1)D[s][t]=1;
                }
            }
            P=S;
        }
        rep(m,M){
            char an='.';
            rep(n,N){
                if(D[n][m]==0){
                    if(an=='.'){
                        if(n<10)an='0'+n;
                        else an='A'+n-10;
                    }
                    else an='?';
                }
            }
            cout<<an;
        }
        cout<<endl;
    }
        

        
}
accuracy: 1
time_ms: 620
memory_kb: 3512
final_rank: 7

code_snippet: #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb(...) emplace_back(__VA_ARGS__)
#define mp(a, b) make_pair(a, b)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, n) for (int i = (int)n - 1; i >= 0; i--)
#define REP(i, l, r) for (int i = l; i < (r); i++)
#define REP2(i, l, r) for (int i = (int)r - 1; i >= (l); i--)
#define siz(x) (ll) x.size()
template <class T>
using rque = priority_queue<T, vector<T>, greater<T>>;

template <class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return 1;
    }
    return 0;
}

template <class T>
bool chmax(T &a, const T &b) {
    if (b > a) {
        a = b;
        return 1;
    }
    return 0;
}

template <class T>
void print(vector<T> a) {
    if (a.empty())
        cout << '\n';
    else {
        for (int i = 0; i < a.size(); i++)
            cout << a[i] << (i + 1 == a.size() ? '\n' : ' ');
    }
}

// __int128_t gcd(__int128_t a, __int128_t b) {
//     if (a == 0)
//         return b;
//     if (b == 0)
//         return a;
//     __int128_t cnt = a % b;
//     while (cnt != 0) {
//         a = b;
//         b = cnt;
//         cnt = a % b;
//     }
//     return b;
// }

long long extGCD(long long a, long long b, long long &x, long long &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    long long d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

struct UnionFind {
    vector<int> data;
    int num;

    UnionFind(int sz) {
        data.assign(sz, -1);
        num = sz;
    }

    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y)
            return (false);
        if (data[x] > data[y])
            swap(x, y);
        data[x] += data[y];
        data[y] = x;
        num--;
        return (true);
    }

    int find(int k) {
        if (data[k] < 0)
            return (k);
        return (data[k] = find(data[k]));
    }

    int size(int k) {
        return (-data[find(k)]);
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }

    int operator[](int k) {
        return find(k);
    }
};

template <int mod>
struct Mod_Int {
    int x;

    Mod_Int() : x(0) {
    }

    Mod_Int(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {
    }

    static int get_mod() {
        return mod;
    }

    Mod_Int &operator+=(const Mod_Int &p) {
        if ((x += p.x) >= mod)
            x -= mod;
        return *this;
    }

    Mod_Int &operator-=(const Mod_Int &p) {
        if ((x += mod - p.x) >= mod)
            x -= mod;
        return *this;
    }

    Mod_Int &operator*=(const Mod_Int &p) {
        x = (int)(1LL * x * p.x % mod);
        return *this;
    }

    Mod_Int &operator/=(const Mod_Int &p) {
        *this *= p.inverse();
        return *this;
    }

    Mod_Int &operator++() {
        return *this += Mod_Int(1);
    }

    Mod_Int operator++(int) {
        Mod_Int tmp = *this;
        ++*this;
        return tmp;
    }

    Mod_Int &operator--() {
        return *this -= Mod_Int(1);
    }

    Mod_Int operator--(int) {
        Mod_Int tmp = *this;
        --*this;
        return tmp;
    }

    Mod_Int operator-() const {
        return Mod_Int(-x);
    }

    Mod_Int operator+(const Mod_Int &p) const {
        return Mod_Int(*this) += p;
    }

    Mod_Int operator-(const Mod_Int &p) const {
        return Mod_Int(*this) -= p;
    }

    Mod_Int operator*(const Mod_Int &p) const {
        return Mod_Int(*this) *= p;
    }

    Mod_Int operator/(const Mod_Int &p) const {
        return Mod_Int(*this) /= p;
    }

    bool operator==(const Mod_Int &p) const {
        return x == p.x;
    }

    bool operator!=(const Mod_Int &p) const {
        return x != p.x;
    }

    Mod_Int inverse() const {
        assert(*this != Mod_Int(0));
        return pow(mod - 2);
    }

    Mod_Int pow(long long k) const {
        Mod_Int now = *this, ret = 1;
        for (; k > 0; k >>= 1, now *= now) {
            if (k & 1)
                ret *= now;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const Mod_Int &p) {
        return os << p.x;
    }

    friend istream &operator>>(istream &is, Mod_Int &p) {
        long long a;
        is >> a;
        p = Mod_Int<mod>(a);
        return is;
    }
};

ll mpow2(ll x, ll n, ll mod) {
    ll ans = 1;
    x %= mod;
    while (n != 0) {
        if (n & 1)
            ans = ans * x % mod;
        x = x * x % mod;
        n = n >> 1;
    }
    ans %= mod;
    return ans;
}

ll modinv2(ll a, ll mod) {
    ll b = mod, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= mod;
    if (u < 0)
        u += mod;
    return u;
}

ll devide_int(ll a, ll b) {
    return (a >= 0 ? a / b : (a - b + 1) / b);
}

constexpr int mod = 1000000007;
// constexpr int mod = 998244353;
// constexpr int mod = 31607;
using mint = Mod_Int<mod>;

mint mpow(mint x, ll n) {
    bool rev = n < 0;
    n = abs(n);
    mint ans = 1;
    while (n != 0) {
        if (n & 1)
            ans *= x;
        x *= x;
        n = n >> 1;
    }
    return (rev ? ans.inverse() : ans);
}

// ----- library -------
// ----- library -------

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (1) {
        int n, m, q;
        cin >> n >> m >> q;
        if (!n)
            break;
        vector<string> s(q), b(q + 1, string(m, '0'));
        rep(i, q) cin >> s[i] >> b[i + 1];
        string ans(m, '?');
        rep(i, m) rep(j, n) {
            bool flag = true;
            rep(k, q) if ((b[k][i] - '0') ^ (b[k + 1][i] - '0') ^ (s[k][j] - '0')) flag = false;
            if (flag) {
                if (ans[i] != '?') {
                    ans[i] = '?';
                    break;
                }
                ans[i] = (j < 10 ? (char)('0' + j) : (char)('A' + j - 10));
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 440
memory_kb: 4568
final_rank: 9

code_snippet: #include <algorithm>
#include <bitset>
#include <complex>
#include <cassert>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

const long long INF = 1e9;
const long long MOD = 1e9 + 7;
// const long long MOD = 998244353;
const long long LINF = 1e18;
using namespace std;

#define YES(n) cout << ((n) ? "YES" : "NO") << endl
#define Yes(n) cout << ((n) ? "Yes" : "No") << endl
#define POSSIBLE(n) cout << ((n) ? "POSSIBLE" : "IMPOSSIBLE") << endl
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << endl
#define dump(x) cout << #x << " = " << (x) << endl
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define COUT(x) cout << (x) << endl
#define SCOUT(x) cout << (x) << " "
#define VECCOUT(x)           \
  for (auto &youso_ : (x))   \
    cout << right << youso_; \
  cout << endl
#define ENDL cout << endl
#define CIN(...)   \
  int __VA_ARGS__; \
  CINT(__VA_ARGS__)
#define LCIN(...)        \
  long long __VA_ARGS__; \
  CINT(__VA_ARGS__)
#define SCIN(...)     \
  string __VA_ARGS__; \
  CINT(__VA_ARGS__)
#define VECCIN(x)          \
  for (auto &youso_ : (x)) \
  cin >> youso_
#define mp make_pair
#define PQ priority_queue<long long>
#define PQG priority_queue<long long, V, greater<long long>>

typedef long long ll;
typedef vector<long long> vl;
typedef vector<long long> vi;
typedef vector<bool> vb;
typedef vector<char> vc;
typedef vector<vl> vvl;
typedef vector<vi> vvi;
typedef vector<vb> vvb;
typedef vector<vc> vvc;
typedef pair<long long, long long> pll;

#define COUT(x) cout << (x) << endl
void CINT()
{
}
template <class Head, class... Tail>
void CINT(Head &&head, Tail &&...tail)
{
  cin >> head;
  CINT(move(tail)...);
}
template <class T>
void mod(T &x)
{
  x %= MOD;
  x += MOD;
  x %= MOD;
}

ll GCD(ll a, ll b)
{
  if (b == 0)
    return a;
  else
    return GCD(b, a % b);
}

struct COMB
{
  vl fact, fact_inv, inv;
  void init_nCk(long long SIZE)
  {
    fact.resize(SIZE + 5);
    fact_inv.resize(SIZE + 5);
    inv.resize(SIZE + 5);
    fact.at(0) = fact.at(1) = fact_inv.at(0) = fact_inv.at(1) = inv.at(1) = 1;
    for (long long i = 2; i < SIZE + 5; i++)
    {
      fact.at(i) = fact.at(i - 1) * i % MOD;
      inv.at(i) = MOD - inv.at(MOD % i) * (MOD / i) % MOD;
      fact_inv.at(i) = fact_inv.at(i - 1) * inv.at(i) % MOD;
    }
  }
  long long nCk(long long n, long long k)
  {
    assert(!(n < k));
    assert(!(n < 0 || k < 0));
    return fact.at(n) * (fact_inv.at(k) * fact_inv.at(n - k) % MOD) % MOD;
  }
};
ll extGCD(ll a, ll b, ll &x, ll &y)
{
  if (b == 0)
  {
    x = 1;
    y = 0;
    return a;
  }
  ll d = extGCD(b, a % b, y, x);
  y -= a / b * x;
  return d;
}

void Main()
{
  ll N;
  while (cin >> N && N != 0)
  {
    LCIN(M, Q);
    vector<string> S(Q);
    vector<string> B(Q);
    for (int i = 0; i < Q; i++)
    {
      cin >> S.at(i) >> B.at(i);
      if (i)
      {
        for (int j = 0; j < N; j++)
        {
          if (S.at(i).at(j) == '1')
          {
            if (S.at(i - 1).at(j) == '1')
              S.at(i).at(j) = '0';
            else
              S.at(i).at(j) = '1';
          }
          else
          {
            S.at(i).at(j) = S.at(i - 1).at(j);
          }
        }
      }
    }
    vvl taiou(N, vl(M, 1));
    for (int m = 0; m < M; m++)
    {
      // light m について
      vl kouho(N, 1);
      for (int q = 0; q < Q; q++)
      {
        if (B.at(q).at(m) == '1')
          for (int i = 0; i < N; i++)
          {
            // switch i について
            if (S.at(q).at(i) == '0')
            {
              kouho.at(i) = 0;
            }
          }
        else if (B.at(q).at(m) == '0')
          for (int i = 0; i < N; i++)
          {
            // switch i について
            if (S.at(q).at(i) == '1')
            {
              kouho.at(i) = 0;
            }
          }
      }
      // VECCOUT(kouho);
      ll sum = accumulate(kouho.begin(), kouho.end(), 0);
      if (sum == 0)
      {
        kouho.at(-1) = 0;
        dump(sum);
      }
      else if (sum == 1)
      {
        for (int i = 0; i < N; i++)
        {
          if (kouho.at(i))
            if (i < 10)
              cout << i;
            else
              cout << (char)(i - 10 + 'A');
        }
      }
      else
      {
        cout << '?';
      }
      // dump("");
    }
    cout << endl;
  }
}

int main()
{
  cout << fixed << setprecision(15);
  Main();
  return 0;
}
accuracy: 1
time_ms: 1020
memory_kb: 5524
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

#ifdef _RUTHEN
#include "debug.hpp"
#else
#define show(...) true
#endif

using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); i++)
template <class T> using V = vector<T>;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N, M, Q;
    while (cin >> N >> M >> Q) {
        if (N == 0 and M == 0 and Q == 0) break;
        V<string> B(Q), S(Q);
        rep(i, Q) cin >> B[i] >> S[i];
        show(B, S);
        V<string> st(Q + 1, string(N, '0'));
        st[0] = string(N, '0');
        rep(i, Q) rep(j, N) st[i + 1][j] = ((st[i][j] - '0') ^ (B[i][j] - '0')) + '0';
        show(st);
        rep(i, M) {
            V<int> ansvec;
            rep(j, N) {
                int ok = 1;
                for (int k = 1; k <= Q; k++) {
                    if (st[k][j] != S[k - 1][i]) ok = 0;
                }
                if (ok) ansvec.push_back(j);
            }
            if (ansvec.size() == 1) {
                char o = (ansvec[0] < 10 ? '0' + ansvec[0] : 'A' + ansvec[0] - 10);
                cout << o;
            } else {
                cout << '?';
            }
        }
        cout << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 4684
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

int main(){
	int N, M, Q;
	while(1){
		cin >> N >> M >> Q;
		if(N == 0 && M == 0 && Q == 0)return 0;
		string s, t, ans(M, '?');
		vector<long long> tb(M, (1ll << N) - 1);
		long long cur = 0;
		for(int i = 0; i < Q; i++){
			cin >> s >> t;
			for(int j = 0; j < N; j++){
				if(s[j] == '1')cur ^= 1ll << j;
			}
			for(int j = 0; j < M; j++){
				tb[j] &= (t[j] == '1' ? cur : ~cur);
			}
		}
		for(int i = 0; i < M; i++){
			if(__builtin_popcountll(tb[i]) != 1)continue;
			int c = __lg(tb[i]);
			ans[i] = c < 10 ? c + '0' : c + 'A' - 10;
		}
		cout << ans << '\n';
	}
}
accuracy: 1
time_ms: 90
memory_kb: 3264
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
int main(void){
    int n, m, q;
    while(1){
        cin >> n >> m >> q;
        if(n == 0) break;
        vector<string> S(q);
        vector<string> B(q);
        string s;
        for(int i = 0; i < n; i++) s += '0';
        for(int i = 0; i < q; i++){
            cin >> S[i] >> B[i];
            for(int j = 0; j < n; j++){
                if(S[i][j] == '1'){
                    if(s[j] == '1') s[j] = '0';
                    else s[j] = '1';
                }
            }
            S[i] = s;
        }
        string ans;
        for(int i = 0; i < m; i++) ans += '?';
        for(int i = 0; i < m; i++){
            vector<bool> ok(n, true);
            for(int j = 0; j < q; j++){
                for(int k = 0; k < n; k++){
                    if(B[j][i] == '1' && S[j][k] == '0') ok[k] = false;
                    else if(B[j][i] == '0' && S[j][k] == '1') ok[k] = false;
                }
            }
            int cnt = 0;
            for(int j = 0; j < n; j++){
                if(ok[j]) cnt++;
            }
            if(cnt == 1){
                for(int j = 0; j < n; j++){
                    if(ok[j]){
                        if(j < 10) ans[i] = '0' + j;
                        else ans[i] = 'A' + j - 10;
                        break;
                    }
                }
            }
        }
        cout << ans << "\n";
    }
}
accuracy: 1
time_ms: 1080
memory_kb: 5424
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    while(true) {
        int N,M,Q; cin >> N >> M >> Q; if(N == 0) break;
        vector<string> S(Q + 1), B(Q + 1);
        rep(i,Q) cin >> S[i + 1] >> B[i + 1];
        rep(i,N) S[0].push_back('0');
        rep(i,M) B[0].push_back('0');

        vector<vector<bool>> f(M, vector<bool> (N, true));
        rep(i,M)rep(j,N)rep(k,Q) {
            if((S[k + 1][j] == '0') ^ (B[k][i] == B[k + 1][i])) f[i][j] = false;
        }

        vector<int> ans(M, -1);
        rep(i,M)rep(j,N) if(f[i][j]) ans[i] = (ans[i] == -1 ? j : -1e9);
        
        rep(i,M) {
            if(ans[i] == -1e9) {
                cout << '?';
            } else if(ans[i] <= 9) {
                cout << char(ans[i] + '0');
            } else {
                cout << char(ans[i] - 10 + 'A');
            }
        }cout << endl;
    }
}
accuracy: 1
time_ms: 1300
memory_kb: 4624
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {

  ios::sync_with_stdio(false);
  cin.tie(0);

  int n,m,q;
  cin >> n >> m >> q;
  while (n != 0) {
    vector<string> s(q),b(q);
    for (int i=0;i<q;i++) {
      cin >> s[i] >> b[i];
      reverse(s[i].begin(),s[i].end());
    }
    vector<long long> bs(q);
    for (int i=0;i<q;i++) {
      bs[i] = stoll(s[i],nullptr,2);
    }
    vector<long long> can(m,(1LL<<n)-1);
    string base = "";
    for (int i=0;i<m;i++) base += "0";
    for (int j=0;j<q;j++) {
      for (int i=0;i<m;i++) {
        if (base[i] != b[j][i]) {
          can[i] = can[i]&bs[j];
        }
        else {
          can[i] = can[i]&(~bs[j]);
        }
      }
      base = b[j];
    }
    for (int i=0;i<m;i++) {
      int las = -1;
      for (int j=0;j<n;j++) {
        if (can[i]&(1LL<<j)) {
          if (las > -1) {
            las = -2;
          }
          else if (las == -1) las = j;
        }
      }
      if (las == -2) cout << '?';
      else if (las < 10) cout << las;
      else cout << (char)(las-10+'A');
    }
    cout << endl;
    cin >> n >> m >> q;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 4620
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using P = pair<string,string>;

void solve(int N, int M, int Q){
  vector<P> vec(Q);
  for(int i=0; i<Q; i++){
    string a, b;
    cin >> a >> b;
    vec[i] = P(a,b);
  }
  vector<set<int>> S(M);
  for(int i=0; i<M; i++){
    for(int j=0; j<N; j++){
      S[i].insert(j);
    }
  }
  vector<int> cnt(N,0);
  for(int i=0; i<Q; i++){
    auto[a,b] = vec[i];
    for(int j=0; j<N; j++){
      if(a[j] == '1'){
        cnt[j]++;
      }
    }
    for(int j=0; j<M; j++){
      for(int k=0; k<N; k++){
        if(b[j] == '0' && cnt[k]%2 == 1){
          S[j].erase(k);
        }
        if(b[j] == '1' && cnt[k]%2 == 0){
          S[j].erase(k);
        }
      }
    }
  }
  string ans (M,'?');
  for(int i=0; i<M; i++){
    if(S[i].size() == 1){
      auto itr = S[i].begin();
      int x = *itr;
      if(x <= 9){
        ans[i] = '0' + x;
      }
      else{
        ans[i] = 'A' + x - 10;
      }
    }
  }
  cout << ans << endl;
}

int main(){
  while(true){
    int N, M, Q;
    cin >> N >> M >> Q;
    if(N == 0){
      break;
    }
    solve(N,M,Q);
  }
}
accuracy: 1
time_ms: 910
memory_kb: 6252
final_rank: 20

code_snippet: #line 1 "/Users/nok0/Documents/Programming/nok0/cftemp.hpp"
#include <bits/stdc++.h>
using namespace std;

#pragma region Macros
// rep macro
#define foa(v, a) for(auto &v : a)
#define REPname(a, b, c, d, e, ...) e
#define REP(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int i = 0; i < (x); ++i)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define REPSname(a, b, c, ...) c
#define REPS(...) REPSname(__VA_ARGS__, REPS1, REPS0)(__VA_ARGS__)
#define REPS0(x) for(int i = 1; i <= (x); ++i)
#define REPS1(i, x) for(int i = 1; i <= (x); ++i)
#define RREPname(a, b, c, d, e, ...) e
#define RREP(...) RREPname(__VA_ARGS__, RREP3, RREP2, RREP1, RREP0)(__VA_ARGS__)
#define RREP0(x) for(int i = (x)-1; i >= 0; --i)
#define RREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define RREP2(i, r, l) for(int i = (r)-1; i >= (l); --i)
#define RREP3(i, r, l, c) for(int i = (r)-1; i >= (l); i -= (c))
#define RREPSname(a, b, c, ...) c
#define RREPS(...) RREPSname(__VA_ARGS__, RREPS1, RREPS0)(__VA_ARGS__)
#define RREPS0(x) for(int i = (x); i >= 1; --i)
#define RREPS1(i, x) for(int i = (x); i >= 1; --i)

// name macro
#define pb push_back
#define eb emplace_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define popcnt(x) __builtin_popcountll(x)
template <class T = int>
using V = std::vector<T>;
template <class T = int>
using VV = std::vector<std::vector<T>>;
template <class T>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
using ll = long long;
using ld = long double;
using int128 = __int128_t;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;

// input macro
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
	is >> p.first >> p.second;
	return is;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
	for(T &i : v) is >> i;
	return is;
}
std::istream &operator>>(std::istream &is, __int128_t &a) {
	std::string s;
	is >> s;
	__int128_t ret = 0;
	for(int i = 0; i < s.length(); i++)
		if('0' <= s[i] and s[i] <= '9')
			ret = 10 * ret + s[i] - '0';
	a = ret * (s[0] == '-' ? -1 : 1);
	return is;
}
namespace scanner {
void scan(int &a) { std::cin >> a; }
void scan(long long &a) { std::cin >> a; }
void scan(std::string &a) { std::cin >> a; }
void scan(char &a) { std::cin >> a; }
void scan(char a[]) { std::scanf("%s", a); }
void scan(double &a) { std::cin >> a; }
void scan(long double &a) { std::cin >> a; }
template <class T, class U>
void scan(std::pair<T, U> &p) { std::cin >> p; }
template <class T>
void scan(std::vector<T> &a) { std::cin >> a; }
void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#define VEC(type, name, size)     \
	std::vector<type> name(size); \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                                    \
	std::vector<std::vector<type>> name(h, std::vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)             \
	std::string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHAR(...)     \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DOUBLE(...)     \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)

// output-macro
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &a) {
	for(int i = 0; i < int(a.size()); ++i) {
		if(i) os << " ";
		os << a[i];
	}
	return os;
}
std::ostream &operator<<(std::ostream &dest, __int128_t &value) {
	std::ostream::sentry s(dest);
	if(s) {
		__uint128_t tmp = value < 0 ? -value : value;
		char buffer[128];
		char *d = std::end(buffer);
		do {
			--d;
			*d = "0123456789"[tmp % 10];
			tmp /= 10;
		} while(tmp != 0);
		if(value < 0) {
			--d;
			*d = '-';
		}
		int len = std::end(buffer) - d;
		if(dest.rdbuf()->sputn(d, len) != len) {
			dest.setstate(std::ios_base::badbit);
		}
	}
	return dest;
}
template <class T>
void print(const T a) { std::cout << a << '\n'; }
template <class Head, class... Tail>
void print(Head H, Tail... T) {
	std::cout << H << ' ';
	print(T...);
}
template <class T>
void printel(const T a) { std::cout << a << '\n'; }
template <class T>
void printel(const std::vector<T> &a) {
	for(const auto &v : a)
		std::cout << v << '\n';
}
template <class Head, class... Tail>
void printel(Head H, Tail... T) {
	std::cout << H << '\n';
	printel(T...);
}
void Yes(const bool b = true) { std::cout << (b ? "Yes\n" : "No\n"); }
void No() { std::cout << "No\n"; }
void YES(const bool b = true) { std::cout << (b ? "YES\n" : "NO\n"); }
void NO() { std::cout << "NO\n"; }
void err(const bool b = true) {
	if(b) {
		std::cout << "-1\n", exit(0);
	}
}

//debug macro
namespace debugger {
template <class T>
void view(const std::vector<T> &a) {
	std::cerr << "{ ";
	for(const auto &v : a) {
		std::cerr << v << ", ";
	}
	std::cerr << "\b\b }";
}
template <class T>
void view(const std::vector<std::vector<T>> &a) {
	std::cerr << "{\n";
	for(const auto &v : a) {
		std::cerr << "\t";
		view(v);
		std::cerr << "\n";
	}
	std::cerr << "}";
}
template <class T, class U>
void view(const std::vector<std::pair<T, U>> &a) {
	std::cerr << "{\n";
	for(const auto &p : a) std::cerr << "\t(" << p.first << ", " << p.second << ")\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &p : m) std::cerr << "\t[" << p.first << "] : " << p.second << "\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::pair<T, U> &p) { std::cerr << "(" << p.first << ", " << p.second << ")"; }
template <class T>
void view(const std::set<T> &s) {
	std::cerr << "{ ";
	for(auto &v : s) {
		view(v);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <class T>
void view(const T &e) { std::cerr << e; }
}  // namespace debugger
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	debugger::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(false)
#else
#define debug(...) (void(0))
#endif

// vector macro
template <class T>
int lb(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x))); }
template <class T>
int ub(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x))); }
template <class T>
void UNIQUE(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<T> press(std::vector<T> &a) {
	auto res = a;
	UNIQUE(res);
	for(auto &v : a)
		v = lb(res, v);
	return res;
}
#define SORTname(a, b, c, ...) c
#define SORT(...) SORTname(__VA_ARGS__, SORT1, SORT0, ...)(__VA_ARGS__)
#define SORT0(a) std::sort((a).begin(), (a).end())
#define SORT1(a, c) std::sort((a).begin(), (a).end(), [](const auto x, const auto y) { return x c y; })
template <class T>
void ADD(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v += x;
}
template <class T>
void SUB(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v -= x;
}
template <class T>
void MUL(std::vector<T> &a, const T x) {
	for(auto &v : a) v *= x;
}
template <class T>
void DIV(std::vector<T> &a, const T x) {
	for(auto &v : a) v /= x;
}
std::vector<std::pair<char, int>> rle(const string &s) {
	int n = s.size();
	std::vector<std::pair<char, int>> ret;
	for(int l = 0; l < n;) {
		int r = l + 1;
		for(; r < n and s[l] == s[r]; r++) {}
		ret.emplace_back(s[l], r - l);
		l = r;
	}
	return ret;
}
template <class T>
std::vector<std::pair<T, int>> rle(const std::vector<T> &v) {
	int n = v.size();
	std::vector<std::pair<T, int>> ret;
	for(int l = 0; l < n;) {
		int r = l + 1;
		for(; r < n and v[l] == v[r]; r++) {}
		ret.emplace_back(v[l], r - l);
		l = r;
	}
	return ret;
}

// math macro
template <class T, class U>
inline bool chmin(T &a, const U &b) { return a > b ? a = b, true : false; }
template <class T, class U>
inline bool chmax(T &a, const U &b) { return a < b ? a = b, true : false; }
template <class T>
T divup(T x, T y) { return (x + y - 1) / y; }
template <class T>
T POW(T a, long long n) {
	T ret = 1;
	while(n) {
		if(n & 1) ret *= a;
		a *= a;
		n >>= 1;
	}
	return ret;
}
// modpow
long long POW(long long a, long long n, const int mod) {
	long long ret = 1;
	a = (a % mod + mod) % mod;
	while(n) {
		if(n & 1) (ret *= a) %= mod;
		(a *= a) %= mod;
		n >>= 1;
	}
	return ret;
}

// others
struct fast_io {
	fast_io() {
		ios::sync_with_stdio(false);
		cin.tie(nullptr);
		cout << fixed << setprecision(15);
	}
} fast_io_;
const int inf = 1e9;
const ll INF = 1e18;
#pragma endregion

void main_();

int main() {
	main_();
	return 0;
}
#line 2 "a.cpp"

void main_() {
	while(1) {
		INT(n, m, q);
		if(!n) break;
		V<string> s(q), b(q);
		REP(i, q) { cin >> s[i] >> b[i]; }
		V<> res(m, -1);
		REP(j, m) {
			set<int> candi;
			REP(c, n) {
				bool ok = 1;
				REP(i, q) {
					int ch = s[i][c] == '1';
					ok &= ch == (b[i][j] != (i ? b[i - 1][j] : '0'));
				}
				if(ok) candi.insert(c);
			}
			if(SZ(candi) == 1) res[j] = *candi.begin();
		}
		REP(i, m) {
			if(res[i] == -1)
				cout << '?';
			else if(res[i] <= 9)
				cout << res[i];
			else
				cout << (char)('A' + res[i] - 10);
		}
		cout << endl;
	}
}
accuracy: 1
time_ms: 680
memory_kb: 4396
final_rank: 11

code_snippet: #ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
 
#include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
 
#pragma region Macros
// rep macro
#define foa(v, a) for(auto &v : a)
#define REPname(a, b, c, d, e, ...) e
#define REP(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int i = 0; i < (x); ++i)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define REPSname(a, b, c, ...) c
#define REPS(...) REPSname(__VA_ARGS__, REPS1, REPS0)(__VA_ARGS__)
#define REPS0(x) for(int i = 1; i <= (x); ++i)
#define REPS1(i, x) for(int i = 1; i <= (x); ++i)
#define RREPname(a, b, c, d, e, ...) e
#define RREP(...) RREPname(__VA_ARGS__, RREP3, RREP2, RREP1, RREP0)(__VA_ARGS__)
#define RREP0(x) for(int i = (x)-1; i >= 0; --i)
#define RREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define RREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define RREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))
#define RREPSname(a, b, c, ...) c
#define RREPS(...) RREPSname(__VA_ARGS__, RREPS1, RREPS0)(__VA_ARGS__)
#define RREPS0(x) for(int i = (x); i >= 1; --i)
#define RREPS1(i, x) for(int i = (x); i >= 1; --i)
 
// name macro
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define popcnt(x) __builtin_popcountll(x)
template <class T = int>
using V = std::vector<T>;
template <class T = int>
using VV = std::vector<std::vector<T>>;
template <class T = int>
using VVV = std::vector<std::vector<std::vector<T>>>;
template <class T>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
using ll = long long;
using ld = long double;
using int128 = __int128_t;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
using Tp = tuple<ll,ll,ll>;
 
// input macro
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
	is >> p.first >> p.second;
	return is;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
	for(T &i : v) is >> i;
	return is;
}
std::istream &operator>>(std::istream &is, __int128_t &a) {
	std::string s;
	is >> s;
	__int128_t ret = 0;
	for(int i = 0; i < s.length(); i++)
		if('0' <= s[i] and s[i] <= '9')
			ret = 10 * ret + s[i] - '0';
	a = ret * (s[0] == '-' ? -1 : 1);
	return is;
}
namespace scanner {
void scan(int &a) { std::cin >> a; }
void scan(long long &a) { std::cin >> a; }
void scan(std::string &a) { std::cin >> a; }
void scan(char &a) { std::cin >> a; }
void scan(char a[]) { std::scanf("%s", a); }
void scan(double &a) { std::cin >> a; }
void scan(long double &a) { std::cin >> a; }
template <class T, class U>
void scan(std::pair<T, U> &p) { std::cin >> p; }
template <class T>
void scan(std::vector<T> &a) { std::cin >> a; }
void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#define VEC(type, name, size)     \
	std::vector<type> name(size); \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                                    \
	std::vector<std::vector<type>> name(h, std::vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)             \
	std::string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHAR(...)     \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DOUBLE(...)     \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
 
// output-macro
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &a) {
	for(int i = 0; i < int(a.size()); ++i) {
		if(i) os << " ";
		os << a[i];
	}
	return os;
}
std::ostream &operator<<(std::ostream &dest, __int128_t &value) {
	std::ostream::sentry s(dest);
	if(s) {
		__uint128_t tmp = value < 0 ? -value : value;
		char buffer[128];
		char *d = std::end(buffer);
		do {
			--d;
			*d = "0123456789"[tmp % 10];
			tmp /= 10;
		} while(tmp != 0);
		if(value < 0) {
			--d;
			*d = '-';
		}
		int len = std::end(buffer) - d;
		if(dest.rdbuf()->sputn(d, len) != len) {
			dest.setstate(std::ios_base::badbit);
		}
	}
	return dest;
}
template <class T>
void print(const T a) { std::cout << a << '\n'; }
template <class Head, class... Tail>
void print(Head H, Tail... T) {
	std::cout << H << ' ';
	print(T...);
}
template <class T>
void printel(const T a) { std::cout << a << '\n'; }
template <class T>
void printel(const std::vector<T> &a) {
	for(const auto &v : a)
		std::cout << v << '\n';
}
template <class Head, class... Tail>
void printel(Head H, Tail... T) {
	std::cout << H << '\n';
	printel(T...);
}
void Yes(const bool b = true) { std::cout << (b ? "Yes\n" : "No\n"); }
void No() { std::cout << "No\n"; }
void YES(const bool b = true) { std::cout << (b ? "YES\n" : "NO\n"); }
void NO() { std::cout << "No\n"; }
void err(const bool b = true) {
	if(b) {
		std::cout << "-1\n", exit(0);
	}
}
 
//debug macro
namespace debugger {
template <class T>
void view(const std::vector<T> &a) {
	std::cerr << "{ ";
	for(const auto &v : a) {
		std::cerr << v << ", ";
	}
	std::cerr << "\b\b }";
}
template <class T>
void view(const std::vector<std::vector<T>> &a) {
	std::cerr << "{\n";
	for(const auto &v : a) {
		std::cerr << "\t";
		view(v);
		std::cerr << "\n";
	}
	std::cerr << "}";
}
template <class T, class U>
void view(const std::vector<std::pair<T, U>> &a) {
	std::cerr << "{\n";
	for(const auto &p : a) std::cerr << "\t(" << p.first << ", " << p.second << ")\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &p : m) std::cerr << "\t[" << p.first << "] : " << p.second << "\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::pair<T, U> &p) { std::cerr << "(" << p.first << ", " << p.second << ")"; }
template <class T>
void view(const std::set<T> &s) {
	std::cerr << "{ ";
	for(auto &v : s) {
		view(v);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}
 
template <class T>
void view(const T &e) { std::cerr << e; }
}  // namespace debugger
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	debugger::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(false)
#else
#define debug(...) (void(0))
#endif
 
// vector macro
template <class T>
int lb(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x))); }
template <class T>
int ub(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x))); }
template <class T>
void UNIQUE(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<T> press(std::vector<T> &a) {
	auto res = a;
	UNIQUE(res);
	for(auto &v : a)
		v = lb(res, v);
	return res;
}
#define SORTname(a, b, c, ...) c
#define SORT(...) SORTname(__VA_ARGS__, SORT1, SORT0, ...)(__VA_ARGS__)
#define SORT0(a) std::sort((a).begin(), (a).end())
#define SORT1(a, c) std::sort((a).begin(), (a).end(), [](const auto x, const auto y) { return x c y; })
template <class T>
void ADD(std::vector<T> &a, const T x) {
	for(auto &v : a) v += x;
}
template <class T>
void SUB(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v -= x;
}
template <class T>
void MUL(std::vector<T> &a, const T x) {
	for(auto &v : a) v *= x;
}
template <class T>
void DIV(std::vector<T> &a, const T x) {
	for(auto &v : a) v /= x;
}
 
// math macro
template <class T, class U>
inline bool chmin(T &a, const U &b) { return a > b ? a = b, true : false; }
template <class T, class U>
inline bool chmax(T &a, const U &b) { return a < b ? a = b, true : false; }
template <class T>
T divup(T x, T y) { return (x + y - 1) / y; }
template <class T>
T POW(T a, long long n) {
	T ret = 1;
	while(n) {
		if(n & 1) ret *= a;
		a *= a;
		n >>= 1;
	}
	return ret;
}

template<typename T>
T ADD(T a, T b){
	T res;
	return __builtin_add_overflow(a, b, &res) ? numeric_limits<T>::max() : res;
}

template<typename T>
T MUL(T a, T b){
	T res;
	return __builtin_mul_overflow(a, b, &res) ? numeric_limits<T>::max() : res;
}

// modpow
long long POW(long long a, long long n, const int mod) {
	long long ret = 1;
	while(n) {
		if(n & 1) (ret *= a) %= mod;
		(a *= a) %= mod;
		n >>= 1;
	}
	return ret;
}
 
// others
struct fast_io {
	fast_io() {
		ios::sync_with_stdio(false);
		cin.tie(nullptr);
		cout << fixed << setprecision(15);
	}
} fast_io_;

#pragma endregion

using R = long double;
constexpr R EPS=1E-11;

// r の(誤差付きの)符号に従って, -1, 0, 1 を返す.
int sgn(const R& r){ return (r > EPS) - (r < -EPS); }
// a, b の(誤差付きの)大小比較の結果に従って, -1, 0, 1 を返す.
int sgn(const R& a, const R &b){ return sgn(a-b); }
// a > 0 は sgn(a) > 0
// a < b は sgn(a, b) < 0
// a >= b は sgn(a, b) >= 0
// のように書く.
// return s * 10^n

//https://atcoder.jp/contests/abc191/submissions/20028529
long long x10(const string& s, size_t n) {
    if (s.front() == '-') return -x10(s.substr(1), n);
    auto pos = s.find('.');
    if (pos == string::npos) return stoll(s + string(n, '0'));
    return stoll(s.substr(0, pos) + s.substr(pos + 1) + string(n + pos + 1 - s.size(), '0'));
}
 
long long ceildiv(long long a, long long b) {
    if (b < 0) a = -a, b = -b;
    if (a >= 0) return (a + b - 1) / b;
    else return a / b;
}
 
long long floordiv(long long a, long long b) {
    if (b < 0) a = -a, b = -b;
    if (a >= 0) return a / b;
    else return (a - b + 1) / b;
}
 
long long floorsqrt(long long x) {
    assert(x >= 0);
    long long ok = 0;
    long long ng = 1;
    while (ng * ng <= x) ng <<= 1;
    while (ng - ok > 1) {
        long long mid = (ng + ok) >> 1;
        if (mid * mid <= x) ok = mid;
        else ng = mid;
    }
    return ok;
}

inline int topbit(unsigned long long x){
	return x?63-__builtin_clzll(x):-1;
}

inline int popcount(unsigned long long x){
	return __builtin_popcountll(x);
}

inline int parity(unsigned long long x){//popcount%2
	return __builtin_parity(x);
}

const int inf = 1e9;
const ll INF = 1e18;

void main_() {
    ll N,M,Q;
    cin >> N >> M >> Q;
    while(N != 0){
        V<ll> ans(M,-1);
        V<string> A, B;
        string v = "";
        
        REP(i,M)v += '0';
        B.push_back(v);
        REP(i,Q){
            string s,t;
            cin >> s >> t;
            A.push_back(s);
            B.push_back(t);
        }
        REP(i,M){
            V<ll> c;
            REP(j,N){
                bool ok = true;
                REP(k,Q){
                    if((A[k][j] == '1') != (B[k][i] != B[k+1][i]))ok = false;
                }
                if(ok)c.push_back(j);
            }
            
            if(c.size() >= 2)continue;
            ans[i] = c[0];
        }
        REP(i,M){
            char c;
            if(ans[i] == -1)c = '?';
            else if(ans[i] <= 9)c = '0' + ans[i];
            else{
                ans[i] -= 10;
                c = 'A' + ans[i];
            }
            cout << c;
        }
        cout << endl;
        cin >> N >> M >> Q;
    }
}

int main() {
	int t = 1;
	//cin >> t;
	while(t--)main_();
	return 0;
}
accuracy: 1
time_ms: 690
memory_kb: 4588
final_rank: 12

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-8;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

int main(){
    while(1){
        int n,m,q; cin >> n >> m >> q;
        if(!n) break;
        vs T(q), s(q), t(q);
        rep(i,q) cin >> s[i] >> T[i];
        t[0] = T[0];
        rep(i,q-1){
            t[i+1].resize(m);
            rep(j,m) t[i+1][j] = ((T[i][j] - '0') ^ (T[i+1][j] - '0')) + '0';
        }
        vl v(n);
        vl ans(m,-1);
        rep(i,m){
            rep(k,n) v[k] = 1;
            rep(j,q){
                if(t[j][i] == '1'){
                    rep(k,n) if(s[j][k] == '0') v[k] = 0;
                }else{
                    rep(k,n) if(s[j][k] == '1') v[k] = 0;
                }
            }
            if(accumulate(all(v),0) == 1){
                ans[i] = max_element(all(v)) - v.begin();
            }
        }
        rep(i,m){
            if(ans[i] == -1) cout << "?";
            else if(ans[i] >= 10) cout << (char)(ans[i] - 10 + 'A');
            else cout << ans[i];
        }
        cout << "\n";
    }
}
accuracy: 1
time_ms: 800
memory_kb: 6184
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<(n);i++)
#define ALL(v) v.begin(),v.end()

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

int main(){
  int n,m,q;
  while(cin>>n>>m>>q,n){
    vector<set<int>> se(m);
    REP(i,m)REP(j,n)se[i].insert(j);
    string pre=string('0',n);
    REP(_,q){
      string s,t;cin>>s>>t;
      REP(i,n)if(pre[i]=='1'){
        if(s[i]=='1')s[i]='0';
        else s[i]='1';
      }
      pre=s;
      REP(i,m){
        if(t[i]=='1')REP(j,n)if(s[j]=='0')se[i].erase(j);
        if(t[i]=='0')REP(j,n)if(s[j]=='1')se[i].erase(j);
      }
    }
    REP(i,m)
      if(se[i].size()==1)cout<<F(*se[i].begin());
      else cout<<"?";
    cout<<endl;
    /*REP(i,m){
      cout<<i<<":"<<se[i].size()<<endl;
      for(int p:se[i])cout<<p<<" ";cout<<endl;
    }*/
  }

}
accuracy: 1
time_ms: 850
memory_kb: 5112
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

ll readbin() {
    string s;
    cin >> s;
    reverse(begin(s), end(s));
    ll ret = 0;
    for (auto&& c : s) {
        ret *= 2;
        ret += c - '0';
    }
    return ret;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int N, M, Q;
    while (cin >> N >> M >> Q, N) {
        vector<ll> S(Q);
        vector<string> B(Q);
        ll bef = 0;
        for (int i = 0; i < Q; i++) {
            S[i] = readbin();
            S[i] ^= bef;
            bef = S[i];
            cin >> B[i];
        }
        S.emplace_back(0);
        B.emplace_back("");
        for (int i = 0; i < M; i++) {
            B.back() += '0';
        }
        S.emplace_back((1ll << N) - 1);
        B.emplace_back("");
        for (int i = 0; i < M; i++) {
            B.back() += '1';
        }
        Q += 2;
        string ans;
        for (int i = 0; i < M; i++) {
            ll maine = (1ll << N) - 1;
            for (int j = 0; j < Q; j++) {
                if (B[j][i] == '0')
                    maine &= ~S[j];
                else
                    maine &= S[j];
            }
            if (maine == (maine & -maine)) {
                int x = __builtin_ctzll(maine);
                if (x < 10)
                    ans += to_string(x);
                else
                    ans += x - 10 + 'A';
            } else
                ans += '?';
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 4344
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

ll readbin() {
    string s;
    cin >> s;
    reverse(begin(s), end(s));
    ll ret = 0;
    for (auto&& c : s) {
        ret *= 2;
        ret += c - '0';
    }
    return ret;
}

int main() {
    int N, M, Q;
    while (cin >> N >> M >> Q, N) {
        vector<ll> S(Q);
        vector<string> B(Q);
        ll bef = 0;
        for (int i = 0; i < Q; i++) {
            S[i] = readbin();
            S[i] ^= bef;
            bef = S[i];
            cin >> B[i];
        }
        S.emplace_back(0);
        B.emplace_back("");
        for (int i = 0; i < M; i++) {
            B.back() += '0';
        }
        S.emplace_back((1ll << N) - 1);
        B.emplace_back("");
        for (int i = 0; i < M; i++) {
            B.back() += '1';
        }
        Q += 2;
        string ans;
        for (int i = 0; i < M; i++) {
            ll maine = (1ll << N) - 1;
            for (int j = 0; j < Q; j++) {
                if (B[j][i] == '0')
                    maine &= ~S[j];
                else
                    maine &= S[j];
            }
            if (maine == (maine & -maine)) {
                int x = __builtin_ctzll(maine);
                if (x < 10)
                    ans += to_string(x);
                else
                    ans += x - 10 + 'A';
            } else
                ans += '?';
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 120
memory_kb: 5080
final_rank: 6