#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define all(v) v.begin(), v.end()
using namespace std;
using ll = int64_t;
struct Node {
map<char, Node*> next;
Node* suffix_link;
Node* parent;
vector<int> ends;
char c;
int len;
int id;
Node() : suffix_link(0), parent(0), c(0), len(0), id(0) {}
Node(Node* p, char x, int y) : suffix_link(0), parent(p), c(x), len(y), id(0) {}
};
Node root;
void add(Node* cursor, string s, int i) {
for (char c : s) {
if (!cursor->next.count(c)) {
cursor->next[c] = new Node(cursor, c, cursor->len + 1);
}
cursor = cursor->next[c];
}
cursor->ends.pb(i);
}
Node* get_sl(Node* n, char c) {
Node* ans = n;
while (ans != &root && !ans->next.count(c)) {
ans = ans->suffix_link;
}
if (ans->next.count(c)) {
ans = ans->next[c];
}
return ans;
}
vector<Node*> build() {
queue<Node*> q;
vector<Node*> v;
q.push(&root);
int ids = 0;
while (!q.empty()) {
Node* n = q.front(); q.pop();
v.pb(n);
n->id = ids++;
if (n == &root || n->parent == &root) {
n->suffix_link = &root;
} else {
Node* ans = n->parent->suffix_link;
while (ans != &root && !ans->next.count(n->c)) {
ans = ans->suffix_link;
}
if (ans->next.count(n->c)) {
ans = ans->next[n->c];
}
n->suffix_link = get_sl(n->parent->suffix_link, n->c);
}
for (auto p : n->next) {
q.push(p.second);
}
}
return v;
}
const int N = 202, D = 27;
int g[N + 2][D];
ll d[N + 2][N][N];
bool can[N + 2][N][N];
ll weight[N + 2];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
ll length;
cin >> length;
vector<ll> adds(n);
for (int i = 0; i < n; i++)
cin >> adds[i];
for (int i = 0; i < n; i++) {
string s;
cin >> s;
add(&root, s, i);
}
auto all_nodes = build();
int k = all_nodes.size();
for (Node* node : all_nodes) {
auto cursor = node;
while (cursor != &root) {
for (int i : cursor->ends) {
weight[node->id] += adds[i];
}
cursor = cursor->suffix_link;
}
//cerr << weight[node->id] << endl;
for (char c = 'a'; c <= ('z' + 1); c++) {
Node* jump = get_sl(node, c);
g[node->id][c - 'a'] = jump->id;
}
}
for (int i = 0; i < k; i++) {
can[0][i][i] = true;
}
for (int m = 0; m < N - 1; m++) {
for (int s = 0; s < k; s++) {
for (int e = 0; e < k; e++) {
if (can[m][s][e]) {
for (int l = 0; l < D; l++) {
int v = g[e][l];
can[m + 1][s][v] = true;
d[m + 1][s][v] = max(d[m + 1][s][v], d[m][s][e] + weight[v]);
}
}
}
}
}
ll res = 0;
for (int i = 0; i <= min(ll(N), length + 1); i++)
res = max(res, d[i][0][0]);
for (int prefix = 0; prefix <= N; prefix++) {
for (int suffix = 0; suffix <= N; suffix++) {
ll remain = length - suffix - prefix;
if (remain > 1) {
for (int cycle = 1; cycle <= N; cycle++) {
if (remain % cycle == 0) {
ll times = remain / cycle;
for (int s = 0; s < k; s++) {
if (can[prefix][0][s] && can[suffix + 1][s][0] && can[cycle][s][s]) {
res = max(res, d[prefix][0][s] + d[suffix + 1][s][0] + d[cycle][s][s] * times);
}
}
}
}
}
}
}
cout << res << endl;
return 0;
}