#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000")
using namespace std;
void solve();
void precalc();
clock_t start;
int testNumber = 1;
bool todo = true;
int main() {
  start = clock();
  int t = 1;
  cout.sync_with_stdio(0);
  cin.tie(0);
  precalc();
  cout.precision(10);
  cout << fixed;
  int testNum = 1;
  while (t--) {
    solve();
    ++testNumber;
  }
  return 0;
}
template <typename T>
T binpow(T q, T w, T mod) {
  if (!w) return 1 % mod;
  if (w & 1) return q * 1LL * binpow(q, w - 1, mod) % mod;
  return binpow(q * 1LL * q % mod, w / 2, mod);
}
void precalc() {}
template <typename T>
T gcd(T q, T w) {
  while (w) {
    q %= w;
    swap(q, w);
  }
  return q;
}
template <typename T>
T lcm(T q, T w) {
  return q / gcd(q, w) * w;
}
const long long K = 26;
struct vertex {
  long long next[K];
  long long p;
  char pch;
  long long link;
  long long go[K];
  vector<long long> leaves;
  long long sum_good;
};
const long long NMAX = 1000;
vertex t[NMAX + 1];
long long sz;
void init() {
  t[0].p = t[0].link = -1;
  memset(t[0].next, 255, sizeof t[0].next);
  memset(t[0].go, 255, sizeof t[0].go);
  sz = 1;
}
void add_string(const string& s, long long id) {
  long long v = 0;
  for (size_t i = 0; i < s.length(); ++i) {
    char c = s[i] - 'a';
    if (t[v].next[c] == -1) {
      memset(t[sz].next, 255, sizeof t[sz].next);
      memset(t[sz].go, 255, sizeof t[sz].go);
      t[sz].link = -1;
      t[sz].p = v;
      t[sz].pch = c;
      t[v].next[c] = sz++;
    }
    v = t[v].next[c];
  }
  t[v].leaves.push_back(id);
}
long long go(long long v, char c);
long long get_link(long long v) {
  if (t[v].link == -1)
    if (v == 0 || t[v].p == 0)
      t[v].link = 0;
    else
      t[v].link = go(get_link(t[v].p), t[v].pch);
  return t[v].link;
}
long long go(long long v, char c) {
  if (t[v].go[c] == -1)
    if (t[v].next[c] != -1)
      t[v].go[c] = t[v].next[c];
    else
      t[v].go[c] = v == 0 ? 0 : go(get_link(v), c);
  return t[v].go[c];
}
const long long L = 50;
void solve() {
  long long n, l;
  cin >> n >> l;
  vector<long long> a(n);
  vector<string> s(n);
  for (long long i = 0; i < n; ++i) {
    cin >> a[i];
  }
  for (long long i = 0; i < n; ++i) {
    cin >> s[i];
  }
  init();
  for (long long i = 0; i < n; ++i) {
    add_string(s[i], i);
  }
  for (long long i = 0; i < sz; ++i) {
    long long link = get_link(i);
    while (link) {
      for (long long to : t[link].leaves) {
        t[i].leaves.push_back(to);
      }
      link = get_link(link);
    }
    sort(t[i].leaves.begin(), t[i].leaves.end());
    t[i].leaves.erase(unique(t[i].leaves.begin(), t[i].leaves.end()),
                      t[i].leaves.end());
    for (long long to : t[i].leaves) {
      t[i].sum_good += a[to];
    }
  }
  vector<vector<vector<long long>>> dp(
      L, vector<vector<long long>>(sz, vector<long long>(sz, -1e17)));
  for (long long i = 0; i < sz; ++i) {
    for (long long c = 0; c < 26; ++c) {
      long long nex = go(i, c);
      dp[0][i][nex] = max(dp[0][i][nex], t[nex].sum_good);
    }
  }
  for (long long i = 0; i + 1 < L; ++i) {
    for (long long v = 0; v < sz; ++v) {
      for (long long u = 0; u < sz; ++u) {
        for (long long w = 0; w < sz; ++w) {
          dp[i + 1][v][u] = max(dp[i + 1][v][u], dp[i][v][w] + dp[i][w][u]);
        }
      }
    }
  }
  vector<long long> best(sz, -1e17);
  vector<long long> new_best(sz, -1e17);
  best[0] = 0;
  for (long long i = 0; i < L; ++i) {
    if (l & 1) {
      new_best.assign(sz, -1e17);
      for (long long v = 0; v < sz; ++v) {
        for (long long u = 0; u < sz; ++u) {
          new_best[u] = max(new_best[u], best[v] + dp[i][v][u]);
        }
      }
      best.swap(new_best);
    }
    l >>= 1;
  }
  long long res = 0;
  for (long long to : best) {
    res = max(res, to);
  }
  cout << res << "\n";
}
