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

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;

int main(){
  int L, H;
  while(cin>>L>>H,L){
    int S = (1<<L)-1;
    vector<int> ans;
    bool used[1000][10] = {};
    vector<string> vs(H);
    vector<int> hit(H);
    vector<int> brow(H);
    REP(i,H){
      cin>>vs[i]>>hit[i]>>brow[i];
      REP(j,vs[i].size())used[i][vs[i][j]-'0'] = true;
    }
    while(S < 1<<10){
      vector<int> digit;
      REP(i,H){
        int hb = 0;
        REP(j,10)if(used[i][j] && S >> j & 1)hb++;
        if(hit[i] + brow[i] != hb){
          goto NEXT;
        }
      }
      REP(i,10)if(S >> i & 1)digit.push_back(i);
      do{
        bool ok = true;
        REP(i,H){
          int h = 0;
          REP(j,L)if((vs[i][j]-'0') == digit[j])h++;
          if(hit[i] != h){
            ok = false;
            break;
          }
        }
        if(ok){
          if(ans.size() > 0){
            ans = vector<int>();
            goto OUTPUT;
          }else{
            ans = digit;
          }
        }
      }while(next_permutation(digit.begin(), digit.end()));
      NEXT:
      int x = S & -S, y = S + x;
      S = ((S & ~y) / x >> 1) | y;
    }
OUTPUT:
    if(ans.size() > 0) { REP(i,ans.size()){cout<<ans[i];} cout<<endl; }
    else cout<<"NO"<<endl;
  }
  return 0;
}