Problem:
Problem H:
The Best Name for Your Baby
In the year 29XX, the government of a small country somewhere on the earth introduced a law restricting first names of the people only to traditional names in their culture, in order to preserve their cultural uniqueness. The linguists of the country specifies a set of rules once every year, and only names conforming to the rules are allowed in that year. In addition, the law also requires each person to use a name of a specific length calculated from one's birth date because
otherwise too many people would use the same very popular names. Since the legislation of that law, the common task of the parents of new babies is to find the name that comes first in the alphabetical order among the legitimate names of the given length because names earlier in the alphabetical order have various benefits in their culture.
Legitimate names are the strings consisting of only lowercase letters that can be obtained by
repeatedly applying the rule set to the initial string "S", a string consisting only of a single uppercase S.
Applying the rule set to a string is to choose one of the rules and apply it to the string. Each
of the rules has the form
A
->
α
, where
A
is an uppercase letter and
α
is a string of lowercase and/or uppercase letters. Applying such a rule to a string is to replace an occurrence of the
letter
A
in the string to the string
α
. That is, when the string has the form "
βAγ
", where
β
and
γ
are arbitrary (possibly empty) strings of letters, applying the rule rewrites it into the string "
βαγ
". If there are two or more occurrences of A in the original string, an arbitrary one of them
can be chosen for the replacement.
Below is an example set of rules.
S -> aAB  (1)
A ->      (2)
A -> Aa   (3)
B -> AbbA (4)
Applying the rule (1) to "S", "aAB" is obtained. Applying (2) to it results in "aB", as A is replaced by an empty string. Then, the rule (4) can be used to make it "aAbbA". Applying (3) to the first occurrence of A makes it "aAabbA". Applying the rule (2) to the A at the end results in "aAabb". Finally, applying the rule (2) again to the remaining A results in "aabb". As no uppercase letter remains in this string, "aabb" is a legitimate name.
We denote such a rewriting process as follows.
(1)     (2)    (4)       (3)        (2)       (2)
S --> aAB --> aB --> aAbbA --> aAabbA --> aAabb --> aabb
Linguists of the country may sometimes define a ridiculous rule set such as follows.
S -> sA (1)
A -> aS (2)
B -> b  (3)
The only possible rewriting sequence with this rule set is:
(1)    (2)     (1)      (2)
S --> sA --> saS --> sasA --> ...
which will never terminate. No legitimate names exist in this case. Also, the rule (3) can never be used, as its left hand side, B, does not appear anywhere else.
It may happen that no rules are supplied for some uppercase letters appearing in the rewriting steps. In its extreme case, even S might have no rules for it in the set, in which case there are no legitimate names, 
...(truncated)

Submitted solutions:

code_snippet: #include <cctype>
#include <cstddef>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <utility>
#include <vector>
int n, l, tot, to[501];
std::string s[51], f[21][501];
bool ed[501], vis[501];
char rev[501];
std::vector<std::pair<int, int> > g[501];
std::map<char, int> mp;
int Id(char c) {
  if (!mp.count(c)) rev[mp[c] = ++tot] = c;
  return mp[c];
}
void Dijkstra(int layer) {
  std::priority_queue<std::pair<std::string, int>,
                      std::vector<std::pair<std::string, int> >,
                      std::greater<std::pair<std::string, int> > >
      q;
  std::memset(vis, 0, tot + 1);
  for (int i = 0; i <= tot; i++)
    if (f[layer][i] != "~") q.push(std::make_pair(f[layer][i], i));
  while (!q.empty()) {
    std::pair<std::string, int> tmp = q.top();
    q.pop();
    int u = tmp.second;
    if (vis[u]) continue;
    vis[u] = true;
    if (layer == 0) ed[u] = true;
    for (int v = 0; v <= tot; v++)
      if (!vis[v]) {
        for (std::vector<std::pair<int, int> >::iterator it = g[v].begin();
             it != g[v].end(); ++it) {
          int x = it->first, y = it->second;
          if (x == u || y == u) {
            if (x == u && ed[y]) f[layer][v] = tmp.first;
            if (y == u && ed[x]) f[layer][v] = tmp.first;
            if (f[layer][v] == tmp.first)
              q.push(std::make_pair(f[layer][v], v));
          }
        }
      }
  }
}
int main(int argc, char const *argv[]) {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(NULL);
  while (std::cin >> n >> l && (n || l)) {
    for (int i = 1; i <= n; i++) std::cin >> s[i];
    mp.clear(), tot = 0;
    std::memset(ed, 0, sizeof(ed));
    std::memset(to, 0, sizeof(to));
    std::memset(rev, 0, sizeof(rev));
    ed[0] = true;
    for (int i = 1; i <= n; i++) {
      std::string a = s[i].substr(2);
      int L = Id(s[i][0]), m = a.size();
      if (m == 0) {
        ed[L] = true;
      } else if (m == 1) {
        if (std::islower(a[0])) {
          int x = Id(a[0]);
          if (!to[L] || a[0] < rev[to[L]]) to[L] = x;
        } else {
          g[L].push_back(std::make_pair(Id(a[0]), 0));
        }
      } else {
        for (int i = 0; i < m - 2; i++) {
          int X = ++tot;
          g[L].push_back(std::make_pair(Id(a[i]), X));
          L = X;
        }
        g[L].push_back(std::make_pair(Id(a[m - 2]), Id(a[m - 1])));
      }
    }
    for (int i = 0; i <= l; i++)
      for (int j = 0; j <= tot; j++) f[i][j] = "~";
    for (int i = 0; i <= tot; i++)
      if (ed[i]) f[0][i] = "";
    Dijkstra(0);
    for (int i = 0; i <= tot; i++) {
      if (to[i]) f[1][i] = rev[to[i]];
      if (std::islower(rev[i])) f[1][i] = rev[i];
    }
    Dijkstra(1);
    for (int i = 2; i <= l; i++) {
      for (int j = 1; j < i; j++) {
        for (int u = 0; u <= tot; u++) {
          for (std::vector<std::pair<int, int> >::iterator it = g[u].begin();
               it != g[u].end(); ++it) {
            int x = it->first, y = it->second;
            if (f[j][x] != "~" && f[i - j][y] != "~") {
              std::string tmp = f[j][x] + f[i - j][y];
              if (tmp < f[i][u]) f[i][u] = tmp;
            }
          }
        }
      }
      Dijkstra(i);
    }
    if (!mp.count('S') || f[l][Id('S')] == "~")
      std::cout << "-\n";
    else
      std::cout << f[l][Id('S')] << '\n';
    for (int i = 0; i <= tot; i++) g[i].clear();
  }
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3936
final_rank: 9

code_snippet: // AOJ #1273 The Best Name for Your Baby
// 2025.5.21

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

static const string FAIL = "{";

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

    while (true) {
        int n, L;
        cin >> n >> L;
        if (n == 0) break;

        vector<vector<string>> rules(26);
        for (int i = 0; i < n; i++) {
            string line;
            cin >> line;
            int A = line[0] - 'A';
            string rhs = line.substr(2);
            rules[A].push_back(rhs);
        }
        for (int A = 0; A < 26; A++) {
            sort(rules[A].begin(), rules[A].end());
        }

        vector<vector<string>> best(26, vector<string>(L+1, FAIL));

        for (int j = 0; j <= L; j++) {
            bool updated = true;
            while (updated) {
                updated = false;
                for (int A = 0; A < 26; A++) {
                    if (rules[A].empty()) continue;
                    string curBest = best[A][j];
                    for (auto &rhs : rules[A]) {
                        int m = rhs.size();
                        static string dp[11][21];
                        for (int i = 0; i <= m; i++)
                            for (int k = 0; k <= j; k++) dp[i][k] = FAIL;
                        dp[0][0] = "";

                        for (int i = 0; i < m; i++) {
                            char c = rhs[i];
                            for (int k = 0; k <= j; k++) {
                                if (dp[i][k] == FAIL) continue;
                                const string &sofar = dp[i][k];
                                if ('a' <= c && c <= 'z') {
                                    if (k+1 <= j) {
                                        string cand = sofar;
                                        cand.push_back(c);
                                        if (dp[i+1][k+1] == FAIL || cand < dp[i+1][k+1])
                                            dp[i+1][k+1] = move(cand);
                                    }
                                } else {
                                    int B = c - 'A';
                                    for (int add = 0; add + k <= j; add++) {
                                        const string &sub = best[B][add];
                                        if (sub == FAIL) continue;
                                        string cand = sofar + sub;
                                        if (dp[i+1][k+add] == FAIL || cand < dp[i+1][k+add])
                                            dp[i+1][k+add] = move(cand);
                                    }
                                }
                            }
                        }
                        if (dp[m][j] != FAIL) {
                            if (curBest == FAIL || dp[m][j] < curBest) curBest = dp[m][j];
                        }
                    }
                    if (curBest != FAIL && curBest != best[A][j]) {
                        best[A][j] = move(curBest);
                        updated = true;
                    }
                }
            }
        }
        const string &ans = best['S' - 'A'][L];
        cout << (ans == FAIL ? "-" : ans) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 930
memory_kb: 3220
final_rank: 7

code_snippet: #include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
#include <cassert>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e3 + 10;
int flag[200][21];
string ans[200][21];
string dp[51][21][21];
int f[51][21];
int in[200][21];
vector<string> vs[200];
map<string, int> mc;
int key[200];
int a[30][30];
int sz[51];
string dfs(int x, int len)
{
	if (flag[x][len])
		return ans[x][len];
	if (in[x][len]) return "-";
	in[x][len] = 1;
	string ret = "-";
	for (int i = 0; i < vs[x].size(); i++)
	{
		string& s = vs[x][i];
		if (s.empty()) continue;
		int id = mc[s];
		if (!f[id][len])
		{
			for (int i = 1; i <= 20; i++)
			{
				dp[id][0][i] = "-";
			}
			dp[id][0][0] = "";
			for (int i = 1; i <= s.length(); i++)
			{
				for (int j = 0; j <= len; j++)
				{
					string& res = dp[id][i][j];
					res = "-";
					char c = s[i - 1];
					if (islower(c))
					{
						if (j > 0 && dp[id][i - 1][j - 1] != "-")
						{
							if (res == "-") res = dp[id][i - 1][j - 1] + c;
							res = min(res, dp[id][i - 1][j - 1] + c);
						}
						continue;
					}
					for (int k = 0; k <= j; k++)
					{
						if (dp[id][i - 1][k] == "-") continue;
						string t1 = dp[id][i - 1][k];
						string t2 = dfs(c, j - k);
						if (t2 == "-") continue;
						if (res == "-") res = t1 + t2;
						res = min(res, t1 + t2);
					}
				}
			}
			f[id][len] = 1;
		}

		if (ret == "-") ret = dp[id][s.length()][len];
		if (dp[id][s.length()][len] != "-")
			ret = min(ret, dp[id][s.length()][len]);
	}
	in[x][len] = 0;
	flag[x][len] = 1;
	return ans[x][len] = ret;
}
void init()
{
	MEM(key, 0);
	MEM(flag, 0);
	int cnt = 26;
	while (cnt--)
	{
		for (int i = 'A'; i <= 'Z'; i++)
		{
			if (key[i] == 1) continue;
			for (int j = 0; j < vs[i].size(); j++)
			{
				string& s = vs[i][j];
				int ok = 1;
				for (int k = 0; k < s.length(); k++)
				{
					char c = s[k];
					ok &= key[c];
				}
				key[i] = ok;
				if (key[i]) break;
			}
		}
	}
	MEM(a, 0);
	for (int i = 'A'; i <= 'Z'; i++)
	{
		for (int j = 0; j < vs[i].size(); j++)
		{
			string& s = vs[i][j];
			string t;
			int ok = 1;
			for (int k = 0; k < s.length(); k++)
			{
				char c = s[k];
				ok &= key[c];
				if (!key[c]) t += c;
			}
			if (t.length() > 1) continue;
			if (t.empty())
			{
				for (int k = 0; k < s.length(); k++)
				{
					a[s[k] - 'A'][i - 'A'] = 1;
				}
			}
			else if (isupper(t[0]))
				a[t[0] - 'A'][i - 'A'] = 1;
		}
	}
	for (int k = 0; k < 26; k++)
	{
		for (int i = 0; i < 26; i++)
		{
			for (int j = 0; j < 26; j++)
			{
				a[i][j] |= a[i][k] & a[k][j];
			}
		}
	}
	for (int i = 'A'; i <= 'Z'; i++)
	{
		flag[i][0] = 1;
		if (key[i] == 1) ans[i][0] = "";
		else ans[i][0] = "-";
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n, m;
	int ks = 0;
	while (cin >> n >> m)
	{
		if (n == 0 && m == 0) break;
		ks++;
		for (int i = 'A'; i <= 'Z'; i++)
			vs[i].clear();
		mc.clear();
		for (int i = 1; i <= n; i++)
		{
			MEM(f[i], 0);
			string s;
			cin >> s;
			char c = s[0];
			s = s.substr(2);
			vs[c].push_back(s);
			mc[s] = i;
		}
		init();
		for (int i = 1; i <= m; i++)
		{
			for (int c = 'A'; c <= 'Z'; c++)
				dfs(c, i);
			queue<int> q;
			for (int c = 'A'; c <= 'Z'; c++)
			{
				if (dfs(c, i) != "-")
				{
					q.push(c);
				}
			}
			for (int j = 1; j <= n; j++)
				f[i][j] = 0;
			while (!q.empty())
			{
				int x = q.front();
				q.pop();
				for (int j = 0; j < 26; j++)
				{
					if (a[x - 'A'][j] == 0) continue;
					string& t = ans[j + 'A'][i];
					if (t == "-" || t > ans[x][i])
					{
						t = ans[x][i];
						q.push(j + 'A');
					}
				}
			}
		}
		puts(dfs('S', m).c_str());
	}
	return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 3824
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
vector<pair<int,int> > g[1010];
int n,l,cnt;
bool st[1010][30],book[1010];
string d[1010],f[1010][30];
priority_queue<pair<string,int>,vector<pair<string,int> >,greater<pair<string,int> > > q;
int main()
{
	int i,j,k,u;
    while(cin>>n>>l&&(n||l)){
        for(i=0;i<1010;i++)g[i].clear();
        cnt=130;
        for(i=1;i<=n;i++){
            string st;
            cin>>st;
            int len=st.size();
            if(len==2)g[st[0]].push_back({0,0});
            	else if(len==3)g[st[0]].push_back({st[2],0});
            		else if(len==4)g[st[0]].push_back({st[2],st[3]});
            			else{
                			g[st[0]].push_back({st[2],++cnt});
                			for(j=3;j<len-2;j++){
                    			g[cnt].push_back({st[j],cnt+1});
                    			cnt++;
                			}
                			g[cnt].push_back({st[len-2],st[len-1]});
            			} 
        }
        for(i=0;i<=cnt;i++)
        	for(j=0;j<=l;j++)f[i][j]="~~";
        	
        memset(st,0,sizeof(st));
        for(i='A';i<='Z';i++)
        	for(j=0;j<g[i].size();j++)
        		if(!(g[i][j].x+g[i][j].y)){
    				st[i][0]=1;
            		f[i][0]="";
        		}
        
        st[0][0]=1;
        for(i='a';i<='z';i++){
            st[i][1]=1;
            f[i][1]=(char)(i); 
        }
        for(j=0;j<=l;j++){
            while(!q.empty())q.pop();
            for(i=0;i<=cnt;i++)d[i]="~~";
            memset(book,0,sizeof(book));
            for(i='A';i<=cnt;i++){
                for(k=1;k<j;k++)
                	for(u=0;u<g[i].size();u++){
                		pair<int,int> v=g[i][u];
                    	if(st[v.x][k]&st[v.y][j-k]){
                        	f[i][j]=min(f[i][j],f[v.x][k]+f[v.y][j-k]);
                        	st[i][j]|=1;
                    	}
                	}
                	
                if(st[i][j]){
                    d[i]=f[i][j];
                    q.push({d[i],i});
                }
            }
            while(!q.empty()){
                int u=q.top().y;
                q.pop();
                if(book[u])continue;
                book[u]=1;
                st[u][j]=1;
                f[u][j]=d[u];
                for(i='A';i<=cnt;i++){
                	if(!book[i]){
                		for(int w=0;w<g[i].size();w++){
                			pair<int,int> v=g[i][w];
                			if(v.x==u||v.y==u){
                        		if(v.x==u&&st[v.y][0])d[i]=d[u];
                        		if(v.y==u&&st[v.x][0])d[i]=d[u];
                        		if(d[i]==d[u])q.push({d[i],i});         
    						}
    					}
    				}
				}
            }
        }
        if(!st['S'][l]){
            cout<<'-'<<endl;
            continue;
        }else cout<<f['S'][l]<<endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 4592
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
vector<pair<int,int> > G[1005];
int n,l,cnt;
bool vis[1005][25],done[1005];
char str[25];
string d[1005],f[1005][25];
priority_queue<pair<string,int> ,vector<pair<string,int> >,greater<pair<string,int> > > q;
int main(){
    while(scanf("%d%d",&n,&l)){
    	if(!n && !l) exit(0);
        for(int i=1;i<=1005;i++){
        	G[i].clear();
		}
        cnt=130;
        for(int i=1;i<=n;i++){
            scanf("%s",str);
            int len=strlen(str);
            if(len==2) G[str[0]].push_back(make_pair(0,0));
            else if(len==3) G[str[0]].push_back(make_pair(str[2],0));
            else if(len==4) G[str[0]].push_back(make_pair(str[2],str[3]));
            else{
                G[str[0]].push_back(make_pair(str[2],++cnt));
                for(int j=3;j<len-2;j++){
                    G[cnt].push_back(make_pair(str[j],cnt+1));
                    cnt++;
                }
                G[cnt].push_back(make_pair(str[len-2],str[len-1]));
            } 
        }
        for(int i=0;i<=cnt;i++){
        	for(int j=0;j<=l;j++){
        		f[i][j]="~~";
			}
		}
        memset(vis,0,sizeof(vis));
        for(int i='A';i<='Z';i++){
        	for(auto v:G[i]){
        		if(!(v.first+v.second)){
					vis[i][0]=1;
        			f[i][0]="";
        		}
        	}
		}
        vis[0][0]=1;
        for(char i='a';i<='z';i++){
            vis[i][1]=1;
            f[i][1]=i; 
        }
        for(int j=0;j<=l;j++){
            while(!q.empty()) q.pop();
            for(int i=0;i<=cnt;i++){
            	d[i]="~~";
			}
            memset(done,0,sizeof(done));
            for(int i='A';i<=cnt;i++){
                for(int k=1;k<j;k++){
                	for(auto v:G[i]){
                    	if(vis[v.first][k]&vis[v.second][j-k]){
                        	f[i][j]=min(f[i][j],f[v.first][k]+f[v.second][j-k]);
                        	vis[i][j]|=1;
                    	}
                	}
				}
                if(vis[i][j]){
                    d[i]=f[i][j];
                    q.push(make_pair(d[i],i));
                }
            }
            while(!q.empty()){
                int u=q.top().second;
                q.pop();
                if(done[u]) continue;
                done[u]=true;
                vis[u][j]=1;
                f[u][j]=d[u];
                for(int i='A';i<=cnt;i++){
                	if(!done[i]){
                		for(auto v:G[i]){
                			if(v.first==u || v.second==u){
                        		if(v.first==u && vis[v.second][0]) d[i]=d[u];
                        		if(v.second==u && vis[v.first][0]) d[i]=d[u];
                        		if(d[i]==d[u]) q.push(make_pair(d[i],i));         
							}
						}
					}
				}
            }
        }
        if(!vis['S'][l]){
            cout<<'-'<<endl;
            continue;
        }
        else cout<<f['S'][l]<<endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 4380
final_rank: 10

code_snippet: /**
 *    author:  gary
 *    created: 27.04.2022 17:40:31
**/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define rep(a,b) for(int a=0;a<b;++a)
#define LL long long
#define PB push_back
#define POB pop_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
string f[26][21];
vector<string> to[26];
bool canempty[26];
vector<int> g[26],rg[26];
int vis[26];
bool type(char c){
    if(c<='z'&&c>='a') return 0;
    return 1;
}
string solve(vector<string> v,int len){
    string dp[21][2];
    rep(i,len+1) rep(j,2) dp[i][j]="{";
    dp[0][0]="";
    rep(t,v.size()){
        rep(i,len+1) dp[i][(t+1)&1]="{";
        rep(i,len+1) if(dp[i][t&1]!="{"){
            string val=dp[i][t&1];
            if(type(v[t][0])==0){
                if(i+v[t].length()>len) break;
                check_min(dp[i+v[t].length()][(t+1)&1],val+v[t]);
            }
            else{
                rep(k,len+1-i) if(f[v[t][0]-'A'][k]!="{"){
                    check_min(dp[i+k][(t+1)&1],val+f[v[t][0]-'A'][k]);
                }
            }
        }
    }
    return dp[len][v.size()&1];
}
stack<int> sta;
vector<int> ord;
void dfs1(int now){
    vis[now]=1;
    rep(i,g[now].size()) if(!vis[g[now][i]]) dfs1(g[now][i]);
    sta.push(now);
}
void dfs2(int now){
    vis[now]=1;
    ord.PB(now);
    rep(i,rg[now].size()) if(!vis[rg[now][i]]) dfs2(rg[now][i]);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,l;
    while (true)
    {
        cin>>n>>l;
        if(n==0&&l==0) break;
        rep(i,26) rb(j,0,20) f[i][j]="{";
        rep(i,26) to[i].clear(),canempty[i]=0;
        // vector<string> save;
        rb(z,1,n){
            string s;
            cin>>s;
            // save.PB(s);
            string t;
            rb(i,2,s.length()-1) t.PB(s[i]);
            int x=s[0]-'A';
            to[x].PB(t);
            if(t.empty()) canempty[x]=1;
        }
        while (true){
            bool ok=0;
            rep(i,26){
                if(!canempty[i]){
                    rep(j,to[i].size()){
                        string tmp=to[i][j];
                        canempty[i]=1;
                        rep(k,tmp.length()){
                            canempty[i]&=type(tmp[k])==1&&canempty[tmp[k]-'A']&&tmp[k]!=('A'+i);
                        }
                        if(canempty[i]) break;
                    }
                    ok|=canempty[i];
                }
            }
            if(!ok) break;
        }
        rep(i,26) g[i].clear(),rg[i].clear(),vis[i]=0;
        ord.clear();
        rep(i,26){
            rep(j,to[i].size()){
                string tmp=to[i][j];
                rep(k,tmp.length()){
                    bool ok=(type(tmp[k])==1);
                    rep(y,tmp.length()){
                        if(y!=k){
                            ok&=(type(tmp[y])==1)&&canempty[tmp[y]-'A'];
                        }
                    }
                    if(ok){
                        // cout<<canempty<<" "<<tmp<<" "<<char('A'+i)<<" "<<tmp[k]<<endl;
                        rg[i].PB(tmp[k]-'A');
                        g[tmp[k]-'A'].PB(i);
                    }
                }
            }
        }
        rep(i,26) sort(ALL(rg[i])),rg[i].erase(unique(ALL(rg[i])),rg[i].end());
        rep(i,26) if(!vis[i]) dfs1(i);
        rep(i,26) vis[i]=0;
        while (!sta.empty())
        {
            int tmp=sta.top();
            sta.pop();
            if(!vis[tmp]) dfs2(tmp);
        }
        rb(j,0,l){
            rep(i_,26){
                int i=ord[i_];
                if(j==0){
                    if(canempty[i]) f[i][j]="";
                    continue;
                }
                rep(z,rg[i].size()) check_min(f[i][j],f[rg[i][z]][j]);
                rep(itx,to[i].size()){
                    string it=to[i][itx];
                    vector<string> v;
                    rep(xx,it.length()){
                        char itt=it[xx];
                        if(v.empty()||type(v.back()[0])!=type(itt)||type(itt)==1) v.PB("");
                        v.back().PB(itt);
                    }
                    check_min(f[i][j],solve(v,j));
                }
            }
        }
        // if(f['S'-'A'][l]=="ieeeeeeeee"){
            // cerr<<n<<" "<<l<<endl;
            // for(auto it:save) cerr<<it<<endl;
        // }
        if(f['S'-'A'][l]=="{") cout<<"-\n";
        else cout<<f['S'-'A'][l]<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 3180
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
 
string dp[26][21];
string Z="{";
 
void init(){
  for(int i=0;i<26;i++){
    for(int j=0;j<=20;j++){
      dp[i][j]=Z;
    }
  }
}
 
int N,M;
string from[50],to[50];
 
bool check(int id){
  int sd=from[id][0]-'A';
   
  if( to[id]=="" ){
    bool res=( dp[sd][0] == Z );
    dp[sd][0]="";
    return res;
  }
   
  string t[21];
  for(int i=0;i<=M;i++)t[i]=Z;
  t[0]="";
 
  bool allZero=true;
   
  for(int i=0;i<(int)to[id].size();i++){
    char ch=to[id][i];
    if('A'<=ch&&ch<='Z'){
      int target=ch-'A';
      if( dp[target][0] == Z )allZero=false;
       
      for(int j=M;j>=0;j--){
        if( dp[target][0]==Z )  t[j]=Z;
         
        for(int k=j;k>=0;k--){
          if(t[j-k]!=Z && dp[target][k]!=Z){
            t[j]=min(t[j],t[j-k]+dp[target][k]);
          }
        }
      }
       
    }else{
      allZero=false;
      for(int j=M;j>=1;j--){
        if(t[j-1]!=Z)t[j]=t[j-1]+ch;
        else t[j]=Z;
      }
      t[0]=Z;
    }
  }
   
  bool res=false;
  for(int i=1;i<=M;i++){
    if(dp[sd][i]>t[i]){
      dp[sd][i]=t[i];
      res=true;
    }
  }
     
  if( allZero && dp[sd][0]==Z){
    res=true;
    dp[sd][0]="";
  }
   
  return res;
}
 
int main(){
  while(1){
    cin>>N>>M;
    if(N==0&&M==0)break;
    init();
    for(int i=0;i<N;i++){
      string str;
      cin>>str;
      int index=str.find('=');
      from[i]=str.substr(0,index);
      if(index+1 == (int)str.size()){
        to[i]="";
      }else{
        to[i]=str.substr(index+1);
      }
    }
    bool update=true;
    while(update){
      update=false;
      for(int i=0;i<N;i++){
        update=(update||check(i));
      }
    }
    string ans = dp[ 'S'-'A' ][ M ];
    if(ans==Z)cout<<'-'<<endl;
    else cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 6700
memory_kb: 3180
final_rank: 13

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

string dp[26][21];
string Z="{";

void init(){
  for(int i=0;i<26;i++){
    for(int j=0;j<=20;j++){
      dp[i][j]=Z;
    }
  }
}

int N,M;
string from[50],to[50];

bool check(int id){
  int sd=from[id][0]-'A';
  
  if( to[id]=="" ){
    //    cout<<"!!"<<endl;
    
    bool res=( dp[sd][0] == Z );
    dp[sd][0]="";
    return res;
  }
  
  string t[21];
  for(int i=0;i<=M;i++)t[i]=Z;
  t[0]="";

  bool allZero=true;
  
  for(int i=0;i<(int)to[id].size();i++){
    char ch=to[id][i];
    if('A'<=ch&&ch<='Z'){
      int target=ch-'A';
      if( dp[target][0] == Z )allZero=false;
      
      for(int j=M;j>=0;j--){
        if( dp[target][0]==Z )  t[j]=Z;
        
        for(int k=j;k>=0;k--){
          if(t[j-k]!=Z && dp[target][k]!=Z){
            t[j]=min(t[j],t[j-k]+dp[target][k]);
          }
        }
      }
      
    }else{
      allZero=false;
      for(int j=M;j>=1;j--){
        if(t[j-1]!=Z)t[j]=t[j-1]+ch;
        else t[j]=Z;
      }
      t[0]=Z;
    }
  }
  
  bool res=false;
  for(int i=1;i<=M;i++){
    if(dp[sd][i]>t[i]){
      dp[sd][i]=t[i];
      res=true;
    }
  }
    
  if( allZero && dp[sd][0]==Z){
    res=true;
    dp[sd][0]="";
  }
  
  return res;
}

int main(){
  while(1){
    cin>>N>>M;
    if(N==0&&M==0)break;
    init();
    for(int i=0;i<N;i++){
      string str;
      cin>>str;
      int index=str.find('=');
      from[i]=str.substr(0,index);
      
      if(index+1 == (int)str.size()){
        to[i]="";
        //        cout<<i<<endl;
      }else{
        to[i]=str.substr(index+1);
      }

      
    }
    
    bool update=true;
    while(update){
      update=false;
      for(int i=0;i<N;i++){
        update=(update||check(i));
      }
      /*

      for(int i=0;i<5;i++){
        cout<<"dp[A]["<<i<<"] = "<<dp[0][i]<<endl;
      }
      for(int i=0;i<5;i++){
        cout<<"dp[B]["<<i<<"] = "<<dp[1][i]<<endl;
      }
      for(int i=0;i<5;i++){
        cout<<"dp[S]["<<i<<"] = "<<dp['S'-'A'][i]<<endl;
      }
      */
    }
    
    string ans = dp[ 'S'-'A' ][ M ];
    if(ans==Z)cout<<'-'<<endl;
    else cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 6510
memory_kb: 3048
final_rank: 12

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

const string kInf = "zzzzzzzzzzzzzzzzzzzzz";

struct Rule {
  int l, r1, r2;

  Rule(int _l, int _r1, int _r2) {
    l = _l, r1 = _r1, r2 = _r2;
  }
};

int N, M, C, R;
int ch_num[128];
vector< Rule > vrl;
vector< vector< string > > fs;
vector< vector< bool > > fb;

void init_and_read(void);
void parse_rule(int, const string &, int, int);
void solve(void);
void cal_zero_ln(int);

int main() {
  while (cin >> N >> M, N + M) {
    init_and_read();
    solve();
  }

  return 0;
}

void init_and_read(void) {
  vrl.clear();
  fill(&ch_num[0], &ch_num[128], -1);
  C = 1;
  for (int i = 0; i < N; ++i) {
    string str;
    int ln;

    cin >> str, ln = str.length();
    for (int j = 0; j < ln; ++j) {
      if (str[j] == '=')  continue;
      if (ch_num[str[j]] == -1) ch_num[str[j]] = C++;
    }

    parse_rule(ch_num[str[0]], str, 2, ln);
  }
}

void parse_rule(int lv, const string &rs, int i, int ln) {
  switch (ln - i) {
    case 0:
      vrl.push_back(Rule(lv, 0, 0));
      break;
    case 1:
      vrl.push_back(Rule(lv, ch_num[rs[i]], 0));
      break;
    case 2:
      vrl.push_back(Rule(lv, ch_num[rs[i]], ch_num[rs[i + 1]]));
      break;
    default:
      vrl.push_back(Rule(lv, ch_num[rs[i]], C));
      parse_rule(C++, rs, i + 1, ln);
  }
}

void solve(void) {
  R = vrl.size();
  fs.clear(), fs.resize(max(M + 1, 2), vector< string >(C, kInf));
  fb.clear(), fb.resize(max(M + 1, 2), vector< bool >(C, false));

  fs[0][0] = "", fb[0][0] = true;
  for (int i = 0; i < 128; ++i)
    if (islower(char(i)) && ch_num[i] != -1)
      fs[1][ch_num[i]] = string(1, char(i)), fb[1][ch_num[i]] = true;

  cal_zero_ln(0);
  for (int i = 1; i <= M; ++i) {
    for (int j = 1; i - j > 0; ++j)
      for (int k = 0; k < R; ++k) {
        int l = vrl[k].l, r1 = vrl[k].r1, r2 = vrl[k].r2;
        if (fb[j][r1] && fb[i - j][r2])
          fs[i][l] = min(fs[i][l], fs[j][r1] + fs[i - j][r2]), fb[i][l] = true;
        if (fb[i - j][r1] && fb[j][r2])
          fs[i][l] = min(fs[i][l], fs[i - j][r1] + fs[j][r2]), fb[i][l] = true;
      }

    cal_zero_ln(i);
  }

  if (ch_num['S'] != -1 && fb[M][ch_num['S']])
    cout << fs[M][ch_num['S']] << endl;
  else
    cout << "-" << endl;
}

void cal_zero_ln(int ln) {
  for (int i = 0; i < C; ++i)
    for (int j = 0; j < R; ++j) {
      int l = vrl[j].l, r1 = vrl[j].r1, r2 = vrl[j].r2;
      if (fb[ln][r1] && fb[0][r2])
        fs[ln][l] = min(fs[ln][l], fs[ln][r1] + fs[0][r2]), fb[ln][l] = true;
      if (fb[0][r1] && fb[ln][r2])
        fs[ln][l] = min(fs[ln][l], fs[0][r1] + fs[ln][r2]), fb[ln][l] = true;
    }
}
accuracy: 1
time_ms: 1290
memory_kb: 1540
final_rank: 4

code_snippet: #include <string.h>
#include <iostream>
#include <string>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
inline void cmin(string &a, const string& b) { if (a > b) a = b; }
inline void cmin(string &a, const string& b, const string& c) {
    if (!a.size() || (b.size()&&b[0]=='|') || (c.size()&&c[0]=='|')) return ;
    if (a.size() != b.size() + c.size()) { a = b+c; return ; }
    const int L = b.size();
    int y = strncmp(b.c_str(), a.c_str(), L);
    if (y == 0) y = strncmp(c.c_str(), a.c_str()+L, c.size());
    if (y >= 0) return ;
    rep (i, b.size()) a[i] = b[i];
    rep (i, c.size()) a[b.size()+i] = c[i];
}
 
int n, L;
char from[64];
string to[64], dp[32][24], sub[2][24];
 
string solve() {
    rep (i, 32) rep (j, 24) dp[i][j] = '|';
    bool up;
    rep (LL, L+1) do {
        up = false;
        rep (k, n) {
            int cur = 0, nxt = 1;
            rep (i, 24) sub[cur][i] = '|';
            sub[cur][0] = "";
            rep (i, to[k].size()) {
                rep (j, 24) sub[nxt][j] = '|';
                if (islower(to[k][i])) {
                    rep (x, LL) cmin(sub[nxt][x+1], sub[cur][x]+to[k][i]);
                }
                else {
                    const int t = to[k][i] - 'A';
                    rep (j, LL+1) rep (x, LL-j+1) {
                        cmin(sub[nxt][x+j], sub[cur][x], dp[t][j]);
                    }
                }
                swap(cur, nxt);
            }
            const int f = from[k] - 'A';
            if (dp[f][LL] > sub[cur][LL]) dp[f][LL] = sub[cur][LL], up = true;
        }
    } while (up);
    if (dp['S'-'A'][L] == "|") return "-";
    return dp['S'-'A'][L];
}

int main() {
    for (;;) {
        cin >> n >> L;
        if (n == 0) return 0;
        string buf;
        rep (i, n) {
            cin >> buf;
            from[i] = buf[0];
            to[i] = buf.substr(2);
        }
        cout << solve() << endl;
    }
}
accuracy: 1
time_ms: 2270
memory_kb: 964
final_rank: 3

code_snippet: #include <string.h>
#include <ctype.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
inline void cmin(string &a, const string& b) { if (a > b) a = b; }
inline void cmin(string &a, const string& b, const string& c) {
    if (a.size() == 0) return ;
    if (b.size() && b[0] == '|') return ;
    if (c.size() && c[0] == '|') return ;
    if (a.size() != b.size() + c.size()) {
        a = b+c;
        return ;
    }
    else {
        int y = 0;
        rep (i, b.size()) {
            if (b[i] < a[i]) { y = -1; break; }
            if (b[i] > a[i]) { y = 1; break; }
        }
        if (y == 0) rep (i, c.size()) {
            if (c[i] < a[b.size()+i]) { y = -1; break; }
            if (c[i] > a[b.size()+i]) { y = 1; break; }
        }
        if (y < 0) {
            rep (i, b.size()) a[i] = b[i];
            rep (i, c.size()) a[b.size()+i] = c[i];
        }
    }
}
 
int n, L;
char from[64];
string to[64];
 
int has[32][24];
string dp[32][24], sub[2][24];
int minL[32], maxL[32];
 
string solve() {
    memset(has, 0, sizeof(has));
    rep (i, 32) rep (j, 24) dp[i][j] = '-';
    rep (i, 32) minL[i] = 1<<20;
    rep (i, 32) maxL[i] = -(1<<20);
    rep (LL, L+1) {
        for (;;) {
            bool update = false;
            rep (k, n) {
                int minE = 0, maxE = 0;
                rep (i, to[k].size()) {
                    if (islower(to[k][i])) minE++, maxE++;
                    else {
                        const int t = to[k][i] - 'A';
                        minE += minL[t];
                        maxE += maxL[t];
                    }
                }
                if (LL < minE || maxE < LL) continue;
                int cur = 0, nxt = 1;
                rep (i, 24) sub[cur][i] = '|';
                sub[cur][0] = "";
                rep (i, to[k].size()) {
                    rep (j, 24) sub[nxt][j] = '|';
                    if (islower(to[k][i])) {
                        rep (x, LL) cmin(sub[nxt][x+1], sub[cur][x]+to[k][i]);
                    }
                    else {
                        const int t = to[k][i] - 'A';
                        rep (j, LL+1) if (has[t][j]) rep (x, LL-j+1) {
                            cmin(sub[nxt][x+j], sub[cur][x], dp[t][j]);
                        }
                    }
                    swap(cur, nxt);
                }
                const int f = from[k] - 'A';
                if (sub[cur][LL] != "|") {
                    if (!has[f][LL] || dp[f][LL] > sub[cur][LL]) {
                        minL[f] = min(minL[f], LL);
                        maxL[f] = max(maxL[f], LL);
                        has[f][LL] = true;
                        update = true;
                        dp[f][LL] = sub[cur][LL];
                    }
                }
            }
            if (!update) break;
        }
    }
    return dp['S'-'A'][L];
}

int main() {
    for (;;) {
        cin >> n >> L;
        if (n == 0) return 0;
        string buf;
        rep (i, n) {
            cin >> buf;
            from[i] = buf[0];
            to[i] = buf.substr(2);
        }
        cout << solve() << endl;
    }
}
accuracy: 1
time_ms: 2650
memory_kb: 960
final_rank: 5

code_snippet: #include<iostream>
#include<string>
#include<vector>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define ALL(C)     (C).begin(),(C).end()
#define pb         push_back
#define mp         make_pair

typedef pair<int,int> pii;

const int N=800;
const int Rs='z'+1;
const int SPACE='A'-1;
bool isequal[N][N];
bool leadSpace[N];
string table[21][N];
bool   isexist[21][N];

void get_input(int n,vector<pii> *rule,int &p){
  rep(i,n){
    string in;
    cin>>in;
    if (in.size()== 2){//SPACE
      leadSpace[in[0]]=true;
      rule[in[0]].pb(mp(SPACE,SPACE));
    }else{
      int me  = in[0];
      REP(j,2,(int)in.size()-1){
	//	cout <<"rule "<< me <<" " << (int)in[j] <<" " <<p << endl;
	rule[me].pb(mp(in[j],p));
	me=p;
	p++;
      }
      //      cout <<"rule "<< me <<" " << (int)in[in.size()-1] << " " << SPACE<<endl;
      rule[me].pb(mp(in[in.size()-1],SPACE));
    }
  }
}

void make_space(int p,vector<pii> *rule){
  rep(k,p){
    rep(i,p){
      rep(j,rule[i].size()){
	if (leadSpace[rule[i][j].first]&&leadSpace[rule[i][j].second]){
	  leadSpace[i]=true;
	}
      }
    }
  }
}

bool vis[N];
void make_equal(int from,int now,vector<pii>*rule){
  if (vis[now])return;
  vis[now]=true;
  if (now != SPACE && !((int)'a'<=now && now <=(int)'z'))isequal[from][now]=true;
  rep(i,rule[now].size()){
    if (leadSpace[rule[now][i].first]){
      make_equal(from,rule[now][i].second,rule);
    }
    if (leadSpace[rule[now][i].second]){
      make_equal(from,rule[now][i].first,rule);
    }
  }
}

string solve(int p,int len,vector<pii> *rule){
  rep(i,p){
    rep(j,21){
      table[j][i]=string(1,(char)'z'+1);
      isexist[j][i]=false;
    }
  }

  rep(i,p){
    if (leadSpace[i]){
      table[0][i]="";
      isexist[0][i]=true;
    }
  }

  REP(k,1,len+1){
    rep(i,p){
      rep(j,rule[i].size()){
	if ('a'<= rule[i][j].first && rule[i][j].first <='z'){
	  if (isexist[k-1][rule[i][j].second]){
	    isexist[k][i]=true;
	    table[k][i]=min(table[k][i],string(1,(char)rule[i][j].first)+table[k-1][rule[i][j].second]);
	  }
	}else {
	  rep(l,k+1){
	    if (isexist[l][rule[i][j].first] &&
		isexist[k-l][rule[i][j].second]){
	      isexist[k][i]=true;
	      table[k][i]=min(table[k][i],
			      table[l][rule[i][j].first]+table[k-l][rule[i][j].second]);
	    }
	  }
	}
      }
    }
    
    
    rep(i,p){
      rep(j,p){
	if (i != j && isequal[i][j]){
	  if (isexist[k][i] && isexist[k][j]){
	    table[k][i]=min(table[k][i],table[k][j]);
	  } else if (isexist[k][j] && !isexist[k][i]){
	    isexist[k][i]=true;
	    table[k][i]=table[k][j];
	  }
	}
      }
    }
  }
   
  if (isexist[len]['S'])return table[len]['S'];
  return "-";
}

main(){
  int n,l;
  while(cin>>n>>l && n){
    rep(i,N){
      rep(j,N)isequal[i][j]=false;
      isequal[i][i]=true;
    }
    rep(i,N)leadSpace[i]=false;
    leadSpace[SPACE]=true;

    vector<pii> rule[N];
    int p = Rs;
    get_input(n,rule,p);

    make_space(p,rule);

    rep(i,p){
      rep(j,p)vis[j]=false;
      make_equal(i,i,rule);
    }

    cout << solve(p,l,rule) << endl;
  }
  return false;
}
accuracy: 1
time_ms: 260
memory_kb: 2036
final_rank: 1

code_snippet: #include<iostream>
#include<string>
#include<vector>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define ALL(C)     (C).begin(),(C).end()
#define pb         push_back
#define mp         make_pair

typedef pair<int,int> pii;

const int N=800;
const int Rs='z'+1;
const int SPACE='A'-1;
bool isequal[N][N];
bool leadSpace[N];
string table[21][N];
bool   isexist[21][N];

void get_input(int n,vector<pii> *rule,int &p){
  rep(i,n){
    string in;
    cin>>in;
    if (in.size()== 2){//SPACE
      leadSpace[in[0]]=true;
      rule[in[0]].pb(mp(SPACE,SPACE));
    }else{
      int me  = in[0];
      REP(j,2,(int)in.size()-1){
	//	cout <<"rule "<< me <<" " << (int)in[j] <<" " <<p << endl;
	rule[me].pb(mp(in[j],p));
	me=p;
	p++;
      }
      //      cout <<"rule "<< me <<" " << (int)in[in.size()-1] << " " << SPACE<<endl;
      rule[me].pb(mp(in[in.size()-1],SPACE));
    }
  }
}

void make_space(int p,vector<pii> *rule){
  rep(k,p){
    rep(i,p){
      rep(j,rule[i].size()){
	if (leadSpace[rule[i][j].first]&&leadSpace[rule[i][j].second]){
	  leadSpace[i]=true;
	}
      }
    }
  }
}

bool vis[N];
void make_equal(int from,int now,vector<pii>*rule){
  if (vis[now])return;
  vis[now]=true;
  if (now != SPACE && !((int)'a'<=now && now <=(int)'z'))isequal[from][now]=true;
  rep(i,rule[now].size()){
    if (leadSpace[rule[now][i].first]){
      make_equal(from,rule[now][i].second,rule);
    }
    if (leadSpace[rule[now][i].second]){
      make_equal(from,rule[now][i].first,rule);
    }
  }
}

string solve(int p,int len,vector<pii> *rule){
  rep(i,p){
    rep(j,21){
      table[j][i]=string(1,(char)'z'+1);
      isexist[j][i]=false;
    }
  }

  rep(i,p){
    if (leadSpace[i]){
      table[0][i]="";
      isexist[0][i]=true;
    }
  }

  REP(k,1,len+1){
    //    cout <<"len " << k << endl;
    rep(i,p){
      rep(j,rule[i].size()){
	if ('a'<= rule[i][j].first && rule[i][j].first <='z'){
	  if (isexist[k-1][rule[i][j].second]){
	    isexist[k][i]=true;
	    //	    cout << i <<" " << rule[i][j].first << " "<<rule[i][j].second <<"::"<<
	    //	    	      string(1,rule[i][j].first) <<" " <<
	    //	      table[k-1][rule[i][j].second] <<endl;

	    table[k][i]=min(table[k][i],string(1,(char)rule[i][j].first)+table[k-1][rule[i][j].second]);
	  }
	}else {
	  rep(l,k+1){
	    if (isexist[l][rule[i][j].first] &&
		isexist[k-l][rule[i][j].second]){
	      isexist[k][i]=true;
	      //	      cout << i <<" " << rule[i][j].first <<" " << rule[i][j].second 
	      //		   <<":" << table[l][rule[i][j].first] <<" " 
	      //		   << table[k-l][rule[i][j].second] << endl;
	      table[k][i]=min(table[k][i],
			      table[l][rule[i][j].first]+table[k-l][rule[i][j].second]);
	    }
	  }
	}
      }
    }
    
    
    rep(i,p){
      rep(j,p){
	if (i != j && isequal[i][j]){
	  //	  cout << i <<" " << j << endl;
	  //	  cout << isexist[k][i] <<" " << isexist[k][j] << endl;
	  //	  cout << table[k][i] <<" " << table[k][j] << endl;
	  if (isexist[k][i] && isexist[k][j]){
	    table[k][i]=min(table[k][i],table[k][j]);
	    //table[k][j]=min(table[k][i],table[k][j]);
	  //	  }else if (isexist[k][i]){
	    //isexist[k][j]=true;
	    //table[k][j]=table[k][i];
	  //	  } else if (isexist[k][j]){
	  } else if (isexist[k][j] && !isexist[k][i]){
	    isexist[k][i]=true;
	    table[k][i]=table[k][j];
	    //	  }
	  }
	}
      }
    }
    
  }

    
  
  rep(i,p){
    //    if (leadSpace[i])cout << "lead space " << i << endl;
  }

  rep(i,p){
    rep(j,p){
      //      if (i != j && isequal[i][j])cout << "equal " << i <<" " <<j << endl;
    }
  }

  rep(i,p){
    rep(j,len+1){
      //      if (isexist[j][i])cout <<i <<" " << j <<" "<<  table[j][i] << endl;
    }
  }
    

  if (isexist[len]['S'])return table[len]['S'];
  return "-";
}

main(){
  int n,l;
  while(cin>>n>>l && n){
    rep(i,N){
      rep(j,N)isequal[i][j]=false;
      isequal[i][i]=true;
    }
    rep(i,N)leadSpace[i]=false;
    leadSpace[SPACE]=true;

    vector<pii> rule[N];
    int p = Rs;
    get_input(n,rule,p);

    make_space(p,rule);

    rep(i,p){
      rep(j,p)vis[j]=false;
      make_equal(i,i,rule);
    }
    /*
    rep(i,p){
      rep(j,p)if (isequal[i][j])isequal[j][i]=true;
    }
    */

    cout << solve(p,l,rule) << endl;
  }
  return false;
}
accuracy: 1
time_ms: 260
memory_kb: 2036
final_rank: 1