#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;
}