#include <bits/stdc++.h>

using namespace std;

#define indeterminate "WIELE POPRAWNYCH ODPOWIEDZI"
#define incorrect "BRAK POPRAWNYCH ODPOWIEDZI"

int pown(int x, int n)
    {
        int y = 1;
        // n = 2*d + r. x^n = (x^2)^d * x^r.
        int d = n >> 1;
        int r = n & 1;
        int x_2_d = d == 0? 1 : pown(x*x, d);
        int x_r = r == 0? 1 : x;
        return x_2_d*x_r;
    }

map<char,int> to_map(string &s){
	map<char,int> M = map<char,int>();
	for (auto const& x : s){
		if(M.find(x)!=M.end()){
			M[x]++;
		}
		else{
			M.insert({x,1});
		}
	}
	return M;
}

int matching(map<char,int> &guess, map<char,int> &verifier){
	int score =0;
	for (auto const& x : verifier){
		if(guess.find(x.first)!=guess.end()){
			score+= min(x.second,guess[x.first]);
		}
	}
	return score;
}

struct question{
	int length;
	int guessnumber;
	vector<string> password;
	vector<int> correct;
	vector<int> misplaced;
	vector<map<char,int>> mappedpasswords;
	
	vector<char> available = vector<char>({'a','b','c','d','e','f','g','h','i','j','k','l',
		'm','n','o','p','q','r','s','t','u','v','w','x','y','z'});
	
	map<char,int> to_map(string &s){
		map<char,int> M = map<char,int>();
		for(int i = 0; i < s.size(); i++){
			if(M.find(s[i])!=M.end()){
				M[s[i]]++;
			}
			else{
				M.insert({s[i],1});
			}
		}
		return M;
	}
	
	question(int n, int g){
		this->length = n;
		this->guessnumber = g;
		password = vector<string>();
		mappedpasswords = vector<map<char,int>>();
		correct = vector<int>();
		misplaced = vector<int>();
		string x;
		int y,z;
		for(int i = 0; i < g; i++){
			cin>>x>>y>>z;
			if(y+z>0){
				password.push_back(x);
				correct.push_back(y);
				misplaced.push_back(z);
				mappedpasswords.push_back(to_map(x));
			}
			else{//we delete all symbols used and worry not about the value here
				//no need to be painfully efficient in that though
				for(const auto& value: x){
					available.erase(remove(available.begin(), available.end(), value), available.end());
				}
				this->guessnumber--;
			}
		}
		
	}
	
	string get_first_item(int L){
		string S="";
		for(int i = 0; i<L;i++){
			S+=available[0];
		}
		return S;
	}
	
	string get_next_item(int L, string &item, int index){
		if(index<0){
			return "";
		}
		if(item[index]==available[available.size()-1]){
			item[index] = available[0];
			return get_next_item(L,item, index-1);
		}
		else{
			vector<char>::iterator it = find(this->available.begin(), this->available.end(), item[index]);
			it++;
			item[index]=*it; 
			return item;
		}
	}
	
	string guessCheck(){
		int found = 0;
		string ans = "";
		
		string SS = get_first_item(this->length);
		while(SS!=""){
			map<char,int> s2map = to_map(SS);
			bool gud = true;
			for(int i =0; i<this->guessnumber; i++){
				int corr = 0;
				int miss = 0;
				for(int q = 0; q< this->length; q++){
					if(this->password[i][q]==SS[q]){
						corr++;
					}
				}
				
				miss = matching(s2map,mappedpasswords[i])-corr;
				if(corr!=correct[i] or miss!=misplaced[i]){
				//	if(this->length==3){cerr<<"Guess "<<SS<<" rejected at test 
				// "<<password[i]<<" "<<correct[i]<<" "<<misplaced[i]<<'\n';}
					gud = false;
					break;
				}
			}
			if(gud){
					if(ans==""){
					ans = SS;
				}
			else{
					return indeterminate;
				}
			}
			SS = get_next_item(this->length,SS,this->length-1);
		}
	if(ans==""){
		return incorrect;
	}
	return ans;
	}
};

int main(){
	int T;
	int n,g;
	cin>>T;
	while(T-->0){
		cin>>n>>g;
		question Q = question(n,g);
		cout<<Q.guessCheck()<<'\n';
	}
	return 0;
}