/*
String DP, but you need to find the minimum string to match, so you can use DP to store the number of currently used strings.
Print the path and use an array to indicate the prefix.
*/
# Include <iostream>
# Include <string>
# Include <cstring>
# Include <cstdio>
Using namespace STD;
String S = "22233344115566070778889990 ";
# Define x 50010
Int DP [X], pre [X], Len [X], p [X], L;
String a [X], in [X], B;
Void change (int x)
{
Len [x] = in [X]. Size ();
For (INT I = 0; I <Len [X]; I ++)
A [X]. push_back (s [in [x] [I]-'a']);
}
Bool check (int I, Int J) // you can check whether a match exists.
{
For (int K = Len [J]-1; k> = 0; k --)
If (B [I-1] = A [J] [k])
I --;
Else
Return false;
Return true;
}
Void print (int x) // recursive print path
{
If (P [x]> 0)
{
Print (P [x]);
Cout <"";
}
Cout <in [pre [x];
}
Int main ()
{
Freopen ("sum. In", "r", stdin );
Freopen ("sum. Out", "W", stdout );
Int N;
While (CIN> B, B [0]! = '-')
{
Cin> N;
For (INT I = 0; I <n; I ++)
{
Cin> in [I];
Change (I );
}
Memset (PRE,-1, sizeof (pre ));
Memset (p,-1, sizeof (p ));
L = B. Size ();
Memset (DP,-1, sizeof (DP ));
DP [0] = 0;
For (INT I = 1; I <= L; I ++)
{
For (Int J = 0; j <n; j ++)
If (LEN [J] <= I & B [I-1] = A [J] [Len [J]-1] & check (I, j ))
{
If (DP [I-len [J] =-1) // if the previous one cannot match
Continue;
Int X;
If (DP [I] =-1) // no other string matches currently
X = DP [I-len [J] + 1;
Else // There are other strings, take the smallest one
X = min (DP [I], DP [I-len [J] + 1 );
If (DP [I]! = X) // if the current string does not match or the current number is less than the number of previously matched strings, update
{
DP [I] = DP [I-len [J] + 1;
Pre [I] = J;
P [I] = I-len [J];
}
}
}
If (DP [l] <0)
Cout <"no solution." <Endl;
Else
{
Print (L );
Cout <Endl;
}
}
Return 0;
}