#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;
}
