// Arup Guha
// 5/11/2020
// Alternate Solution to COP 3502 Week #1 Program: Scrabble

// This solution uses a double for loop to determine if a word can be formed
// with a set of tiles. Since our words are small, this solution is as
// efficient as the originally posted solution.

#include <stdio.h>
#include <string.h>

// Limits on the dictionary of words.
const int MAXWORDS = 100;
const int MAXSIZE = 7;

// Number of letters...
const int NUMLETTERS = 26;

// Scores of all tiles in Scrabble.
const int TILESCORES[] = {1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10};

// Function Prototypes
int canForm(char* word, char* tiles);
int score(char* word,int letterMult[], int wordMult[]);

int main(void) {

    int numCases;
    scanf("%d", &numCases);

    // Process each case.
    for (int loop=0; loop<numCases; loop++) {

        int numWords;
        scanf("%d", &numWords);

        // Read in words.
        char words[MAXWORDS][MAXSIZE+1];
        for (int i=0; i<numWords; i++)
            scanf("%s", words[i]);

        // Read in your tiles.
        char tiles[MAXSIZE+1];
        scanf("%s", tiles);

        // Store all multipliers here.
        int letterMult[MAXSIZE];
        int wordMult[MAXSIZE];

        // Read in letter multipliers.
        for (int i=0; i<MAXSIZE; i++)
            scanf("%d", &letterMult[i]);

        // Read in word multipliers.
        for (int i=0; i<MAXSIZE; i++)
            scanf("%d", &wordMult[i]);

        // Store the answer here.
        int best = 0;

        // Try each word.
        for (int i=0; i<numWords; i++) {

            // Skip words we can't form.
            if (!canForm(words[i], tiles)) continue;

            // Score this word.
            int curScore = score(words[i], letterMult, wordMult);

            // Update if this word is best one yet.
            if (curScore > best) best = curScore;
        }

        // Output the best possible score.
        printf("%d\n", best);
    }

    return 0;
}

// Pre-condition: word stores the word to be formed, and tiles has the
//                tiles to be used. tiles is length 7 and both have uppercase
//                letters only.
// Post-condition: Returns 1 if the tiles can be used to form the word and
//                 0 otherwise.
int canForm(char* word, char* tiles) {

    // Initially, we haven't used any tiles.
    int used[MAXSIZE];
    for (int i=0; i<MAXSIZE; i++)
        used[i] = 0;

    int wordlen = strlen(word);

    // Go through each letter.
    for (int i=0; i<wordlen; i++) {

        int gotit = 0;
        for (int j=0; j<MAXSIZE; j++) {

            // We already used this tile, skip it.
            if (used[j]) continue;

            // If this is true, we can use this tile!
            if (word[i] == tiles[j]) {
                used[j] = 1;
                gotit = 1;
                break;
            }
        }

        // We never got this letter, so we can't form the word.
        if (!gotit) return 0;
    }

    // If we get here, we are good.
    return 1;
}

// Pre-condition: word is 7 or fewer upper case letters, letterMult and
//                wordMult are of size 26, all values in letterMult are 1
//                except for at most 1, and all values in both arrays are
//                1, 2 or 3.
// Post-condition: The score of word according to the simplified Scrabble
//                 rules given is returned.
int score(char* word,int letterMult[], int wordMult[]) {

    int total = 0, len = strlen(word), mult = 1;

    // Go through each letter and add up letter scores with letter multipliers.
    // Also, multiply together the word multiplier.
    for (int i=0; i<len; i++) {
        total += (TILESCORES[word[i]-'A']*letterMult[i]);
        mult *= wordMult[i];
    }

    // This is the final score of the word.
    return mult*total;
}
