#include <bits/stdc++.h>
using namespace std;
struct MyGraph {
  int size;
  vector<string> prefix;
  vector<int> score;
  vector<map<char, int>> next;
  vector<vector<int>> back;
  MyGraph() : size(0) { add(""); }
  int add(string newPrefix) {
    int res = size;
    size++;
    prefix.push_back(newPrefix);
    next.emplace_back();
    back.emplace_back();
    score.push_back(0);
    return res;
  }
};
int main() {
  int n;
  long long l;
  scanf("%d%lld", &n, &l);
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
  }
  map<string, int> words;
  for (int i = 0; i < n; i++) {
    char buff[256];
    scanf("%s", buff);
    words[buff] += a[i];
  }
  MyGraph graph;
  for (auto kv : words) {
    int cur = 0;
    string s = kv.first;
    for (int i = 1; i <= s.size(); i++) {
      if (graph.next[cur].count(s[i - 1])) {
        cur = graph.next[cur][s[i - 1]];
        continue;
      }
      auto prefix = s.substr(0, i);
      int last = cur;
      cur = graph.add(prefix);
      graph.next[last][s[i - 1]] = cur;
    }
  }
  for (int i = 0; i < graph.size; i++) {
    for (int nextch = 'a'; nextch <= 'z'; nextch++) {
      if (graph.next[i].count(nextch)) continue;
      auto prefcheck = graph.prefix[i];
      prefcheck.push_back(nextch);
      int maxmatch = 0, matched = 0;
      for (int j = graph.size - 1; j > 0; j--) {
        int dlen = graph.prefix[j].length();
        int plen = prefcheck.length();
        if (dlen >= plen) continue;
        if (dlen <= maxmatch) continue;
        if (strcmp(graph.prefix[j].c_str(),
                   prefcheck.c_str() + (plen - dlen)) == 0) {
          maxmatch = dlen;
          matched = j;
        }
      }
      graph.back[i].push_back(matched);
    }
  }
  for (int i = 0; i < graph.size; i++) {
    for (auto kv : words) {
      auto s = kv.first;
      auto p = graph.prefix[i];
      if (s.length() > p.length()) continue;
      if (strcmp(p.c_str() + (p.length() - s.length()), s.c_str()) == 0) {
        graph.score[i] += kv.second;
      }
    }
  }
  int mn = graph.size;
  vector<long long> mat(mn * mn, -1);
  for (int i = 0; i < mn; i++) {
    for (auto kv : graph.next[i]) {
      mat[i * mn + kv.second] = graph.score[kv.second];
    }
    for (auto next : graph.back[i]) {
      mat[i * mn + next] = graph.score[next];
    }
  }
  vector<long long> tmp(mn * mn, -1);
  vector<long long> res(mn * mn, -1);
  res[0] = 0;
  while (l) {
    if (l % 2) {
      for (int i = 0; i < mn; i++) {
        for (int j = 0; j < mn; j++) {
          long long bestval = -1;
          for (int k = 0; k < mn; k++) {
            auto a = res[(i)*mn + (k)];
            auto b = mat[(k)*mn + (j)];
            if (a == -1 || b == -1) continue;
            bestval = max(bestval, a + b);
          }
          tmp[(i)*mn + (j)] = bestval;
        }
      }
      tmp.swap(res);
    }
    for (int i = 0; i < mn; i++) {
      for (int j = 0; j < mn; j++) {
        long long bestval = -1;
        for (int k = 0; k < mn; k++) {
          auto a = mat[(i)*mn + (k)];
          auto b = mat[(k)*mn + (j)];
          if (a == -1 || b == -1) continue;
          bestval = max(bestval, a + b);
        }
        tmp[(i)*mn + (j)] = bestval;
      }
    }
    tmp.swap(mat);
    l /= 2;
  }
  long long ans = 0;
  for (int i = 0; i < mn; i++) {
    ans = max(ans, res[i]);
  }
  printf("%lld\n", ans);
  return 0;
}
