#include <bits/stdc++.h>   using std::abs;   using std::bitset;   using std::cerr;   using std::cin;   using std::copy;   using std::cout;   using std::deque;   using std::endl;   using std::fill;   using std::fixed;   using std::greater;   using std::iota;   using std::istream;   using std::lower_bound;   using std::make_pair;   using std::make_tuple;   using std::map;   using std::max;   using std::max_element;   using std::min;   using std::min_element;   using std::multiset;   using std::next_permutation;   using std::nth_element;   using std::ostream;   using std::pair;   using std::priority_queue;   using std::queue;   using std::reverse;   using std::rotate;   using std::set;   using std::sort;   using std::string;   using std::swap;   using std::tie;   using std::tuple;   using std::unique;   using std::unordered_map;   using std::unordered_set;   using std::upper_bound;   using std::vector;   long long rnd(long long x, long long y) {     static auto gen = std::bind(std::uniform_int_distribution<long long>(),                                 std::mt19937(960172));     return gen() % (y - x + 1) + x;   }   long long gcd(long long a, long long b) {     while (b > 0) {       long long t = a % b;       a = b;       b = t;     }     return a;   }   template <typename T>   T sqr(T const& a) {     return a * a;   }   int const INF = 100 + (int)1e9;   long long const INFL = 100 + (long long)1e18;   long double const PI = 3.1415926535897932384626433832795028;   int const N = 211;   int const A = 26;   int next[N][A];   int link[N];   int go[N][A];   int prev[N];   int back[N];   int leaf[N];   int sz;   int getNode(int pr, int edge) {     std::fill(next[sz], next[sz] + A, -1);     link[sz] = -1;     std::fill(go[sz], go[sz] + A, -1);     prev[sz] = pr;     back[sz] = edge;     leaf[sz] = 0;     return sz++;   }   int getGo(int, int);   int getLink(int v) {     if (link[v] == -1) {       if (v == 0 || prev[v] == 0) {         link[v] = 0;       } else {         link[v] = getGo(getLink(prev[v]), back[v]);       }     }     return link[v];   }   int getGo(int v, int x) {     if (go[v][x] == -1) {       if (next[v][x] != -1) {         go[v][x] = next[v][x];       } else if (v == 0) {         go[v][x] = v;       } else {         go[v][x] = getGo(getLink(v), x);       }     }     return go[v][x];   }   void mul(long long a[N][N], long long b[N][N], long long c[N][N]) {     static long long t[N][N];     for (int i = 0; i < N; ++i) {       for (int j = 0; j < N; ++j) {         long long cur = -INFL;         for (int k = 0; k < N; ++k) {           cur = max(cur, a[i][k] + b[k][j]);         }         t[i][j] = cur;       }     }     for (int i = 0; i < N; ++i) {       for (int j = 0; j < N; ++j) {         c[i][j] = t[i][j];       }     }   }   int a[N];   void solve() {     int n;     long long L;     scanf(          %d           %lld ,         &n, &L);     for (int i = 0; i < n; ++i) {       scanf( %d , a + i);     }     static char buf[N];     gets(buf);     getNode(0, 0);     for (int i = 0; i < n; ++i) {       gets(buf);       int v = 0;       for (int j = 0; buf[j]; ++j) {         int x = buf[j] -  a ;         if (next[v][x] == -1) {           next[v][x] = getNode(v, x);         }         v = next[v][x];       }       leaf[v] += a[i];     }     {       vector<int> q = {0};       for (int head = 0; head < (int)q.size(); ++head) {         int v = q[head];         leaf[v] += leaf[getLink(v)];         for (int x = 0; x < A; ++x) {           int to = next[v][x];           if (to >= 0) {             q.push_back(to);           }         }       }     }     static long long mat[N][N];     for (int i = 0; i < N; ++i) {       fill(mat[i], mat[i] + N, -INFL);     }     for (int from = 0; from < sz; ++from) {       for (int x = 0; x < A; ++x) {         int to = getGo(from, x);         if (mat[to][from] == -INFL) {           mat[to][from] = 0;         }         mat[to][from] += leaf[to];       }     }     static long long dp[N];     fill(dp, dp + N, -INFL);     dp[0] = 0;     for (long long l = L; l > 0; l /= 2) {       if (l % 2 == 1) {         static long long dp1[N];         for (int v = 0; v < N; ++v) {           long long cur = -INFL;           for (int u = 0; u < N; ++u) {             cur = max(cur, dp[u] + mat[v][u]);           }           dp1[v] = cur;         }         for (int i = 0; i < N; ++i) {           dp[i] = dp1[i];         }       }       mul(mat, mat, mat);     }     cout << *max_element(dp, dp + N) << endl;   }   int main() {     cout.precision(15);     cout << fixed;     cerr.precision(6);     cerr << fixed;     solve();   }