#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
using namespace std;
#define endl '\n'
// 计算两个字符串的最长公共前缀的长度
int LCP(const string& s1, const string& s2) {
int i = 0;
while (i < s1.size() && i < s2.size() && s1[i] == s2[i]) {
i++;
}
return i;
}
// 计算一个序列中的逆序对数
long long count_inversions(const vector<string>& seq, const string& alphabet) {
// 预处理每个字符串的排名和每个字母在每个位置上的出现次数
int n = seq.size(); // 序列的长度
int m = seq[0].size(); // 字符串的长度
vector<int> rank(n); // 每个字符串的排名
vector<vector<vector<int>>> cnt(n, vector<vector<int>>(m, vector<int>(26, 0))); // 每个字符串的每个位置上的每个字母的出现次数
vector<string> sorted_seq = seq; // 排序后的序列
sort(sorted_seq.begin(), sorted_seq.end()); // 按照字典序排序
for (int i = 0; i < n; i++) {
rank[i] = lower_bound(sorted_seq.begin(), sorted_seq.end(), seq[i]) - sorted_seq.begin(); // 找到每个字符串的排名
for (int j = 0; j < m; j++) {
cnt[i][j][seq[i][j] - 'a'] = 1; // 统计每个字符串的每个位置上的每个字母的出现次数
}
}
// 初始化每个位置上的逆序对数和累积和
vector<long long> inv(m, 0); // 每个位置上的逆序对数
vector<long long> sum(m, 0); // 每个位置上的逆序对数的累积和
// 遍历每个位置
for (int j = 0; j < m; j++) {
vector<int> freq(26, 0); // 每个字母在这个位置上出现的次数
int total = 0; // 这个位置上出现的字符串的总数
// 遍历每个字母
for (int k = 0; k < 26; k++) {
char c = alphabet[k]; // 当前的字母
int cur = 0; // 这个字母在这个位置上出现的字符串的个数
// 遍历每个排名
for (int i = 0; i < n; i++) {
int idx = pos[i]; // 找到对应的字符串的下标
freq[c - 'a'] += cnt[idx][j][c - 'a']; // 更新这个字母在这个位置上出现的次数
cur += cnt[idx][j][c - 'a']; // 更新这个字母在这个位置上出现的字符串的个数
}
// 更新这个位置上的逆序对数
inv[j] += (long long)(total - cur) * cur;
// 更新这个位置上出现的字符串的总数
total += cur;
}
// 更新这个位置上的逆序对数的累积和
sum[j] = (j == 0 ? 0 : sum[j-1]) + inv[j];
}
// 返回整个序列的逆序对数
return sum[m-1];
}
int main() {
// 输入序列的长度和宇宙的个数
int n, q;
cin >> n >> q;
// 输入序列
vector<string> seq(n);
for (int i = 0; i < n; i++) {
cin >> seq[i];
}
// 对于每个宇宙,输入字母顺序,计算并输出逆序对数
for (int i = 0; i < q; i++) {
string alphabet;
cin >> alphabet;
cout << count_inversions(seq, alphabet) << endl;
}
return 0;
}