Problem:
What is the Number in my Mind ?
Let us enjoy a number guess game.
A number containing L digits is in my mind (where 4 <= L <= 10). You 
should guess what number it is. It is composed of any of the following ten 
digits:
"0","1","2","3","4","5","6","7","8", and "9".
No digits appear twice in the number. For example, when L = 4, "1234" is a 
legitimate candidate but "1123" is not (since "1" appears twice).
The number may begin with "0", and a number "05678" should be distinct from a 
number "5678", for example.
If you and your computer cannot see through my mind by telepathy, a group of
hints
will be needed in order for you to identify the number in my mind. 
A
hint
is a triple of numbers named
try
,
hit
, and
blow
.
The
try
is a number containing L decimal digits. No digits appear 
twice in the
try
, and this number may also begin with "0".
The
hit
value indicates the count of digits that the
try
and 
the number in my mind have in common, and that are exactly in the same position.
The
blow
value indicates the count of digits that the
try
and 
the number in my mind have in common, but that are NOT in the same position.
They are arranged in one line as follows.
try hit blow
For example, if L = 4 and the number in my mind is
9876
, then the 
following is an example of hint-set consisting of legitimate hints.
7360 0 2
2507 0 1
9713 1 1
9678 2 2
The above hint-set should be sufficient for you to guess the number and  
the answer should be
9876
.
In contrast, the following hint-set is not sufficient to guess the 
number.
7360 0 2
9713 1 1
9678 2 2
No number is consistent with the following hint-set.
9678 2 2
1234 2 2
Answers for last two hint-sets should be
NO
.
Your job is to write a program identifying the numbers in my mind using given 
hint-sets.
Input
The input consists of multiple hint-sets as follows. Each of them corresponds 
to a number in my mind.
< HINT-SET
1
>
< HINT-SET
2
>
. . .
< HINT-SET
i
>
. . .
< HINT-SET
n
>
A
<HINT-SET
i
>
is composed of one header line in the 
following format (
L
and
H
should be separated by a single space 
character.):
L
H
and
H
lines of hints in the following format (1 <= j <=
H
) :
TRY
1
HIT
1
BLOW
1
TRY
2
HIT
2
BLOW
2
. . .
TRY
j
HIT
j
BLOW
j
. . .
TRY
H
HIT
H
BLOW
H
L
indicates the number of digits of the number in my mind and
TRY
j
.
HIT
j
and
BLOW
j
indicate hit and blow values between the
TRY
j
and the number  
in my mind. (They are separated by a single space character.)
The end of the input is indicated by a header line with
L
= 0 and
H
= 0.
Output
For each hint-set, the answer should be printed, each in a separate line. If 
you can successfully identify the number for a given hint-set, the answer should 
be the number. If you cannot identify the number, the answer should be
NO
.
Sample Input
6 4
160348 0 4
913286 2 3
431289 3 1
671283 3 3
10 8
3827690415 2 8
0482691573 1 9
1924730586 3 7
1378490256 1 9
6297830541 1 9
4829531706 3 7
4621570983 1 9
9820147536 6 4
4 4
2713 0 3
1247 2 0
1230 1 1
1387 2 1
6 
...(truncated)

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) for(ll i=0;i<n;i++)
#define ALL(A) A.begin(),A.end()
int main(){
    while(1){
        ll N,M;cin>>N>>M;
        if(!N)return 0;
        vector<string>S(M);
        vi H(M),B(M);
        REP(i,M)cin>>S[i]>>H[i]>>B[i];
        vi T(M);
        REP(i,M)REP(j,N)T[i]+=1<<(S[i][j]-'0');
        vector<ll>K;
        REP(i,1<<10)if(__builtin_popcount(i)==N){
            bool ok=1;
            REP(j,M)if(__builtin_popcount(T[j]&i)!=B[j]+H[j]){ok=0;break;}
            if(ok)K.emplace_back(i);
        }
        string ans="NO";
        for(auto b:K){
            string s;
            REP(i,10)if((b>>i)%2)s+='0'+i;
            do{
                bool ok=1;
                REP(i,M){
                    ll h=0;
                    REP(j,N)if(S[i][j]==s[j])h++;
                    if(h!=H[i]){ok=0;break;}
                }
                if(ok){
                    if(ans=="NO")ans=s;
                    else{ans="YES";break;}
                }
            }while(next_permutation(ALL(s)));
            if(ans=="YES"){ans="NO";break;}
        }
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 920
memory_kb: 3360
final_rank: 3

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

pair<int,int> calc(string &s, string &t){
    int n = s.length();
    int hit = 0;
    int snum[10]={}, tnum[10]={};
    for(int i=0; i<n; i++){
        if(s[i] == t[i]) hit++;
        snum[s[i]-'0']++;
        tnum[t[i]-'0']++;
    }
    int blow = 0;
    for(int i=0; i<10; i++){
        if(snum[i]>0 and tnum[i]>0) blow++;
    }
    return {hit, blow-hit};
}

int main(){
    int fact[11];
    fact[1] = 1;
    for(int i=2; i<=10; i++){
        fact[i] = fact[i-1]*i;
    }
    while(1){
        int n,m;
        cin >> n >> m;
        if(n == 0) break;

        vector<string> tr(m);
        vector<int> hit(m), blow(m);
        for(int i=0; i<m; i++){
            cin >> tr[i] >> hit[i] >> blow[i];
        }

        string s = "0123456789";
        vector<int> use(10, 0);
        for(int i=0; i<n; i++){
            use[9-i] = 1;
        }
        int ans_num = 0;
        string ans;
        do{
            string t = "";
            for(int i=0; i<10; i++){
                if(use[i]) t += s[i];
            }
            bool ok = true;
            for(int i=0; i<m; i++){
                auto ret = calc(t, tr[i]);
                if(hit[i]+blow[i] != ret.first+ret.second){
                    ok = false;
                }
            }
            if(!ok) continue;
            do{
                bool ok = true;
                for(int i=0; i<m; i++){
                    auto ret = calc(t, tr[i]);
                    if(hit[i] != ret.first or blow[i] != ret.second){
                        ok = false;
                        break;
                    }
                }
                if(ok){
                    ans_num++;
                    ans = t;
                }
                if(ans_num > 1) break;
            }while(next_permutation(t.begin(), t.end()));
            if(ans_num > 1) break;
        }while(next_permutation(use.begin(), use.end()));
        if(ans_num == 1){
            cout << ans << endl;
        }else{
            cout << "NO" << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 5680
memory_kb: 3188
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

template <class BI>
bool next_partial_permutation(BI first, BI middle, BI last){
    reverse(middle, last);
    return next_permutation(first, last);
}

pair<int,int> calc(string &s, string &t){
    int n = s.length();
    int hit = 0;
    int snum[10]={}, tnum[10]={};
    for(int i=0; i<n; i++){
        if(s[i] == t[i]) hit++;
        snum[s[i]-'0']++;
        tnum[t[i]-'0']++;
    }
    int blow = 0;
    for(int i=0; i<10; i++){
        if(snum[i]>0 and tnum[i]>0) blow++;
    }
    return {hit, blow-hit};
}
int calc_hitblow(string &s, string &t){
    int n = s.length();
    int snum[10]={}, tnum[10]={};
    for(int i=0; i<n; i++){
        snum[s[i]-'0']++;
        tnum[t[i]-'0']++;
    }
    int res = 0;
    for(int i=0; i<10; i++){
        if(snum[i]>0 and tnum[i]>0) res++;
    }
    return res;
}

int main(){
    int fact[11];
    fact[1] = 1;
    for(int i=2; i<=10; i++){
        fact[i] = fact[i-1]*i;
    }
    while(1){
        int n,m;
        cin >> n >> m;
        if(n == 0) break;

        vector<string> tr(m);
        vector<int> hit(m), blow(m);
        for(int i=0; i<m; i++){
            cin >> tr[i] >> hit[i] >> blow[i];
        }

        string s = "0123456789";
        vector<int> use(10, 0);
        for(int i=0; i<n; i++){
            use[9-i] = 1;
        }
        int ans_num = 0;
        string ans;
        do{
            string t = "";
            for(int i=0; i<10; i++){
                if(use[i]) t += s[i];
            }
            bool ok = true;
            for(int i=0; i<m; i++){
                if(calc_hitblow(t, tr[i]) != hit[i]+blow[i]){
                    ok = false;
                }
            }
            if(!ok) continue;
            do{
                bool ok = true;
                for(int i=0; i<m; i++){
                    auto ret = calc(t, tr[i]);
                    if(hit[i] != ret.first or blow[i] != ret.second){
                        ok = false;
                        break;
                    }
                }
                if(ok){
                    ans_num++;
                    ans = t;
                }
                if(ans_num > 1) break;
            }while(next_permutation(t.begin(), t.end()));
        }while(next_permutation(use.begin(), use.end()));
        if(ans_num == 1){
            cout << ans << endl;
        }else{
            cout << "NO" << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 5200
memory_kb: 3200
final_rank: 14

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
    vector<vector<int>> sub;
    for(int i = 1; i < 1<<10; i++){
        vector<int> x;
        for(int j = 0; j < 10; j++) if((i>>j)&1)    x.push_back(j);
        sub.push_back(x);
    }

    int n, m;
    while(cin >> n >> m, n){
        vector<string> a(m);
        vector<int> b(m), c(m);
        for(int i = 0; i < m; i++)  cin >> a[i] >> b[i] >> c[i];
        vector<vector<bool>> origin(m, vector<bool>(10,0));
        for(int i = 0; i < m; i++){
            for(char c : a[i])  origin[i][c-'0'] = true;
        }
        bool no = false;
        vector<string> ans;
        for(vector<int> x : sub){
            if(x.size() != n) continue;
            do{
                bool valid = true;
                for(int j = 0; valid && j < m; j++){
                    int blow = 0, hit = 0;
                    for(int k = 0; k < n; k++){
                        hit += a[j][k]-'0'==x[k];
                        blow += origin[j][x[k]];
                    }
                    blow -= hit;
                    valid &= b[j]==hit && c[j]==blow;
                }
                if(valid){
                    if(ans.size()){
                        no = true;
                        break;
                    }
                    string tmp = "";
                    for(int j = 0; j < n; j++)  tmp += (char)('0'+x[j]);
                    ans.push_back(tmp);
                }
            }while(next_permutation(x.begin(),x.end()));
            sort(x.begin(), x.end());
            if(no)  break;
        }
        if(ans.size() == 0 || no)  cout << "NO" << endl;
        else    cout << ans[0] << endl;

    }
    return 0;
}
accuracy: 1
time_ms: 6200
memory_kb: 3204
final_rank: 16

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
    vector<vector<int>> sub;
    for(int i = 1; i < 1<<10; i++){
        vector<int> x;
        for(int j = 0; j < 10; j++) if((i>>j)&1)    x.push_back(j);
        sub.push_back(x);
    }

    int n, m;
    while(cin >> n >> m, n){
        vector<string> a(m);
        vector<int> b(m), c(m);
        for(int i = 0; i < m; i++)  cin >> a[i] >> b[i] >> c[i];
        vector<vector<bool>> origin(m, vector<bool>(10,0));
        for(int i = 0; i < m; i++){
            for(char c : a[i])  origin[i][c-'0'] = true;
        }
        bool no = false;
        vector<string> ans;
        for(vector<int> &x : sub){
            if(x.size() != n) continue;
            do{
                bool valid = true;
                for(int j = 0; valid && j < m; j++){
                    int blow = 0, hit = 0;
                    for(int k = 0; k < n; k++){
                        hit += a[j][k]-'0'==x[k];
                        blow += origin[j][x[k]];
                    }
                    blow -= hit;
                    valid &= b[j]==hit && c[j]==blow;
                }
                if(valid){
                    if(ans.size()){
                        no = true;
                        break;
                    }
                    string tmp = "";
                    for(int j = 0; j < n; j++)  tmp += (char)('0'+x[j]);
                    ans.push_back(tmp);
                }
            }while(next_permutation(x.begin(),x.end()));
            sort(x.begin(), x.end());
            if(no)  break;
        }
        if(ans.size() == 0 || no)  cout << "NO" << endl;
        else    cout << ans[0] << endl;

    }
    return 0;
}
accuracy: 1
time_ms: 6730
memory_kb: 3128
final_rank: 17

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	int hit,blow;
	char num[11];
};

vector<Info> info;
int Keta,num_candidate;
ll POW[12] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000};
ll ans;

int calc_hit(char left[11],char right[11]){

	int hit = 0;

	for(int i = 0; i < Keta; i++){
		if(left[i] == right[i])hit++;
	}
	return hit;
}

int calc_blow(char left[11],char right[11],int right_num){

	int blow = 0;

	int check_left[10];
	for(int i = 0; i < 10; i++)check_left[i] = -1;
	for(int i = 0; i < Keta; i++){
		check_left[left[i]-'0'] = i;
	}

	for(int i = 0; i < right_num;i++){
		if(check_left[right[i]-'0'] != -1 && check_left[right[i]-'0'] != i)blow++;
	}
	return blow;
}



void recursive(char buf[11],bool used[10],int count){
	if(num_candidate > 1)return;

	bool FLG;

	if(count == Keta){

		FLG = true;
		for(int i = 0; i < info.size(); i++){
			if(calc_blow(info[i].num,buf,count) != info[i].blow || calc_hit(info[i].num,buf) != info[i].hit){
				FLG = false;
				break;
			}
		}

		if(FLG){
			num_candidate++;
			if(num_candidate >= 2){
				return;
			}
			ans = 0;
			for(int i = 0; i < count; i++){
				ans = 10*ans + buf[i] - '0';
			}
		}

		return;
	}

	FLG = true;
	int blow;
	for(int i = 0; i < info.size(); i++){
		if((blow = calc_blow(info[i].num,buf,count)) > info[i].blow || blow+(Keta-count) < info[i].blow){
			FLG = false;
			break;
		}
	}
	if(!FLG)return;

	for(int i = 0; i < 10; i++){
		if(!used[i]){
			char next_buf[11];
			bool next_used[10];
			for(int k = 0; k < Keta; k++)next_buf[k] = buf[k];
			next_buf[count] = '0' + i;
			for(int k = 0; k < 10; k++)next_used[k] = used[k];
			next_used[i] = true;
			recursive(next_buf,next_used,count+1);
		}
	}
}

void func(int H){

	info.clear();

	num_candidate = 0;

	for(int loop = 0; loop < H; loop++){
		Info data;
		scanf("%s %d %d",data.num,&data.hit,&data.blow);
		info.push_back(data);
	}

	char buf[11];
	bool used[10];
	for(int i = 0; i < 10; i++)used[i] = false;
	recursive(buf,used,0);

	if(num_candidate == 1){
		ll tmp = POW[Keta-1];
		if(tmp > ans){
			printf("0");
		}
		printf("%lld\n",ans);
	}else{
		printf("NO\n");
	}
}


int main(){

	int H;

	while(true){
		scanf("%d %d",&Keta,&H);
		if(Keta == 0 && H == 0)break;

		func(H);
	}
	return 0;
}
accuracy: 1
time_ms: 850
memory_kb: 3276
final_rank: 2

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	int hit,blow;
	char num[11];
};

vector<Info> info;
int Keta,num_candidate;
ll POW[12] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000};
ll ans;

int calc_hit(char left[11],char right[11]){

	int hit = 0;

	for(int i = 0; i < Keta; i++){
		if(left[i] == right[i])hit++;
	}
	return hit;
}

int calc_blow(char left[11],char right[11],int right_num){

	int blow = 0;

	int check_left[10];
	for(int i = 0; i < 10; i++)check_left[i] = -1;
	for(int i = 0; i < Keta; i++){
		check_left[left[i]-'0'] = i;
	}

	for(int i = 0; i < right_num;i++){
		if(check_left[right[i]-'0'] != -1 && check_left[right[i]-'0'] != i)blow++;
	}
	return blow;
}



void recursive(char buf[11],bool used[10],int count){
	if(num_candidate > 1)return;

	bool FLG;

	if(count == Keta){

		FLG = true;
		for(int i = 0; i < info.size(); i++){
			if(calc_blow(info[i].num,buf,count) != info[i].blow || calc_hit(info[i].num,buf) != info[i].hit){
				FLG = false;
				break;
			}
		}

		if(FLG){
			num_candidate++;
			if(num_candidate >= 2){
				return;
			}
			ans = 0;
			for(int i = 0; i < count; i++){
				ans = 10*ans + buf[i] - '0';
			}
		}

		return;
	}

	//blow???????¨????:?°?????????¨???1??¶,blow?????£?§£???????????§???????????§????????°???return
	FLG = true;
	int blow;
	for(int i = 0; i < info.size(); i++){
		if((blow = calc_blow(info[i].num,buf,count)) > info[i].blow || blow+(Keta-count) < info[i].blow){
			FLG = false;
			break;
		}
	}
	if(!FLG)return;

	for(int i = 0; i < 10; i++){
		if(!used[i]){
			char next_buf[11];
			bool next_used[10];
			for(int k = 0; k < Keta; k++)next_buf[k] = buf[k];
			next_buf[count] = '0' + i;
			for(int k = 0; k < 10; k++)next_used[k] = used[k];
			next_used[i] = true;
			recursive(next_buf,next_used,count+1);
		}
	}
}

void func(int H){

	info.clear();

	num_candidate = 0;

	for(int loop = 0; loop < H; loop++){
		Info data;
		scanf("%s %d %d",data.num,&data.hit,&data.blow);
		info.push_back(data);
	}

	char buf[11];
	bool used[10];
	for(int i = 0; i < 10; i++)used[i] = false;
	recursive(buf,used,0);

	if(num_candidate == 1){
		ll tmp = POW[Keta-1];
		if(tmp > ans){
			printf("0");
		}
		printf("%lld\n",ans);
	}else{
		printf("NO\n");
	}
}


int main(){

	int H;

	while(true){
		scanf("%d %d",&Keta,&H);
		if(Keta == 0 && H == 0)break;

		func(H);
	}
	return 0;
}
accuracy: 1
time_ms: 870
memory_kb: 3140
final_rank: 1

code_snippet: #include <iostream>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <bitset>
#include <cstdio>
using namespace std;
typedef long long int lli;
const int MAX_H = 20;
int L, H;
lli nums[MAX_H];
int s_nums[MAX_H], hit[MAX_H], blow[MAX_H];
lli ans;
void print_bits(lli n){
  for(int i = 0; i < L; ++i){
    cout << static_cast<bitset<4> >(n&15) << ".";
    n >>= 4;
  }
  cout << endl;
}
inline lli conv_64(const char* s){
  lli ret = 0;
  for(int i = 0; i < L; ++i){
    ret <<= 4;
    ret += (lli)(s[i]-'0');
  }
  return ret;
}
inline string deco_64(lli n){
  string ret;
  for(int i = 0; i < L; ++i){
    ret += (char)((n&15)+'0');
    n >>= 4;
  }
  reverse(ret.begin(), ret.end());
  return ret;
}
inline int conv(const char* s){
  int ret = 0;
  for(int i = 0; i < L; ++i){
    ret += 1 << (s[i]-'0');
  }
  return ret;
}
inline int check_64(lli n, lli m){
  lli tmp = n ^ m;
  int ret = 0;
  for(int i = 0; i < L; ++i){
    if((15&tmp) == 0){
      ++ret;
    }
    tmp >>= 4;
  }
  return ret;
}
inline int check(int n, int m){
  return __builtin_popcount(n&m);
}
inline bool solve(lli n, int m){
  for(int i = 0; i < H; ++i){
    int h = check_64(n, nums[i]);
    int b = check(m, s_nums[i]) - h;
    if(hit[i] != h || blow[i] != b){
      return false;
    } 
  }
  return true;
}
inline int dfs(lli n, int used, int depth, int ret){  
  if(depth == L){
    if(solve(n, used)){
      ans = n;
      return ret + 1;
    }
    return ret;
  }  
  for(int i = 0; i < 10; ++i){
    if(((used >> i) & 1) != 1){
      ret = dfs((n<<4)+i, used|(1<<i), depth+1, ret);
      if(ret >= 2){
        return ret;
      }
    }
  }
  return ret;
}
int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  char tmp[11];
  while(true){
    scanf("%d %d", &L, &H);
    if(L == 0 && H == 0){
      break;
    }
    for(int i = 0; i < H; ++i){
      scanf("%s", tmp);
      nums[i] = conv_64(tmp);
      s_nums[i] = conv(tmp);      
      scanf("%d %d", &hit[i], &blow[i]);
    }
    int a = dfs(0L, 0, 0, 0);
    if(a == 1){
      //print_bits(ans);
      cout << deco_64(ans) << endl;
    }
    else{
      cout << "NO" << endl;
    }
  }
  return 0;
}
//uncode
accuracy: 1
time_ms: 8000
memory_kb: 1240
final_rank: 20

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

template < class BidirectionalIterator >
bool next_combination ( BidirectionalIterator first1 ,
  BidirectionalIterator last1 ,
  BidirectionalIterator first2 ,
  BidirectionalIterator last2 )
{
  if (( first1 == last1 ) || ( first2 == last2 )) {
    return false ;
  }
  BidirectionalIterator m1 = last1 ;
  BidirectionalIterator m2 = last2 ; --m2;
  while (--m1 != first1 && !(* m1 < *m2 )){
  }
  bool result = (m1 == first1 ) && !(* first1 < *m2 );
  if (! result ) {
    // ???
    while ( first2 != m2 && !(* m1 < * first2 )) {
      ++ first2 ;
    }
    first1 = m1;
    std :: iter_swap (first1 , first2 );
    ++ first1 ;
    ++ first2 ;
  }
  if (( first1 != last1 ) && ( first2 != last2 )) {
    // ???
    m1 = last1 ; m2 = first2 ;
    while (( m1 != first1 ) && (m2 != last2 )) {
      std :: iter_swap (--m1 , m2 );
      ++ m2;
    }
    // ??¢
    std :: reverse (first1 , m1 );
    std :: reverse (first1 , last1 );
    std :: reverse (m2 , last2 );
    std :: reverse (first2 , last2 );
  }
  return ! result ;
}
 
template < class BidirectionalIterator >
bool next_combination ( BidirectionalIterator first ,
  BidirectionalIterator middle ,
  BidirectionalIterator last )
{
  return next_combination (first , middle , middle , last );
}

vector<int> data;
int L,H;



int main(){
  for(int i=0;i<=9;i++) data.push_back( i );
  while( cin >> L >> H && (H||L) ){
    vector<vector<int> > T;
    vector<int> Hit,Blow;    
    for(int i=0;i<H;i++){
      string s; int h,b; cin >> s >> h >> b;
      T.push_back( vector<int>() ); Hit.push_back( h ); Blow.push_back( b );
      for(int j=0;j<L;j++) T[i].push_back( s[j]-'0' );
    }
    vector<int> ans;
    bool flag = true;
    sort(data.begin(),data.end());
    do {
      do {
        int pos[10];
        memset(pos,-1,sizeof(pos));
        for(int i=0;i<L;i++) pos[data[i]] = i;
        bool f = true;
        for(int i=0;i<H;i++){
          int c1,c2; c1 = c2 = 0;
          for(int j=0;j<L;j++){
            int p = pos[T[i][j]];
            if( p == -1 ) continue;
            else if( p == j ) c1++;
            else c2++;
            if( c1 > Hit[i] || c2 > Blow[i] ) break;
          }
          if( c1 != Hit[i] || c2 != Blow[i] ) f = false;
          if(!f)break;
        }
        if( f ) {
          if( ans.empty() ) 
            for(int i=0;i<L;i++) ans.push_back( data[i] );
          else
            flag = false;
        }
      } while( next_permutation( data.begin(), data.begin() + L ) );
      if( !flag ) break;
    } while( next_combination( data.begin(), data.begin() + L, data.end() ) );

    if( flag && !ans.empty() ){
      for(int i=0;i<L;i++ ) cout << ans[i];
      cout << endl;
    } else
      cout << "NO" << endl;
  }

}
accuracy: 1
time_ms: 7790
memory_kb: 1236
final_rank: 18

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <sstream>
#include <vector>
using namespace std;

#define REP2(i, m, n) for(int i = (int)(m); i < (int)(n); i++)
#define REP(i, n) REP2(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define FOREACH(i, c) for(auto i = (c).begin(); i != (c).end(); ++i)
#define BIT(n, m) (((n) >> (m)) & 1)

typedef long long ll;
typedef pair<int, int> PI;

const ll inf = 1e15;
const ll mod = 1000 * 1000 * 1000 + 7;
const double eps = 1e-9;

template <typename S, typename T> ostream &operator<<(ostream &out, const pair<S, T> &p) {
  out << "(" << p.first << ", " << p.second << ")";
  return out;
}

template <typename T> ostream &operator<<(ostream &out, const vector<T> &v) {
  out << "[";
  REP(i, v.size()){
    if (i > 0) out << ", ";
    out << v[i];
  }
  out << "]";
  return out;
}


int H, L;
vector<string> T;
vector<int> hint;
vector<int> blow;
vector<int> h_count;
vector<int> t_mask;
int used_mask = 0;

void dfs(int pos, string &str, string &ans)
{
  if (ans == "-2") return;
  
  if (pos == str.size()){
    bool ok = true;
    REP(i, T.size()) if (ok){
      int h = h_count[i];
      int b = __builtin_popcount(used_mask & t_mask[i]) - h;
      ok = ok && h == hint[i] && b == blow[i];
    }
    if (ok){
      if (ans == "-1"){
        ans = str;
      } else {
        ans = "-2";
      }
    }
    return;
  }

  REP(i, 10) if ((used_mask & (1 << i)) == 0){
    str[pos] = '0' + i;
    used_mask = used_mask | 1 << i;

    bool ok = true;
    REP(j, T.size()) {
      h_count[j] += T[j][pos] == str[pos];
      if (h_count[j] > hint[j]) ok = false;
    }
    if (ok) dfs(pos + 1, str, ans);
    REP(j, T.size()) h_count[j] -= T[j][pos] == str[pos];
    
    used_mask = used_mask ^ 1 << i;
  }
}


int main(){
  int L, H;
  while (cin >> L >> H && L + H){
    T.resize(H);
    hint.resize(H);
    blow.resize(H);
    t_mask.resize(H);
    h_count.resize(H);
    fill(ALL(h_count), 0);
    used_mask = 0;
    REP(i, H){
      cin >> T[i] >> hint[i] >> blow[i];
      t_mask[i] = 0;
      REP(j, T[i].size()) t_mask[i] |= (1 << (T[i][j] - '0'));
    }
    string ans = "-1";
    string str(L, ' ');
    dfs(0, str, ans);
    if (ans != "-1" && ans != "-2"){
      cout << ans << endl;
    } else {
      cout << "NO" << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 5270
memory_kb: 1232
final_rank: 12

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }


int L, H;
vector< pair<string,pint> > data;
vector<set<char> > se;
bool used[10];
int con = 0;
string res;

void dfs(int v, string str, vector<pint> now) {
    //cout << v << ", " << str << ", " << now << endl;
    if (v == L) {
        bool ok = true;
        for (int i = 0; i < now.size(); ++i) {
            if (now[i] != data[i].second) ok = false;
        }
        if (ok) {
            ++con; res = str;
        }
        return;
    }
    
    for (char c = '0'; c <= '9'; ++c) {
        if (used[c-'0']) continue;
        
        string nstr = str + c;
        vector<pint> next = now;
        bool ok = true;
        for (int i = 0; i < now.size(); ++i) {
            if (data[i].first[v] == c) { ++next[i].first; }
            else {
                if ( se[i].count(c) ) { ++next[i].second; }
            }
            
            if (next[i].first > data[i].second.first) { ok = false; break; }
            if (next[i].second > data[i].second.second) { ok = false; break; }
            if (next[i].first + next[i].second < data[i].second.first + data[i].second.second -L-v-1) { ok = false; break; }
        }
        if (ok) {
            used[c-'0'] = true;
            dfs(v+1, nstr, next);
            used[c-'0'] = false;
        }
    }
}

int main() {
    // freopen( "/Users/macuser/Dropbox/Contest/input.in", "r", stdin );
    
    while (cin >> L >> H) {
        if (L == 0) break;
        
        data.resize(H);
        se.clear(); se.resize(H);
        
        for (int i = 0; i < H; ++i) {
            string str; int h; int b;
            cin >> str >> h >> b;
            data[i] = MP(str,pint(h,b));
            for (int j = 0; j < str.size(); ++j) se[i].insert(str[j]);
        }
        
        memset(used, 0, sizeof(used));
        res = "";
        string str = "";
        con = 0;
        vector<pint> now(H, pint(0,0));
        
        dfs(0, str, now);
        
        if (con == 1) cout << res << endl;
        else cout << "NO" << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 2780
memory_kb: 1228
final_rank: 6

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }


int L, H;
vector< pair<string,pint> > data;
vector<set<char> > se;
bool used[10];
int con = 0;
string res;

void dfs(int v, string str, vector<pint> now) {
    //cout << v << ", " << str << ", " << now << endl;
    if (v == L) {
        bool ok = true;
        for (int i = 0; i < now.size(); ++i) {
            if (now[i] != data[i].second) ok = false;
        }
        if (ok) {
            ++con; res = str;
        }
        return;
    }
    
    for (char c = '0'; c <= '9'; ++c) {
        if (used[c-'0']) continue;
        
        string nstr = str + c;
        vector<pint> next = now;
        bool ok = true;
        for (int i = 0; i < now.size(); ++i) {
            if (data[i].first[v] == c) { ++next[i].first; }
            else {
                if ( se[i].count(c) ) { ++next[i].second; }
            }
            
            if (next[i].first > data[i].second.first) { ok = false; break; }
            if (next[i].second > data[i].second.second) { ok = false; break; }
        }
        if (ok) {
            used[c-'0'] = true;
            dfs(v+1, nstr, next);
            used[c-'0'] = false;
        }
    }
}

int main() {
    // freopen( "/Users/macuser/Dropbox/Contest/input.in", "r", stdin );
    
    while (cin >> L >> H) {
        if (L == 0) break;
        
        data.resize(H);
        se.clear(); se.resize(H);
        
        for (int i = 0; i < H; ++i) {
            string str; int h; int b;
            cin >> str >> h >> b;
            data[i] = MP(str,pint(h,b));
            for (int j = 0; j < str.size(); ++j) se[i].insert(str[j]);
        }
        
        memset(used, 0, sizeof(used));
        res = "";
        string str = "";
        con = 0;
        vector<pint> now(H, pint(0,0));
        
        dfs(0, str, now);
        
        if (con == 1) cout << res << endl;
        else cout << "NO" << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 2660
memory_kb: 1232
final_rank: 5

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[1100][11];
int H[1100];
int L[1100];
int n;
int ret[12];
int ans=0;
int v[12];
int now[12];
int tmp[12];
int m;
void solve(int a){
	if(ans>1)return;
	for(int j=0;j<n;j++){
		int h=0;
		int bl=0;
		for(int k=0;k<m;k++)tmp[k]=0;
		for(int k=0;k<a;k++){
			if(str[j][k]-'0'==now[k]){tmp[k]=1;h++;}
		}
		for(int k=0;k<a;k++){
			for(int l=0;l<a;l++){
				if(tmp[l])continue;
				if(str[j][k]-'0'==now[l]){tmp[l]=1;bl++;break;}
			}
		}
		if(h>H[j])return;
		if(h+m-a<H[j])return;
		if(bl>L[j])return;
		if(bl+(m-a)*2<L[j])return;
	}
	if(a==m){
		ans++;
		for(int i=0;i<m;i++)ret[i]=now[i];
		return;
	}
	for(int i=0;i<10;i++){
		if(!v[i]){
			v[i]=1;
			now[a]=i;
			solve(a+1);
			v[i]=0;
		}
	}
}
int main(){
	int a,b;
	while(scanf("%d%d",&a,&b),a){
		m=a;
		n=b;
		for(int i=0;i<b;i++){
			scanf("%s%d%d",str[i],H+i,L+i);
		}
		ans=0;
		for(int i=0;i<12;i++)v[i]=0;
		solve(0);
		if(ans!=1){
			printf("NO\n");continue;
		}
		for(int i=0;i<a;i++)printf("%d",ret[i]);
		printf("\n");
	}
}
accuracy: 1
time_ms: 4940
memory_kb: 1056
final_rank: 11

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

#define REP(i,n) for(int i=0;i<(int)(n);i++)

using namespace std;

pair<int,int> hb(const vector<int> &l, const vector<int> &r, int K) {
  int hit = 0;
  int blow = 0;
  REP(i,K) if (l[i] == r[i]) ++hit;
  vector<int> cnt(11,0);
  REP(i,K) ++cnt[l[i]];
  REP(i,K) if(cnt[r[i]]) ++blow;
  return make_pair(hit, blow-hit);
}

vector<int> search(const vector<int> &v, const vector<tuple<vector<int>,int,int>> &hint, int l) {
  if (v.size() == l) {
    REP(i,hint.size()) {
      vector<int> hi;
      int h,b;
      tie(hi,h,b) = hint[i];
      if (hb(v,hi,l) != make_pair(h,b)) return vector<int>();
    }
    return v;
  } else {
    vector<int> vv(l,11);
    REP(i,v.size()) vv[i]=v[i];
    REP(i,hint.size()) {
      vector<int> hi;
      int h,b,hv,bv,hvv,bvv;
      tie(hi,h,b) = hint[i];
      tie(hvv,bvv) = hb(vv,hi,l);
      if(hvv>h||bvv>b) return vector<int>();
      int rem = h-hvv + b-bvv;
      if (rem > l-v.size()) return vector<int>();
    }
    vector<int> cnt(10);
    REP(i,v.size()) ++cnt[v[i]];
    vector<int> ans;
    REP(i,10){
      if(cnt[i]==0) {
        auto cp = v;
        cp.push_back(i);
        auto res = search(cp,hint,l);
        if (res.empty()) continue;
        if (ans.empty())
          ans = res;
        else
          throw "hoge";
      }
    }
    return ans;
  }
}

int main() {
  while(1){
    int l,h;
    cin>>l>>h;
    if(!l) break;
    vector<tuple<vector<int>,int,int>> hint;
    REP(i,h) {
      string tr;
      int hit, blow;
      cin>>tr>>hit>>blow;
      vector<int> trv(l);
      REP(j,l) trv[j] = tr[j]-'0';
      hint.emplace_back(trv,hit,blow);
    }
    vector<int> v;
    try{
      auto ans = search(v, hint, l);
      if (ans.empty()) {
        cout << "NO"<< endl;
      }else {
        for(auto i:ans) cout<<i;
        cout<<endl;
      }
    }catch(...){
      cout<<"NO"<<endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 3430
memory_kb: 1300
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <cctype>
#include <algorithm>
#include <set>
#include <cmath>
#include <cassert>
#include <array>
using namespace std;

int pow_int(int x, int n) {
	int res = 1;
	for(int i = 0; i < n; ++i) {
		res *= x;
	}
	return res;
}

array<int, 10> count_num(const string &s) {
	array<int, 10> cnt;
	cnt.fill(0);
	for(const auto &c : s) {
		++cnt[c - '0'];
	}
	return cnt;
}

int match(const string &a, const string &b) {
	const int n = a.size();
	int res = 0;
	for(int i = 0; i < n; ++i) {
		if(a[i] == b[i]) ++res;
	}
	return res;
}

int count_blow(const string &a, const string &b) {
	const array<int, 10> cnt_a = count_num(a);
	const array<int, 10> cnt_b = count_num(b);

	int res = 0;
	for(int i = 0; i < 10; ++i) {
		res += min(cnt_a[i], cnt_b[i]);
	}
	return res - match(a, b);
}

string to_leading_zero_string(int x, int n) {
	char buf[256];
	sprintf(buf, "%0*d", n, x);
	return string(buf);
}

bool valid(const string &s) {
	const array<int, 10> cnt = count_num(s);
	return *max_element(cnt.begin(), cnt.end()) <= 1;
}

vector<string> solve(const vector<string> &number, const vector<int> &hit, const vector<int> & blow) {
	const int n = number.size();
	const int l = number[0].size();
	const int half = l / 2;

	const int first_size = half;
	const int second_size = l - half;

	const int max_first = pow_int(10, first_size);
	const int max_second = pow_int(10, second_size);

	vector<string> first, second;
	first.reserve(n);
	second.reserve(n);

	for(int i = 0; i < n; ++i) {
		first.emplace_back(number[i].substr(0, half));
		second.emplace_back(number[i].substr(half));
	}

	map<vector<int>, vector<string>> candidates;

	for(int x = 0; x < max_first; ++x) {
		const string str = to_leading_zero_string(x, first_size);
		if(!valid(str)) continue;

		vector<int> key(n);

		for(int i = 0; i < n; ++i) {
			const int rest_hit = hit[i] - match(str, first[i]);
			if(rest_hit < 0) goto ng_first;
			key[i] = rest_hit;
		}

		candidates[key].emplace_back(str);

	ng_first:;
	}


	vector<string> res;
	for(int x = 0; x < max_second; ++x) {
		const string str = to_leading_zero_string(x, second_size);
		if(!valid(str)) continue;
		vector<int> key(n);

		for(int i = 0; i < n; ++i) {
			key[i] = match(str, second[i]);
			if(key[i] > hit[i]) goto ng_second;
		}

		if(!candidates.count(key)) goto ng_second;
		for(const auto &e : candidates.at(key)) {
			string s = e + str;
			if(!valid(s)) continue;

			bool ok = true;

			for(int i = 0; i < n; ++i) {
				if(count_blow(s, number[i]) != blow[i]) {
					ok = false;
					break;
				}
			}

			if(ok) {
				res.emplace_back(s);
				if(res.size() > 1) return res;
			}
		}

	ng_second:;
	}

	return res;
}

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

	for(int l, h; cin >> l >> h && l;) {
		vector<string> number(h);
		vector<int> hit(h), blow(h);

		for(int i = 0; i < h; ++i) {
			cin >> number[i] >> hit[i] >> blow[i];
		}

		const auto answers = solve(number, hit, blow);
		cout << (answers.size() == 1 ? answers.front() : "NO") << endl;
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 1410
memory_kb: 3104
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <cctype>
#include <algorithm>
#include <set>
#include <cmath>
#include <cassert>
#include <array>
using namespace std;

#define dump(a) //(cerr << #a << " = " << (a) << endl)

inline int match(const string &a, const string &b) {
  const int n = a.size();
  int res = 0;
  for(int i = 0; i < n; ++i) {
	if(a[i] == b[i]) ++res;
  }
  return res;
}

inline int count_blow(const string &a, const string &b) {
  int res = 0;
  for(int c = '0'; c <= '9'; ++c) {
	res += min(count(a.begin(), a.end(), c), count(b.begin(), b.end(), c));
  }
  return res - match(a, b);
}

inline string to_leading_zero_string(int x, int n) {
  char buf[256];
  sprintf(buf, "%0*d", n, x);
  return string(buf);
}

bool valid(const string &s) {
  for(char c = '0'; c <= '9'; ++c) {
	if(count(s.begin(), s.end(), c) > 1) return false;
  }
  return true;
}

vector<string> solve(const vector<string> &number, const vector<int> &hit, const vector<int> & blow) {
  const int n = number.size();
  const int l = number[0].size();
  const int half = l / 2;

  const int first_size = half;
  const int second_size = l - half;

  const int max_first = pow(10, first_size);
  const int max_second = pow(10, second_size);

  map<vector<int>, vector<string>> candidates;

  for(int x = 0; x < max_first; ++x) {
	const string str = to_leading_zero_string(x, first_size);
	if(!valid(str)) continue;

	vector<int> key(n);

	for(int i = 0; i < n; ++i) {
	  const string first = number[i].substr(0, half);
	  const int rest_hit = hit[i] - match(str, first);
	  if(rest_hit < 0) goto first_ng;
	  key[i] = rest_hit;
	}

	candidates[key].emplace_back(str);

  first_ng:;
  }

  vector<string> res;
  for(int x = 0; x < max_second; ++x) {
	const string str = to_leading_zero_string(x, second_size);
	if(!valid(str)) continue;
	vector<int> key(n);

	for(int i = 0; i < n; ++i) {
	  const string second = number[i].substr(half);
	  key[i] = match(str, second);
	  if(key[i] > hit[i]) goto second_ng;
	}

	if(str == "281") dump(str);
	if(str == "281") for(auto &e : key) dump(e);
	if(!candidates.count(key)) goto second_ng;
	for(const auto &e : candidates.at(key)) {
	  string s = e + str;
	  if(!valid(s)) continue;

	  bool ok = true;

	  if(s == "637281") dump(s);

	  for(int i = 0; i < n; ++i) {
		if(s == "637281") dump(count_blow(s, number[i]));
		if(count_blow(s, number[i]) != blow[i]) {
		  ok = false;
		  break;
		}
	  }

	  if(ok) res.emplace_back(s);
	}

  second_ng:;
  }

  return res;
}

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

  for(int l, h; cin >> l >> h && l;) {
	vector<string> number(h);
	vector<int> hit(h), blow(h);

	for(int i = 0; i < h; ++i) {
	  cin >> number[i] >> hit[i] >> blow[i];
	}

	const auto answers = solve(number, hit, blow);
	dump(answers.size());
	cout << (answers.size() == 1 ? answers.front() : "NO") << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 2420
memory_kb: 3108
final_rank: 9

code_snippet: #include<iostream>
#include<tuple>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
using namespace std;

typedef tuple<vector<int>, int, int> Hint;
enum{TRY, HIT, BLOW};

const int NUMBERS = 10;

vector<vector<int>> subset_combination(int n, int k, vector<int> number) {
    vector<vector<int>> result;
    unsigned long long int S = (1 << k) - 1;
    unsigned long long int E = ~((1 << n) - 1);
    while(!(S & E)) {
        bitset<NUMBERS> flag(S);
        vector<int> v;
        for(int i = 0; i < n; i++) if(flag[i]) v.push_back(number[i]);
        result.push_back(v);
        unsigned long long int smallest = S & -S;
        unsigned long long int ripple = S + smallest;
        unsigned long long int nsmallest = ripple & -ripple;
        S = ripple | (((nsmallest / smallest) >> 1) - 1);
    }
    return result;
}

vector<vector<int>> check(vector<int> v, const vector<Hint>& hint) {
    sort(v.begin(), v.end());
    vector<vector<int>> result;
    do {
        bool ok = true;
        for(const auto& h: hint) {
            int hit = 0, blow = 0;
            int count[10] = {0};
            for(const auto& n: get<TRY>(h)) count[n]++;
            for(int i = 0; i < v.size(); i++) {
                if(v[i] == get<TRY>(h)[i]) hit++;
                else if(count[v[i]]) blow++;
            }
            if(hit != get<HIT>(h) || blow != get<BLOW>(h)) {
                ok = false;
                break;
            }
        }
        if(ok) {
            result.push_back(v);
            if(result.size() > 1) return result;
        }
    } while (next_permutation(v.begin(), v.end()));
    return result;
}

int main() {
    int L, H;
    vector<Hint> hint;
    vector<vector<int>> candidate;
    while(cin >> L >> H, L | H) {
        hint.resize(H);
        for(auto& element: hint) {
            string t;
            int h, b;
            cin >> t >> h >> b;
            vector<int> number;
            for(auto& n: t) number.push_back(n - '0');
            element = Hint(number, h, b);
        }

        vector<int> all = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        candidate = subset_combination(NUMBERS, L, all);

        vector<int> answer;
        bool ok = true;
        for(auto& v: candidate) {
            vector<vector<int>> result = check(v, hint);
            if(result.size() > 1) ok = false;
            if(result.size() == 1) {
                if(answer.size()) ok = false;
                else answer = *result.begin();
            }
            if(!ok) break;
        }

        if(ok && answer.size()) {
            for(const auto& n: answer) cout << n;
            cout << endl;
        } else {
            cout << "NO" << endl;
        }
    }
}
accuracy: 1
time_ms: 5530
memory_kb: 1268
final_rank: 13

code_snippet: #include <iostream>
#include <algorithm>
using namespace std;

const int MAXH = 1000000;
int L, H;
string s[MAXH];
int h[MAXH], b[MAXH], o[MAXH];
int bit[MAXH];
string t;
string ans;

void rec(int k, int used) {
  if(k == L) {
    for(int j = 0; j < H; ++j) {
      if(h[j]|b[j]|o[j]) return;
    }
    if(ans != "") throw 0;
    ans = t;
    return;
  }
  for(int i = 0; i < 10; ++i) {
    if((used >> i) & 1) continue;
    char c = i + '0';
    bool flag = true;
    for(int j = 0; j < H; ++j) {
      if(s[j][k] == c) {
        h[j] -= 1;
      } else if((bit[j] >> i) & 1) {
        b[j] -= 1;
      } else {
        o[j] -= 1;
      }
      if(h[j] < 0 || b[j] < 0 || o[j] < 0) {
        flag = false;
      }
    }
    if(flag) {
      t[k] = c;
      rec(k+1, used|(1<<i));
    }
    for(int j = 0; j < H; ++j) {
      if(s[j][k] == c) {
        h[j] += 1;
      } else if((bit[j] >> i) & 1) {
        b[j] += 1;
      } else {
        o[j] += 1;
      }
    }
  }
}

int main() {
  while(cin >> L >> H && (L|H)) {
    for(int i = 0; i < H; ++i) {
      cin >> s[i] >> h[i] >> b[i];
      o[i] = L - h[i] - b[i];
      bit[i] = 0;
      for(int j = 0; j < s[i].size(); ++j) {
        bit[i] |= 1<<(s[i][j]-'0');
      }
    }
    t.resize(L);
    try {
      ans = "";
      rec(0,0);
      if(ans == "") {
        cout << "NO" << endl;
      } else {
        cout << ans << endl;
      }
    } catch(...) {
      cout << "NO" << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 16532
final_rank: 19

code_snippet: #include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<cassert>
#include<sstream>
#include<complex>
#include<cstdio>
#include<climits>
#include<cstdlib>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<ctime>
#include<cctype>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define EPS 1e-10
#define equals(a,b) (fabs((a)-(b)) < EPS) 
#define MAX 1000
using namespace std;
struct P
{
  string s;
  int h,b;
  P(string s="$$$",int h=-inf,int b=-inf):s(s),h(h),b(b){}
};

int L,H;
P is[MAX];
bool ch[MAX][10];
bool ok,fin;
string ans;

bool check(string s,bool fl)
{
  rep(i,H)
    {
      int hit,blow;
      hit = blow = 0;

      rep(j,s.size())
	{
	  if(s[j] == is[i].s[j])
	    {
	      hit++;
	      continue;
	    }
	  if(ch[i][s[j]-'0'])blow++;
	}

      if(!fl && hit >  is[i].h)return false;
      if( fl && hit != is[i].h)return false;

      if(!fl && blow >  is[i].b)return false;
      if( fl && blow != is[i].b)return false;
    }
  return true;
}


void dfs(int k,int used,string s)
{
  if(fin)return;
  if(!check(s,false))return;
  if(k >= L)
    {
      if(check(s,true))
	{
	  if(ok)
	    {
	      fin = true;
	      ok = false;
	    }
	  else
	    {
	      ok = true;
	      ans = s;
	    }
	}
      return;
    }

  rep(i,10)
    {
      if((used >> i) & 1)continue;
      dfs(k+1,used|(1<<i),s + string(1,(char)('0'+i)));
    }
}

int main()
{
  while(cin >> L >> H,L|H)
    {
      ok = fin = false;
      assert(H < MAX);
      rep(i,H)rep(j,10)ch[i][j] = false;
      rep(i,H)
	{
	  cin >> is[i].s >> is[i].h >> is[i].b;
	  rep(j,L)
	    ch[i][is[i].s[j]-'0'] = true;
	}
      dfs(0,0,"");
      cout << (ok?ans:"NO") << endl;
    }
  return 0;
}
accuracy: 1
time_ms: 2990
memory_kb: 1272
final_rank: 7

code_snippet: //01
#include<iostream>
#include<string>
#include<vector>

using namespace std;

int l,h;
vector<string> tr;
vector<int> hi,bl;
char t[11];
string a;
int ac;

void dfs(int d,int u){
  if(d!=l){
    for(int i=0;i<10;i++){
      if(!(u>>i&1)){
	t[d]='0'+i;
	for(int i=0;i<tr.size();i++){
	  int ch=0,cb=0;
	  for(int j=0;j<=d;j++){
	    if(tr[i].find(t[j])!=string::npos){
	      ((t[j]==tr[i][j])?ch:cb)++;
	    }
	  }
	  if(ch+l-d-1<hi[i]||ch>hi[i]||cb+l-d-1<bl[i]||cb>bl[i])goto next;
	}
	dfs(d+1,u|1<<i);
      next:
	;
      }
    }
  }else{
    t[d]=0;
    ac++;
    a=t;
  }
}

int main(){
  while(cin>>l>>h,l|h){
    tr.resize(h);
    hi.resize(h);
    bl.resize(h);
    while(h--){
      cin>>tr[h]>>hi[h]>>bl[h];
    }
    ac=0;
    dfs(0,0);
    if(ac==1){
      cout<<a<<endl;
    }else{
      cout<<"NO"<<endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 3350
memory_kb: 1232
final_rank: 8