#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}

struct Matrix {
	typedef Matrix M;
	vvi d;int N;
	Matrix(const int &n,bool flag=0)
	{
		N=n;
		d.resize(N);
		rep(i,N){d[i].resize(N);fill(all(d[i]),-1);if(flag)d[i][i]=0;}

	}

	M operator*(const M& m) const {
		M a=M(N);
		rep(k,N)rep(i,N) rep(j,N)

			if(~d[i][k] and ~m.d[k][j]) a.d[i][j] =max(a.d[i][j],d[i][k]+m.d[k][j]);
		return a;
	}
	vector<ll> operator*(const vector<ll>& vec) const { //this is for M*vec=vec
		vector<ll> ret(N);
		rep(i,N) rep(j,N) ret[i] += d[i][j] * vec[j];
		return ret;
	}
	M operator^(ll p) const {
		assert(p >= 0);
		M a=M(N,1), b(*this);

		while (p) {
			if (p&1) a = a*b;
			b = b*b;
			p >>= 1;
		}
		return a;
	}
};

const int maxn=200;
string s[maxn];
int tr[maxn][27], au[maxn][27], nx = 1, e[maxn], a[maxn], f[maxn], matches[maxn],n;

inline void add(int i){
	int v = 0;
	for(auto ch: s[i]){
		int c = ch - 'a';
		if(!tr[v][c])
			tr[v][c] = nx ++;
		v = tr[v][c];
	}
	e[v] += a[i];
}
inline void ahoc(){
	queue<int> q;
	q.push(0);
	while(!q.empty()){
		int v = q.front();
		q.pop();
		if(f[v] != v)	{e[v] += e[f[v]];}
		repn(i,0,26){
			int u = tr[v][i];
			if(u){
				au[v][i] = u;
				if(v)
					f[u] = au[f[v]][i];
				q.push(u);
			}
			else
				au[v][i] = au[f[v]][i];
		}
	}
}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n,l;cin>>n>>l;
	rep(i,n){
		cin>>a[i];
	}
	rep(i,n){cin>>s[i];add(i);}ahoc();

	Matrix dp(nx);
	for(auto ch='a';ch<='z';ch++)rep(i,nx){
		dp.d[au[i][ch-'a']][i]=e[au[i][ch-'a']];}
	//rep(i,nx){rep(j,nx)cout<<dp.d[i][j]<<" ";cout<<"\n";}cout<<"\n";
	dp=dp^l;
	//rep(i,nx){rep(j,nx)cout<<dp.d[i][j]<<" ";cout<<"\n";}
	ll maxi=0;
	for(int final=0;final<nx;final++)
		maxi=max(dp.d[final][0],maxi);
	cout<<maxi;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}

struct Matrix {
	typedef Matrix M;
	vvi d;int N;
	Matrix(const int &n,bool flag=0)
	{
		N=n;
		d.resize(N);
		rep(i,N){d[i].resize(N);fill(all(d[i]),-1);if(flag)d[i][i]=0;}

	}

	M operator*(const M& m) const {
		M a=M(N);
		rep(k,N)rep(i,N) rep(j,N)

			if(~d[i][k] and ~m.d[k][j]) a.d[i][j] =max(a.d[i][j],d[i][k]+m.d[k][j]);
		return a;
	}
	vector<ll> operator*(const vector<ll>& vec) const { //this is for M*vec=vec
		vector<ll> ret(N);
		rep(i,N) rep(j,N) ret[i] += d[i][j] * vec[j];
		return ret;
	}
	M operator^(ll p) const {
		assert(p >= 0);
		M a=M(N,1), b(*this);

		while (p) {
			if (p&1) a = a*b;
			b = b*b;
			p >>= 1;
		}
		return a;
	}
};

const int maxn=201;
string s[maxn];
int tr[maxn][27], au[maxn][27], nx = 1, e[maxn], a[maxn], f[maxn], matches[maxn],n;

inline void add(int i){
	int v = 0;
	for(auto ch: s[i]){
		int c = ch - 'a';
		if(!tr[v][c])
			tr[v][c] = nx ++;
		v = tr[v][c];
	}
	e[v] += a[i];
}
inline void ahoc(){
	queue<int> q;
	q.push(0);
	while(!q.empty()){
		int v = q.front();
		q.pop();
		if(f[v] != v)	{e[v] += e[f[v]];}
		repn(i,0,26){
			int u = tr[v][i];
			if(u){
				au[v][i] = u;
				if(v)
					f[u] = au[f[v]][i];
				q.push(u);
			}
			else
				au[v][i] = au[f[v]][i];
		}
	}
}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	ll n,l;cin>>n>>l;
	rep(i,n){
		cin>>a[i];
	}
	rep(i,n){cin>>s[i];add(i);}ahoc();

	Matrix dp(nx);
	rep(i,nx)for(auto ch='a';ch<='z';ch++){
		dp.d[i][au[i][ch-'a']]=e[au[i][ch-'a']];}
	//rep(i,nx){rep(j,nx)cout<<dp.d[i][j]<<" ";cout<<"\n";}cout<<"\n";
	dp=dp^l;
	//rep(i,nx){rep(j,nx)cout<<dp.d[i][j]<<" ";cout<<"\n";}
	ll maxi=0;
	for(int final=0;final<nx;final++)
		maxi=max(dp.d[0][final],maxi);
	cout<<maxi;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

using namespace std;

/*******  All Required define Pre-Processors and typedef Constants *******/
#define scd(t) scanf("%d",&t)
#define scld(t) scanf("%ld",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define mem(a, b) memset(a, (b), sizeof(a))
#define repd(i,k) for(ll i=k;i>=0;i--)
#define rep(i,k) for(ll i=0;i<k;i++)
#define repn(i,k1,k2) for(ll i=k1;i<k2;i++)
#define sz(x) (ll)(x).size()
#define ff first
#define ss second

#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define mp make_pair
#define pb push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define ee6 (ll)1000001
#define ee5 (ll)100001

#define tt ll t;cin>>t; while(t--)
typedef long long int ll;

typedef pair<ll, ll> pr;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<pr> vpr;
typedef vector<vpr>vvpr;
typedef vector<vi> vvi;
typedef map<ll,ll> MPII;
typedef set<ll> SETI;
typedef multiset<ll> MSETI;
//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
    tree_order_statistics_node_update>;

ll powmod(ll a, ll e) {
	if (e == 0) return 1;
	ll x = powmod(a * a % MOD, e >> 1);
	return e & 1 ? x * a % MOD : x;
}

struct Matrix {
	typedef Matrix M;
	vvi d;int N;
	Matrix(const int &n,bool flag=0)
	{
		N=n;
		d.resize(N);
		rep(i,N){d[i].resize(N);fill(all(d[i]),-1);if(flag)d[i][i]=0;}

	}

	M operator*(const M& m) const {
		M a=M(N);
		rep(k,N)rep(i,N) rep(j,N)

			if(~d[i][k] and ~m.d[k][j]) a.d[i][j] =max(a.d[i][j],d[i][k]+m.d[k][j]);
		return a;
	}
	vector<ll> operator*(const vector<ll>& vec) const { //this is for M*vec=vec
		vector<ll> ret(N);
		rep(i,N) rep(j,N) ret[i] += d[i][j] * vec[j];
		return ret;
	}
	M operator^(ll p) const {
		assert(p >= 0);
		M a=M(N,1), b(*this);

		while (p) {
			if (p&1) a = a*b;
			b = b*b;
			p >>= 1;
		}
		return a;
	}
};

const int maxn=201;
string s[maxn];
int tr[maxn][27], au[maxn][27], nx = 1, e[maxn], a[maxn], f[maxn], matches[maxn],n;

inline void add(int i){
	int v = 0;
	for(auto ch: s[i]){
		int c = ch - 'a';
		if(!tr[v][c])
			tr[v][c] = nx ++;
		v = tr[v][c];
	}
	e[v] += a[i];
}
inline void ahoc(){
	queue<int> q;
	q.push(0);
	while(!q.empty()){
		int v = q.front();
		q.pop();
		if(f[v] != v)	{e[v] += e[f[v]];}
		repn(i,0,26){
			int u = tr[v][i];
			if(u){
				au[v][i] = u;
				if(v)
					f[u] = au[f[v]][i];
				q.push(u);
			}
			else
				au[v][i] = au[f[v]][i];
		}
	}
}

int main()
{
	#if !ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n,l;cin>>n>>l;
	rep(i,n){
		cin>>a[i];
	}
	rep(i,n){cin>>s[i];add(i);}ahoc();

	Matrix dp(nx);
	for(auto ch='a';ch<='z';ch++)rep(i,nx){
		dp.d[au[i][ch-'a']][i]=e[au[i][ch-'a']];}
	//rep(i,nx){rep(j,nx)cout<<dp.d[i][j]<<" ";cout<<"\n";}cout<<"\n";
	dp=dp^l;
	//rep(i,nx){rep(j,nx)cout<<dp.d[i][j]<<" ";cout<<"\n";}
	ll maxi=0;
	for(int final=0;final<nx;final++)
		maxi=max(dp.d[final][0],maxi);
	cout<<maxi;
}


#include <bits/stdc++.h>
#define up(i, a, b) for (int i = a, _b = b; i <= _b; i++)
#define down(i, a, b) for (int i = a, _b = b; i >= _b; i--)
#define long long long
#define endl '\n'
#define X first
#define Y second
#define II pair<int, int>
#define debug(X) cerr << #X << " = " << X << endl
#define debug2(X, Y) cerr << #X << " = " << X << " , " << #Y << " = " << Y << endl
#define show(X, a, b) { cerr << #X << " = "; up(_, a, b) cerr << X[_] << " "; cerr << endl; }
#define gc getchar
#define pc putchar
using namespace std;
inline void read(int &x) {
        register int c = gc();
        x = 0;
        int neg = 0;
        for (; ((c<48 || c>57) && c != '-'); c = gc());
        if(c=='-') {neg=1; c=gc();}
        for(; c>47 && c<58; c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
        if(neg) x=-x;
}
inline void writeln(int x) {

        char buffor[21];
        register int i=0;
        int neg=0; if (x<0) {neg=1; x= -x;}
        do {
                buffor[i++]=(x%10)+'0';
                x/=10;
        } while(x);
        i--;
        if (neg) pc('-');
        while(i>=0) pc(buffor[i--]);
        pc('\n');
}

int n, happiness[210];
long len;
const int MAX_SIZE_TRIE = 210;
struct aho {
        int Next[26]; int sum_happiness;
        int p, pch;
        int link, Go[26];
};
int sz_trie;
aho trie[MAX_SIZE_TRIE];
void initTrie() {
        up(i, 0, 25) trie[0].Next[i] = trie[0].Go[i] = - 1;
        trie[0].sum_happiness = trie[0].p = 0; trie[0].link = - 1;
        sz_trie = 1;
}
void add(string &s, int id) {
        int cur = 0;
        up(i, 0, (int)s.size() - 1) {
            int c = (int)(s[i] - 'a');
            if (trie[cur].Next[c] == - 1) {
                up(i, 0, 25) trie[sz_trie].Next[i] = trie[sz_trie].Go[i] = - 1;
                trie[sz_trie].sum_happiness = 0;
                trie[sz_trie].p = cur; trie[sz_trie].pch = c; trie[sz_trie].link = - 1;
                trie[cur].Next[c] = sz_trie++;
            }
            cur = trie[cur].Next[c];
        }
        trie[cur].sum_happiness += happiness[id];
}
int go(int u, int c);
int get_link(int u) {
        if (trie[u].link == - 1) {
            if (u == 0 || trie[u].p == 0) trie[u].link = 0;
            else trie[u].link = go(get_link(trie[u].p), trie[u].pch);
        }
        return trie[u].link;
}
int go(int u, int c) {
        if (trie[u].Go[c] == - 1) {
            if (trie[u].Next[c] != - 1) trie[u].Go[c] = trie[u].Next[c];
            else trie[u].Go[c] = u == 0 ? 0 : go(get_link(u), c);
        }
        return trie[u].Go[c];
}
const long oo = 1e18;
struct Matrix {
        long data[210][210];
};
Matrix f, t;
Matrix operator * (const Matrix &a, const Matrix &b) {
        Matrix c;
        up(i, 0, sz_trie - 1)
          up(j, 0, sz_trie - 1) {
            c.data[i][j] = - oo;
            up(k, 0, sz_trie - 1)
              c.data[i][j] = max(c.data[i][j], a.data[i][k] + b.data[k][j]);
            }
        return c;
}

void input() {
        initTrie();
        cin >> n >> len;
        up(i, 1, n) cin >> happiness[i];
        up(i, 1, n) {
            string s; cin >> s;
            add(s, i);
        }
}
void init_Matrix() {
        up(i, 1, sz_trie - 1) f.data[0][i] = - oo; // f[0][0] = 0, f[0][i] (i > 0) not exist
        up(u, 0, sz_trie - 1)
          up(v, 0, sz_trie - 1)
            t.data[u][v] = - oo;
        up(u, 0, sz_trie - 1)
          up(c, 0, 25) { // from node u go edge c
              int v = go(u, c); int oldv = v;
              int tot_happiness = 0;
              while (v) {
                  tot_happiness += trie[v].sum_happiness;
                  v = get_link(v);
              }
              if (t.data[u][oldv] < 0) t.data[u][oldv] = 0;
              t.data[u][oldv] += tot_happiness;
          }

}
Matrix power(Matrix a, long k) {
        Matrix res = a; k--;
        while (k) {
            if ((k & 1) == 1) res = res * a;
            a = a * a;
            k >>= 1;
        }
        return res;
}
void cal_dp() {
        // up(i, 0, sz_trie - 1) show(t.data[i], 0, sz_trie - 1);

        t = power(t, len);
        // show(f.data[0], 0, sz_trie - 1);
        // up(i, 1, len) {
            // f = f * t;
            // show(f.data[0], 0, sz_trie - 1);
        // }
        f = f * t;
        long res = 0;
        up(i, 0, sz_trie - 1) res = max(res, f.data[0][i]);
        cout << res << endl;
}
Matrix ff[201], tt;
void cal_dp_trau() {
        up(i, 1, sz_trie - 1) ff[0].data[0][i] = - oo;
        // up(i, 0, sz_trie - 1) cerr << trie[i].sum_happiness << " ";
        // debug(get_link(13));
        // return;
        up(i, 0, len - 1) {
          up(u, 0, sz_trie - 1) ff[i + 1].data[0][u] = - oo;
          up(u, 0, sz_trie - 1)
            up(c, 0, 25) {
              int v = go(u, c); int oldv = v;
              int tot_happiness = 0;
              while (v) {
                  tot_happiness += trie[v].sum_happiness;
                  v = get_link(v);
              }
              ff[i + 1].data[0][oldv] = max(ff[i + 1].data[0][oldv], ff[i].data[0][u] + tot_happiness);
              tt.data[u][oldv] = tot_happiness;
          }
            // up(u, 0, sz_trie - 1) cerr << ff[i].data[0][u] << " "; cerr << endl;
        }
        // up(u, 0, sz_trie - 1) cerr << ff[len].data[0][u] << " ";
          // up(i, 0, sz_trie - 1) show(tt.data[i], 0, sz_trie - 1);
        long res = 0;
        up(i, 0, sz_trie - 1) res = max(res, ff[len].data[0][i]);
        cout << res;
}
int main() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);

  #ifdef I_Love_Pork
  #define TASK "tmp"
        freopen(TASK ".inp","r",stdin);
        freopen(TASK ".out","w",stdout);
  #endif

  #ifdef I_Love_Pork
        clock_t BeginExecuteTime = clock();
  #endif

        input();
        init_Matrix();
        cal_dp();
        // cal_dp_trau();

  #ifdef I_Love_Pork
        clock_t EndExecuteTime = clock();
        cerr << fixed << setprecision(2) << "Time executed: " << double(EndExecuteTime - BeginExecuteTime) / CLOCKS_PER_SEC << "s";
  #endif

        return 0;
}


#include <bits/stdc++.h>
#include <unistd.h>
#define ll long long
#define ull unsigned long long
#define inf 1000000007
#define inf16 0x3f3f3f3f
#define INF 1000000000000000007LL
#define VI vector<int>
#define VPII vector<pair<int, int> >
#define VLL vector<ll>
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define endl '\n'
#define ALL(c) (c).begin(), (c).end()
#define SIZE(x) (int)(x).size()
using namespace std;

const int N = 207;

int n, curr = 1;

ll l;

string s[N];
int a[N];
int trie[N][26];
int suf[N];
int sum[N];

queue<int> Q;
VI rev;

struct mat
{
	ll m[N][N];

	mat()
	{
		for(int i = 0; i < N; ++i)
		{
			for(int j = 0; j < N; ++j)
			{
				m[i][j] = -INF;
			}
		}
	}
};

mat operator*(const mat &a, const mat &b)
{
	mat res;

	for(int i = 1; i <= curr; ++i)
	{
		for(int j = 1; j <= curr; ++j)
		{
			for(int k = 1; k <= curr; ++k)
			{
				res.m[i][j] = max(res.m[i][j], a.m[i][k]+b.m[k][j]);
			}
		}
	}

	return res;
}

mat pot[67];

int32_t main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(NULL);

	cin >> n >> l;

	for(int i = 1; i <= n; ++i)
	{
		cin >> a[i];
	}

	for(int i = 1; i <= n; ++i)
	{
		cin >> s[i];

		int st = 1;

		for(int j = 0; j < s[i].size(); ++j)
		{
			if(!trie[st][s[i][j]-'a'])
				trie[st][s[i][j]-'a'] = ++curr;

			st = trie[st][s[i][j]-'a'];
		}

		sum[st] += a[i];
	}

	suf[1] = 1;
	Q.push(1);

	while(!Q.empty())
	{
		int v = Q.front();
		Q.pop();
		rev.pb(v);

		for(int i = 0; i < 26; ++i)
		{
			if(trie[v][i])
			{
				if(v==1)
					suf[trie[v][i]] = 1;
				else
				{
					int u = suf[v];

					while(u!=1 && !trie[u][i])
						u = suf[u];

					if(trie[u][i])
						u = trie[u][i];

					suf[trie[v][i]] = u;
				}

				sum[trie[v][i]] += sum[suf[trie[v][i]]];
				Q.push(trie[v][i]);
			}
		}
	}

	for(int i = 1; i <= curr; ++i)
	{
		for(int j = 0; j < 26; ++j)
		{
			int u = i;

			while(u!=1 && !trie[u][j])
				u = suf[u];

			if(trie[u][j])
				u = trie[u][j];

			pot[0].m[i][u] = sum[u];
		}
	}

	for(int i = 1; i <= 47; ++i)
	{
		pot[i] = pot[i-1]*pot[i-1];
	}

	mat res;

	for(int i = 1; i <= curr; ++i)
	{
		res.m[i][i] = 0;
	}

	for(int i = 0; i <= 47; ++i)
	{
		if(l&(1ll<<i))
			res = res*pot[i];
	}

	ll ans = 0;

	for(int i = 1; i <= curr; ++i)
	{
		ans = max(ans, res.m[1][i]);
	}

	cout << ans;
}


#include<bits/stdc++.h>
#define idx(c) (c-'a')
using namespace std;
const int maxn=205;
int n,len,anss[maxn];
char s[233],str[233];
typedef long long LL;

struct mat{
	LL a[maxn][maxn];
	LL* operator[](int x){return a[x];}
	mat(){}
	void clear(){
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				a[i][j]=-1e18;
	}
	void unit(){
		for(int i=0;i<maxn;i++)
			a[i][i]=0;
	}
};
mat operator*(mat A,mat B){
	static mat C;C.clear();
	for(int k=0;k<maxn;k++)
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				C[i][j]=max(C[i][j],A[i][k]+B[k][j]);
	return C;
}
mat operator^(mat x,LL k){
	static mat ans;ans.clear();ans.unit();
	for(;k;k>>=1){
		if(k&1)ans=ans*x;
		x=x*x;
	}return ans;
}

struct node{
	LL val;
	node *go[26],*fail,*last;
	node(node *C=0){
		for(int i=0;i<26;i++)go[i]=C;
		fail=last=C;val=0;
	}
}*root,pool[maxn*10],*cur=pool,*null;

node *newnode(node *C){
	*cur=node(C);
	return cur++;
}
void insert(const char *s,int x){
	node *u=root;int len=strlen(s);
	for(int i=0;i<len;i++){
		int v=idx(s[i]);
		if(u->go[v]==null)u->go[v]=newnode(null);
		u=u->go[v];
	}u->val+=x;
}
void get_fail(){
	queue<node*>q;
	for(int i=0;i<26;i++)if(root->go[i]!=null)
	q.push(root->go[i]),root->go[i]->fail=root->go[i]->last=root;

vector<node*>sta;
	while(!q.empty()){
		node *u=q.front(),*v;q.pop();
		sta.push_back(u);
		for(int i=0;i<26;i++)if((v=u->go[i])!=null){
			q.push(v);node *j=u->fail;
			while(j!=null&&j->go[i]==null)j=j->fail;
			v->fail=j->go[i];
			v->last=v->fail->val?v->fail:v->fail->last;
			v->val+=v->last->val;
		}else u->go[i]=u->fail->go[i];
	}
/*	reverse(sta.begin(),sta.end());
	for(auto u:sta){
		node *v=u->last;
		while(v!=root){
			u->val+=v->val;
			v=v->last;
		}
	}*/
}

int main(){
	null=newnode(0);root=null;
	for(int i=0;i<26;i++)null->go[i]=null;
	null->fail=null->last=null;
	int n;
	LL l;
	cin>>n>>l;
	set<string>S;
	static int a[maxn];
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		string s;cin>>s;
			insert(s.c_str(),a[i]);
		S.insert(s);
	}

	get_fail();

	static mat A;
	A.clear();
	LL tot=cur-pool;
	for(int i=0;i<tot;i++){
		node *u=pool+i,*v;
		for(int j=0;j<26;j++)if((v=u->go[j])!=null){
	//		cerr<<(u-pool)<<"->"<<(v-pool)<<endl;
			A[u-pool][v-pool]=v->val;
		}
	}

	A=A^l;

	LL ans=0;
	for(int i=0;i<maxn;i++)
		ans=max(ans,A[0][i]);

	cout<<ans<<endl;

	return 0;
}


#include<bits/stdc++.h>
#define idx(c) (c-'a')
using namespace std;
const int maxn=205;
int n,len,anss[maxn];
char s[233],str[233];
typedef long long LL;

struct mat{
	LL a[maxn][maxn];
	LL* operator[](int x){return a[x];}
	mat(){}
	void clear(){
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				a[i][j]=-1e18;
	}
	void unit(){
		for(int i=0;i<maxn;i++)
			a[i][i]=0;
	}
};
mat operator*(mat A,mat B){
	static mat C;C.clear();
	for(int k=0;k<maxn;k++)
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				C[i][j]=max(C[i][j],A[i][k]+B[k][j]);
	return C;
}
mat operator^(mat x,LL k){
	static mat ans;ans.clear();ans.unit();
	for(;k;k>>=1){
		if(k&1)ans=ans*x;
		x=x*x;
	}return ans;
}

struct node{
	LL val;
	node *go[26],*fail,*last;
	node(node *C=0){
		for(int i=0;i<26;i++)go[i]=C;
		fail=last=C;val=0;
	}
}*root,pool[maxn*10],*cur=pool,*null;

node *newnode(node *C){
	*cur=node(C);
	return cur++;
}
void insert(const char *s,int x){
	node *u=root;int len=strlen(s);
	for(int i=0;i<len;i++){
		int v=idx(s[i]);
		if(u->go[v]==null)u->go[v]=newnode(null);
		u=u->go[v];
	}u->val+=x;
}
void get_fail(){
	queue<node*>q;
	for(int i=0;i<26;i++)if(root->go[i]!=null)
	q.push(root->go[i]),root->go[i]->fail=root->go[i]->last=root;

	while(!q.empty()){
		node *u=q.front(),*v;q.pop();
		for(int i=0;i<26;i++)if((v=u->go[i])!=null){
			q.push(v);node *j=u->fail;
			while(j!=null&&j->go[i]==null)j=j->fail;
			v->fail=j->go[i];
			v->last=v->fail->val?v->fail:v->fail->last;
		}else u->go[i]=u->fail->go[i];
	}
	for(node *u=cur-1;u!=root;u--){
		node *v=u->last;
		while(v!=root){
			u->val+=v->val;
			v=v->last;
		}
	}
}

int main(){
	null=newnode(0);root=null;
	for(int i=0;i<26;i++)null->go[i]=null;
	null->fail=null->last=null;
	int n;
	LL l;
	cin>>n>>l;
	set<string>S;
	static int a[maxn];
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		string s;cin>>s;
			insert(s.c_str(),a[i]);
		S.insert(s);
	}

	get_fail();

	static mat A;
	A.clear();
	LL tot=cur-pool;
	for(int i=0;i<tot;i++){
		node *u=pool+i,*v;
		for(int j=0;j<26;j++)if((v=u->go[j])!=null){
	//		cerr<<(u-pool)<<"->"<<(v-pool)<<endl;
			A[u-pool][v-pool]=v->val;
		}
	}

	A=A^l;

	LL ans=0;
	for(int i=0;i<maxn;i++)
		ans=max(ans,A[0][i]);

	cout<<ans<<endl;

	return 0;
}


#include<bits/stdc++.h>
#define idx(c) (c-'a')
using namespace std;
const int maxn=205;
int n,len,anss[maxn];
char s[233],str[233];
typedef long long LL;

struct mat{
	LL a[maxn][maxn];
	LL* operator[](int x){return a[x];}
	mat(){}
	void clear(){
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				a[i][j]=-1e18;
	}
	void unit(){
		for(int i=0;i<maxn;i++)
			a[i][i]=0;
	}
};
mat operator*(mat A,mat B){
	static mat C;C.clear();
	for(int k=0;k<maxn;k++)
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				C[i][j]=max(C[i][j],A[i][k]+B[k][j]);
	return C;
}
mat operator^(mat x,LL k){
	static mat ans;ans.clear();ans.unit();
	for(;k;k>>=1){
		if(k&1)ans=ans*x;
		x=x*x;
	}return ans;
}

struct node{
	int val;
	node *go[26],*fail,*last;
	node(node *C=0){
		for(int i=0;i<26;i++)go[i]=C;
		fail=last=C;val=0;
	}
}*root,pool[maxn*10],*cur=pool,*null;

node *newnode(node *C){
	*cur=node(C);
	return cur++;
}
void insert(const char *s,int x){
	node *u=root;int len=strlen(s);
	for(int i=0;i<len;i++){
		int v=idx(s[i]);
		if(u->go[v]==null)u->go[v]=newnode(null);
		u=u->go[v];
	}u->val+=x;
}
void get_fail(){
	queue<node*>q;
	for(int i=0;i<26;i++)if(root->go[i]!=null)
	q.push(root->go[i]),root->go[i]->fail=root->go[i]->last=root;

	while(!q.empty()){
		node *u=q.front(),*v;q.pop();
		for(int i=0;i<26;i++)if((v=u->go[i])!=null){
			q.push(v);node *j=u->fail;
			while(j!=null&&j->go[i]==null)j=j->fail;
			v->fail=j->go[i];
			v->last=v->fail->val?v->fail:v->fail->last;
		}else u->go[i]=u->fail->go[i];
	}
	for(node *u=cur-1;u!=root;u--){
		node *v=u->last;
		while(v!=root){
			u->val+=v->val;
			v=v->last;
		}
	}
}

int main(){
	null=newnode(0);root=null;
	for(int i=0;i<26;i++)null->go[i]=null;
	null->fail=null->last=null;
	int n;
	LL l;
	cin>>n>>l;
	set<string>S;
	static int a[maxn];
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		string s;cin>>s;
			insert(s.c_str(),a[i]);
		S.insert(s);
	}

	get_fail();

	static mat A;
	A.clear();
	LL tot=cur-pool;
	for(int i=0;i<tot;i++){
		node *u=pool+i,*v;
		for(int j=0;j<26;j++)if((v=u->go[j])!=null){
	//		cerr<<(u-pool)<<"->"<<(v-pool)<<endl;
			A[u-pool][v-pool]=v->val;
		}
	}

	A=A^l;

	LL ans=0;
	for(int i=0;i<maxn;i++)
		ans=max(ans,A[0][i]);

	cout<<ans<<endl;

	return 0;
}


#include<bits/stdc++.h>
#define idx(c) (c-'a')
using namespace std;
const int maxn=205;
int n,len,anss[maxn];
char s[233],str[233];
typedef long long LL;

struct mat{
	LL a[maxn][maxn];
	LL* operator[](int x){return a[x];}
	mat(){}
	void clear(){
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				a[i][j]=-1e18;
	}
	void unit(){
		for(int i=0;i<maxn;i++)
			a[i][i]=0;
	}
};
mat operator*(mat A,mat B){
	static mat C;C.clear();
	for(int k=0;k<maxn;k++)
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				C[i][j]=max(C[i][j],A[i][k]+B[k][j]);
	return C;
}
mat operator^(mat x,LL k){
	static mat ans;ans.clear();ans.unit();
	for(;k;k>>=1){
		if(k&1)ans=ans*x;
		x=x*x;
	}return ans;
}

struct node{
	int val;
	node *go[26],*fail,*last;
	node(node *C=0){
		for(int i=0;i<26;i++)go[i]=C;
		fail=last=C;val=0;
	}
}*root,pool[maxn*10],*cur=pool,*null;

node *newnode(node *C){
	*cur=node(C);
	return cur++;
}
void insert(const char *s,int x){
	node *u=root;int len=strlen(s);
	for(int i=0;i<len;i++){
		int v=idx(s[i]);
		if(u->go[v]==null)u->go[v]=newnode(null);
		u=u->go[v];
	}u->val+=x;
}
void get_fail(){
	queue<node*>q;
	for(int i=0;i<26;i++)if(root->go[i]!=null)
	q.push(root->go[i]),root->go[i]->fail=root->go[i]->last=root;

	vector<node*>sta;
	while(!q.empty()){
		node *u=q.front(),*v;q.pop();
		sta.push_back(u);
		for(int i=0;i<26;i++)if((v=u->go[i])!=null){
			q.push(v);node *j=u->fail;
			while(j!=null&&j->go[i]==null)j=j->fail;
			v->fail=j->go[i];
			v->last=v->fail->val?v->fail:v->fail->last;
		}else u->go[i]=u->fail->go[i];
	}
	reverse(sta.begin(),sta.end());
	for(auto u:sta){
		node *v=u->last;
		while(v!=root){
			u->val+=v->val;
			v=v->last;
		}
	}
}

int main(){
	null=newnode(0);root=null;
	for(int i=0;i<26;i++)null->go[i]=null;
	null->fail=null->last=null;
	int n;
	LL l;
	cin>>n>>l;
	set<string>S;
	static int a[maxn];
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		string s;cin>>s;
		if(!S.count(s)){
			insert(s.c_str(),a[i]);
		}
		S.insert(s);
	}

	get_fail();

	static mat A;
	A.clear();
	LL tot=cur-pool;
	for(int i=0;i<tot;i++){
		node *u=pool+i,*v;
		for(int j=0;j<26;j++)if((v=u->go[j])!=null){
	//		cerr<<(u-pool)<<"->"<<(v-pool)<<endl;
			A[u-pool][v-pool]=v->val;
		}
	}

	A=A^l;

	LL ans=0;
	for(int i=0;i<maxn;i++)
		ans=max(ans,A[0][i]);

	cout<<ans<<endl;

	return 0;
}


#include<bits/stdc++.h>
#define mp make_pair
#define ni(x) scanf("%d", &(x))
#define nii(x,y) scanf("%d%d",&(x),&(y))
#define mul(x,y) ((ll)(x)*(y)%mod)
#define mtp make_tuple
#define F(i,n) for(int i = 0; i < (n); i++)
#define FF(i,n) for(int i = 1; i <= (n); i++)

using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const int mod = 1000000007;
const int inf = 2012345678;
const ll infl = 9012345678901234567;
const double pi = 3.1415926535897932384626433832795;
//----------------------------------------------------------------------------//

const int CHAR = 26;
const int N = 220;

#define CONVERT(c) (c)-'a'
class AhoCora {
public:
	struct Node {
		int ch[CHAR];
		int link;
		vector<int> dic;
	}nd[N];
	int Q[N]; int qs, qe;
	int size;
	int createNode() {
		int ret = size++;
		for (int i = 0; i<CHAR; i++) {
			nd[ret].ch[i] = -1;
		}
		return ret;
	}
	void init() {
		size = 0;
		createNode();
	}
	template<typename A>
	void add(A str, int sz, int id) {
		int cur = 0;
		for (int i = 0; i<sz; i++) {
			int c = CONVERT(str[i]);
			if (nd[cur].ch[c] == -1) {
				int nnd = createNode();
				nd[cur].ch[c] = nnd;
			}
			cur = nd[cur].ch[c];
		}
		nd[cur].dic.push_back(id);
	}
	inline int next(int u, int c) {
		while (u&&nd[u].ch[c]<0)
			u = nd[u].link;
		if (nd[u].ch[c]<0)return 0;
		else return nd[u].ch[c];
	}
	void computelink() {
		qs = qe = 0;
		nd[0].link = 0;
		for (int x, i = 0; i<CHAR; i++) {
			if ((x = nd[0].ch[i]) >= 0) {
				Q[qe++] = x;
				nd[x].link = 0;
			}
		}
		while (qs<qe) {
			int u = Q[qs++];
			for (int v, i = 0; i<CHAR; i++) {
				if ((v = nd[u].ch[i]) >= 0) {
					Q[qe++] = v;
					int m = nd[u].link;
					int L = nd[v].link = next(m, i);
					nd[v].dic.insert(nd[v].dic.end(), nd[L].dic.begin(), nd[L].dic.end());
				}
			}
		}
	}
}acc;

char buf[200][220];
int a[200];

const int M =5000;

int ndn;
int go[N][26];
int sa[N];
int dp[M+1][N];
int dpm[M+1];

int main() {
	//freopen("inp.txt", "r", stdin);
	int n; ll l;
	ni(n); scanf("%I64d", &l);
	F(i, n) {
		ni(a[i]);
	}
	acc.init();
	F(i, n) {
		scanf("%s", buf[i]);
		acc.add(buf[i], strlen(buf[i]), i);
	}
	acc.computelink();
	int ndn = acc.size;
	F(i, ndn) {
		F(j, CHAR) {
			go[i][j] = acc.next(i, j);
		}
	}
	F(i, ndn) {
		for (auto &x : acc.nd[i].dic) sa[i] += a[x];
	}
	F(t, M+1)F(i, ndn)dp[t][i] = -1;
	dp[0][0] = 0;
	F(t, M) {
		F(i, ndn) {
			if (dp[t][i] == -1)continue;
			F(j, CHAR) {
				int ni = go[i][j];
				dp[t + 1][ni] = max(dp[t + 1][ni], dp[t][i] + sa[ni]);
			}
		}
	}
	F(i, M+1)dpm[i] = *max_element(dp[i], dp[i] + ndn);
	if (l <= M) {
		printf("%d\n", dpm[l]);
		return 0;
	}
	int ii = -1;
	for (int i = (M+1)/2; i < M; i++) {
		bool bad = false;
		int X = dpm[M] - dpm[i];
		for (int j = 0; j < M - i; j++) {
			if (dpm[i + j] - dpm[2 * i - M + j] != X) {
				bad = true; break;
			}
		}
		if (!bad) {
			ii = i; break;
		}
	}
	if (ii == -1) {
		assert(0);
	}
	int T = M - ii;
	int rem = (l-ii)%T;
	ll qq = (l - ii) / T;
	int X = dpm[M] - dpm[ii];
	printf("%I64d\n", X*qq + dpm[ii + rem]);
}


#include <bits/stdc++.h>
using namespace std;
typedef long long       ll;
typedef pair<int,int>   pii;
typedef vector<int>     vi;
typedef long double     ld;
#define MOD         1000000007
#define pb          push_back
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define endl        '\n'
#define PI          3.14159265359d
#define sz(x)       (int)x.size()
vector<string> pat;
int A[205];
struct AC {
    int N, P;
    vector<map<char, int>> next;
    vector<int> link, out_link, score;
    vector<vector<int>> out;
    AC(): N(0), P(0) { node(); }
    int node() {
        next.emplace_back();
        link.emplace_back(0);
        out_link.emplace_back(0);
        out.emplace_back(0);
        score.emplace_back(0);
        return N++;
    }
    void add_pattern(const string& T) {
        int u = 0;
        for (auto c : T) {
          if (!next[u][c]) next[u][c] = node();
          u = next[u][c];
        }
        out[u].push_back(P++);
    }
    void compute() {
        queue<int> q;
        for (q.push(0); !q.empty(); ) {
            int u = q.front(); q.pop();
            for (auto e : next[u]) {
                int v = e.S;
                link[v] = u ? advance(link[u], e.F) : 0;
                out_link[v] = out[link[v]].empty() ? out_link[link[v]] : link[v];
                q.push(e.S);
            }
        }
    }
    int advance(int u, char c) {
        while (u && next[u].find(c) == next[u].end())
            u = link[u];
        if (next[u].find(c) != next[u].end())
            u = next[u][c];
        return u;
    }
    void calc_scores() {
        for (int u=0;u<N;u++) {
            for (int v = u; v; v = out_link[v])
                for (auto p : out[v])
                    score[u]+=A[p];
        }
    }
}ac;
ll a[205][205];
void mult(ll a[205][205],ll b[205][205])
{
    ll c[205][205];
    int i,j,k;
    for(i=0;i<ac.N;i++)
        for(j=0;j<ac.N;j++)
            for(k=0,c[i][j]=-1;k<ac.N;k++)
                if(a[i][k]>=0&&b[k][j]>=0)
                    c[i][j]=max(c[i][j],a[i][k]+b[k][j]);
    for(i=0;i<ac.N;i++)
        for(j=0;j<ac.N;j++)
            a[i][j]=c[i][j];
}
void power(ll a[205][205], ll b)
{
    ll x[205][205],y[205][205];
    int i,j;
    for(i=0;i<ac.N;i++)
        for(j=0;j<ac.N;j++)
            if(i==j)
                x[i][j]=0;
            else
                x[i][j]=-1;
    for(i=0;i<ac.N;i++)
        for(j=0;j<ac.N;j++)
            y[i][j]=a[i][j];
    while(b)
    {
        if(b%2)
            mult(x,y);
        mult(y,y);
        b/=2;
    }
    for(i=0;i<ac.N;i++)
        for(j=0;j<ac.N;j++)
           a[i][j]=x[i][j];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,i,j;
    ll l,res=0;
    string s;
    cin>>n>>l;
    for(i=0;i<n;i++)
        cin>>A[i];
    while(n--)
    {
        cin>>s;
        pat.pb(s);
        ac.add_pattern(s);
    }
    ac.compute();
    ac.calc_scores();
    for(i=0;i<ac.N;i++)
    {
        for(j=0;j<ac.N;j++)
            a[i][j]=-1;
        for(char c='a';c<='z';c++)
        {
            j=ac.advance(i,c);
            a[i][j]=ac.score[j];
        }
    }
    power(a,l);
    for(i=0;i<ac.N;i++)
        if(a[0][i]>=0)
            res=max(res,a[0][i]);
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
#define ld long double
#define endl "\n"
#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pb(x) push_back(x)
#define mp(a,b) make_pair(a,b)
#define ms(v,x) memset(v,x,sizeof(v))
#define all(v) v.begin(),v.end()
#define ff first
#define ss second
#define rep(i, a, b) for(int i = a; i < (b); ++i)
//#define per(i, a, b) for(int i = b-1; i>=a ; i--)
#define trav(a, x) for(auto& a : x)
#define allin(a , x) for(auto a : x)
#define td(v) v.begin(),v.end()
#define sz(v) (int)v.size()
//#define M   1000000007 // 1e9 + 7
#define int long long
using namespace std;
typedef vector<int> vi;
typedef long long ll;
typedef pair<int,int> pii;
inline ll mod(ll n, ll m ){ ll ret = n%m; if(ret < 0) ret += m; return ret; }
ll gcd(ll a, ll b){return (b == 0LL ? a : gcd(b, a%b));}
ll exp(ll a,ll b,ll m){
    if(b==0LL) return 1LL;
    if(b==1LL) return mod(a,m);
    ll k = mod(exp(a,b/2,m),m);
    if(b&1LL){
        return mod(a*mod(k*k,m),m);
    }
    else return mod(k*k,m);
}

typedef pair<string,int> psi;

struct AhoCorasick {
  enum {alpha = 26, first = 'a'};
  struct Node {
    // (nmatches is optional)
    int back, next[alpha], start = -1, end = -1;
    ll nmatches = 0;
    Node(int v) { memset(next, v, sizeof(next));}
  };
  int maxi=0;
  vector<Node> N;
  vector<int> backp;
  void insert(string& s, int j,ll val) {
    assert(!s.empty());
    int n = 0;
    trav(c, s) {
      maxi = (maxi<n?n:maxi);
      int& m = N[n].next[c - first];
      if (m == -1) { n = m = sz(N); N.emplace_back(-1); }
      else n = m;
      maxi = (maxi<n?n:maxi);
    }
    if (N[n].end == -1) N[n].start = j;
    backp.push_back(N[n].end);
    N[n].end = j;
    maxi = (maxi<n?n:maxi);
    N[n].nmatches+=val;
  }
  AhoCorasick(vector<psi>& pat) {
    N.emplace_back(-1);
    rep(i,0,sz(pat)) insert(pat[i].ff, i,pat[i].ss);
    N[0].back = sz(N);
    N.emplace_back(0);

    queue<int> q;
    for (q.push(0); !q.empty(); q.pop()) {
      int n = q.front(), prev = N[n].back;
      rep(i,0,alpha) {
        int &ed = N[n].next[i], y = N[prev].next[i];
        if (ed == -1) ed = y;
        else {
          N[ed].back = y;
          (N[ed].end == -1 ? N[ed].end : backp[N[ed].start])
            = N[y].end;
          N[ed].nmatches += N[y].nmatches;
          q.push(ed);
        }
      }
    }
  }
  ll cost(string word) {
    int n = 0;
    vi res;
     ll count = 0;
    trav(c, word) {
      n = N[n].next[c - first];
      res.push_back(N[n].end);
       count += N[n].nmatches;
    }
    return count;
  }

};

const ll inf = (ll)1e18;
struct matrix{
  int n,m;
  vector<vector<ll>> mat;
  matrix(){}
  matrix(int l,int c){
    n = l;
    m = c;
    mat.resize(n, vector<ll>(m,-inf));
  }
  void nsize(int l,int c){
    n = l;
    m = c;
    mat.resize(n, vector<ll>(m,-inf));
  }
};
matrix operator*(const matrix& A,const matrix& B){
    matrix ret(A.n,B.m);
    for(int i=0;i<A.n;i++)
        for(int j=0;j<B.m;j++)
            for(int k=0;k<A.m;k++){
                ret.mat[i][j] = max(A.mat[i][k] + B.mat[k][j],ret.mat[i][j]);
            }
    return ret;
}
matrix def; // def = matriz Identidade
matrix expo(matrix a,int b){
    if(b==0) return def;
    if(b==1){
        return a;
    }
    matrix now = expo(a,b/2);
    if(b&1){
        return a*now*now;
    }
    else return now*now;
}

const int N = 210;

int a[N];

int32_t main(){
 fastio;
 int n;
 ll l;
 cin>>n>>l;
 for(int i=1;i<=n;i++){
  cin >> a[i];
 }
 vector<psi> vec;
 for(int i=1;i<=n;i++){
  string s;
  cin>> s;
  vec.pb(psi(s,a[i]));
 }
 AhoCorasick aho(vec);

int maxi = aho.maxi;
def = matrix(maxi+1,maxi+1);
matrix mat(maxi+1,maxi+1);
 for(int i=0;i<=maxi;i++){
  for(int j=0;j<=maxi;j++){
    mat.mat[i][j]=-inf;
    def.mat[i][j] = (i==j?1:0);
  }
 }
 for(int i=0;i<=maxi;i++){
    for(int j=0;j<26;j++){
      int id = aho.N[i].next[j];
      if(id!=-1)mat.mat[i][id] = aho.N[id].nmatches;
    }
 }

 mat = expo(mat,l);

 ll res=0;
 for(int i=0;i<=maxi;i++){
  res = max(res,mat.mat[0][i]);
 }
 cout << res << endl;

  // Math -> gcd it all
  // Did u check N=1? Did you switch N,M?
}


#include <bits/stdc++.h>
#define ld long double
#define endl "\n"
#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define pb(x) push_back(x)
#define mp(a,b) make_pair(a,b)
#define ms(v,x) memset(v,x,sizeof(v))
#define all(v) v.begin(),v.end()
#define ff first
#define ss second
#define rep(i, a, b) for(int i = a; i < (b); ++i)
//#define per(i, a, b) for(int i = b-1; i>=a ; i--)
#define trav(a, x) for(auto& a : x)
#define allin(a , x) for(auto a : x)
#define td(v) v.begin(),v.end()
#define sz(v) (int)v.size()
//#define M   1000000007 // 1e9 + 7
//#define int long long
using namespace std;
typedef vector<int> vi;
typedef long long ll;
typedef pair<int,int> pii;
inline ll mod(ll n, ll m ){ ll ret = n%m; if(ret < 0) ret += m; return ret; }
ll gcd(ll a, ll b){return (b == 0LL ? a : gcd(b, a%b));}
ll exp(ll a,ll b,ll m){
    if(b==0LL) return 1LL;
    if(b==1LL) return mod(a,m);
    ll k = mod(exp(a,b/2,m),m);
    if(b&1LL){
        return mod(a*mod(k*k,m),m);
    }
    else return mod(k*k,m);
}

typedef pair<string,int> psi;

struct AhoCorasick {
  enum {alpha = 26, first = 'a'};
  struct Node {
    // (nmatches is optional)
    int back, next[alpha], start = -1, end = -1;
    ll nmatches = 0;
    Node(int v) { memset(next, v, sizeof(next));}
  };
  int maxi=0;
  vector<Node> N;
  vector<int> backp;
  void insert(string& s, int j,ll val) {
    assert(!s.empty());
    int n = 0;
    trav(c, s) {
      maxi = (maxi<n?n:maxi);
      int& m = N[n].next[c - first];
      if (m == -1) { n = m = sz(N); N.emplace_back(-1); }
      else n = m;
      maxi = (maxi<n?n:maxi);
    }
    if (N[n].end == -1) N[n].start = j;
    backp.push_back(N[n].end);
    N[n].end = j;
    maxi = (maxi<n?n:maxi);
    N[n].nmatches+=val;
  }
  AhoCorasick(vector<psi>& pat) {
    N.emplace_back(-1);
    rep(i,0,sz(pat)) insert(pat[i].ff, i,pat[i].ss);
    N[0].back = sz(N);
    N.emplace_back(0);

    queue<int> q;
    for (q.push(0); !q.empty(); q.pop()) {
      int n = q.front(), prev = N[n].back;
      rep(i,0,alpha) {
        int &ed = N[n].next[i], y = N[prev].next[i];
        if (ed == -1) ed = y;
        else {
          N[ed].back = y;
          (N[ed].end == -1 ? N[ed].end : backp[N[ed].start])
            = N[y].end;
          N[ed].nmatches += N[y].nmatches;
          q.push(ed);
        }
      }
    }
  }
  ll cost(string word) {
    int n = 0;
    vi res;
     ll count = 0;
    trav(c, word) {
      n = N[n].next[c - first];
      res.push_back(N[n].end);
       count += N[n].nmatches;
    }
    return count;
  }

};

const ll inf = (ll)1e18;
struct matrix{
  int n,m;
  vector<vector<ll>> mat;
  matrix(){}
  matrix(int l,int c){
    n = l;
    m = c;
    mat.resize(n, vector<ll>(m,-inf));
  }
  void nsize(int l,int c){
    n = l;
    m = c;
    mat.resize(n, vector<ll>(m,-inf));
  }
};
matrix operator*(const matrix& A,const matrix& B){
    matrix ret(A.n,B.m);
    for(int i=0;i<A.n;i++)
        for(int j=0;j<B.m;j++)
            for(int k=0;k<A.m;k++){
                ret.mat[i][j] = max(A.mat[i][k] + B.mat[k][j],ret.mat[i][j]);
            }
    return ret;
}
matrix def; // def = matriz Identidade
matrix expo(matrix a,int b){
    if(b==0) return def;
    if(b==1){
        return a;
    }
    matrix now = expo(a,b/2);
    if(b&1){
        return a*now*now;
    }
    else return now*now;
}

const int N = 210;

int a[N];

int32_t main(){
 fastio;
 int n;
 ll l;
 cin>>n>>l;
 for(int i=1;i<=n;i++){
  cin >> a[i];
 }
 vector<psi> vec;
 for(int i=1;i<=n;i++){
  string s;
  cin>> s;
  vec.pb(psi(s,a[i]));
 }
 AhoCorasick aho(vec);
 matrix mat(N,N);
 def = matrix(N,N);
 for(int i=0;i<N;i++){
  for(int j=0;j<N;j++){
    def.mat[i][j]=(i==j);
  }
 }
int maxi = aho.maxi;
 for(int i=0;i<=maxi;i++){
  for(int j=0;j<=maxi;j++){
    mat.mat[i][j]=-inf;
  }
 }
 for(int i=0;i<=maxi;i++){
    for(int j=0;j<26;j++){
      int id = aho.N[i].next[j];
      if(id!=-1)mat.mat[i][id] = aho.N[id].nmatches;
    }
 }

 mat = expo(mat,l);

 ll res=0;
 for(int i=0;i<=maxi;i++){
  res = max(res,mat.mat[0][i]);
 }
 cout << res << endl;

  // Math -> gcd it all
  // Did u check N=1? Did you switch N,M?
}


#include <bits/stdc++.h>

using namespace std;

const int N = 205;
const long long INF = 1e18;

namespace AhoCorasick {

	int node = 1;
	int F[N];
	int trie[N][26];
	int fail[N], nxt[N][26];
	vector<int> G[N];

	void add(string &S, int A) {
		int cur = 0;
		for (int i = 0; i < S.size(); ++i) {
			int x = S[i] - 'a';
			if (!trie[cur][x]) trie[cur][x] = node++;
			cur = trie[cur][x];
		}
		F[cur] += A;
	}

	void bfs() {
		queue<int> qu;
		qu.push(0);
		while (qu.size()) {
			int u = qu.front(); qu.pop();
			for (int i = 0; i < 26; ++i) {
				int v = trie[u][i];
				nxt[u][i] = nxt[fail[u]][i];
				if (v) {
					fail[v] = nxt[u][i];
					nxt[u][i] = v, qu.push(v);
				}
			}
		}
	}

	void dfs(int u) {
		for (auto v : G[u]) F[v] += F[u], dfs(v);
	}

	void calc() {
		bfs();
		for (int i = 1; i < node; ++i) {
			G[fail[i]].push_back(i);
		}
		// for (int i = 1; i < node; ++i) cout << fail[i] << ' '; cout << '\n';
		dfs(0);
	}
}

namespace MatrixMult {
	struct Matrix {
		int n, m;
		long long a[N][N];

		void init(int n, int m) {
			this -> n = n, this -> m = m;
			for (int i = 0; i < n; ++i) {
				for (int j = 0; j < m; ++j) {
					a[i][j] = -INF;
				}
			}
		}
	};

	Matrix operator * (Matrix x, Matrix y) {
		Matrix z; z.init(x.n, y.m);
		for (int i = 0; i < x.n; ++i) {
			for (int j = 0; j < y.m; ++j) {
				for (int k = 0; k < x.m; ++k) {
					z.a[i][j] = max(z.a[i][j], x.a[i][k] + y.a[k][j]);
				}
			}
		}
		return z;
	}

	Matrix matPow(Matrix &x, long long y) {
		if (y == 1) return x;
		Matrix ret = matPow(x, y >> 1); ret = ret * ret;
		if (y & 1) ret = ret * x; return ret;
	}

	void solve(long long l) {
		int node = AhoCorasick::node;
		Matrix res; res.init(1, node);
		Matrix mul; mul.init(node, node);
		for (int i = 0; i < node; ++i) {
			for (int j = 0; j < 26; ++j) {
				int nxt = AhoCorasick::nxt[i][j];
				int F = AhoCorasick::F[nxt];
				mul.a[i][nxt] = F;
			}
		}
		res.a[0][0] = 0;
		res = res * matPow(mul, l);
		long long mx = -INF;
		for (int i = 0; i < node; ++i) mx = max(mx, res.a[0][i]);
		cout << mx;
	}
}

int n, a[N];
long long l;
string s[N];

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> l;
	for (int i = 0; i < n; ++i) cin >> a[i];
	for (int i = 0; i < n; ++i) {
		cin >> s[i];
		AhoCorasick::add(s[i], a[i]);
	}
	AhoCorasick::calc();
	MatrixMult::solve(l);
}


#include<string>
#include<array>
#include<vector>
#include<regex>
#include<algorithm>
#include<random>
#include<map>
#include<set>
#include<deque>
#include<iomanip>
#include<sstream>
#include<stack>
#include<iostream>
#include<limits>
#include<bitset>
#include<list>
#include<queue>
#include<memory.h>
#include<functional>
using namespace std;
const int sigma = 26;
using namespace std;

struct Trie_node
{
	Trie_node *next[sigma];
	Trie_node *fail;
	int sign,w;
	void clear()
	{
		w = 0;
		memset(next, 0, sizeof(next));
		fail = 0;
	}
};
Trie_node pool[1503500], *cur=pool;
void init()
{
	cur = pool;
}
Trie_node *newnode()
{
	cur->clear();
	cur->sign = cur - pool + 1;
	return cur++;
}
vector<int> last;
Trie_node * queue1[1010000];
struct Trie
{
	Trie_node *root;
	Trie()
	{
		root = newnode();
	}
	void insert(string &l,int k)
	{
		Trie_node *found = root;
		for (auto &s : l)
		{
			if (found->next[s - 'a'] != NULL)
				found = found->next[s - 'a'];
			else
			{
				found->next[s - 'a'] = newnode();
				found = found->next[s - 'a'];
			}
		}
		found->w += k;
	}
	int head, tail;
	void compute_fail()
	{
		head = 1;
		tail = 2;
		queue1[1] = root;
		while (head != tail)
		{
			Trie_node *part2 = NULL;
			Trie_node *father = queue1[head];
			head++;
			for (int s = 0; s < sigma; ++s)
			{
				if (father->next[s] != NULL)
				{
					if (father == root)
						father->next[s]->fail = root;
					else
					{
						part2 = father->fail;
						while (part2 != NULL)
						{
							if (part2->next[s] != NULL)
							{
								father->next[s]->fail = part2->next[s];
								break;
							}
							part2 = part2->fail;
						}
						if (part2 == NULL)
							father->next[s]->fail = root;
					}
					queue1[tail++] = (father->next[s]);
				}
			}
		}
	}
	void clear()
	{
		root = newnode();
	}
}tr;
long long MAXN=300, n, mod;
struct Matrix//矩阵的类
{
	long long a[300][300];
	void init()           //将其初始化为单位矩阵
	{
		memset(a, -1, sizeof(a));

	}
} A;

void printM(Matrix &a)
{
	for (int i = 0; i < 20; ++i)
	{
		cout << endl;
		for (int j = 0; j < 20; ++j)
			cout << a.a[i][j] << " ";
	}
}
Matrix mul(Matrix a, Matrix b)  //(a*b)%mod  矩阵乘法
{
	Matrix ans;
	ans.init();
	for (int i = 0; i < MAXN; i++)
		for (int j = 0; j < MAXN; j++)
		{
			for (int k = 0; k < MAXN; k++)
				if (a.a[i][k] >= 0 && b.a[k][j] >= 0)
				{
					ans.a[i][j] = max(ans.a[i][j], a.a[i][k] + b.a[k][j]);
				}
		}
	return ans;
}

Matrix pow(Matrix a, long long n)    //(a^n)%mod  //矩阵快速幂
{
	Matrix ans;
	ans.init();
	ans = a;
	n--;
	while (n)
	{

		if (n % 2)//n&1
			ans = mul(ans, a);
		n /= 2;
		a = mul(a, a);

	}
	return ans;
}

queue<Trie_node *> que;
Trie_node *bfs1;
void bfs()
{
	que.push(tr.root);
	while (!que.empty())
	{
		bfs1 = que.front();
		if(bfs1!=tr.root)
		bfs1->w += bfs1->fail->w;
		for (int i = 0; i < sigma; ++i)
			if (bfs1->next[i] != NULL)
				que.push(bfs1->next[i]);
		//cout << bfs1->sign << " " <<bfs1->fail->sign <<" "<<bfs1->w << endl;
		que.pop();
	}
	que.push(tr.root);
	while (!que.empty())
	{
		bfs1 = que.front();
		que.pop();
		for (int i = 0; i < sigma; ++i)
			if (bfs1->next[i] != NULL)
			{
				que.push(bfs1->next[i]);
				A.a[bfs1->sign][bfs1->next[i]->sign] = bfs1->next[i]->w;
				//cout << bfs1->sign << "|| " << bfs1->next[i]->sign << " || " << bfs1->next[i]->w << endl;
			}
		A.a[bfs1->sign][tr.root->sign] = 0;
		Trie_node *fa = bfs1->fail;
		while (fa)
		{
			A.a[bfs1->sign][fa->sign] = 0;
			for (int i = 0; i < sigma; ++i)
				if (fa->next[i] != NULL)
					A.a[bfs1->sign][fa->next[i]->sign] = fa->next[i]->w;
			fa = fa->fail;
		}
		A.a[1][1] = 0;
	}
}
array<int, 300> arr;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	string s;
	A.init();
	long long a, b, c, d;
	cin >> a >> b ;
	for (int i = 1; i <= a; ++i)
		cin >> arr[i];
	for (int i = 1; i <= a; ++i)
	{
		cin >> s;
		tr.insert(s,arr[i]);
	}
	tr.compute_fail();
	bfs();
	A = pow(A, b);

	long long ans = 0;
	for (int i = 0; i < 300; ++i)
	{
		ans = max(ans,A.a[tr.root->sign][i]);
	}
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int maxn = 200 + 5;
const long long inf = 0x3f3f3f3f3f3f3f3f;

int n;
long long l;

int a[maxn];
string str[maxn];

struct matrix {
	long long f[maxn][maxn];

	matrix(){memset(f, 0xc0, sizeof(f));}
};

matrix E, F, G;

matrix mul(matrix &A, matrix &B){
	matrix ret;

	for(int i=0;i<maxn;i++){
		for(int j=0;j<maxn;j++){
			for(int k=0;k<maxn;k++){
				ret.f[i][j] = max(ret.f[i][j], A.f[i][k] + B.f[k][j]);
			}
		}
	}

	return ret;
}

matrix qpow(matrix b, long long x){
	matrix ret = E;

	while(x){
		if(x & 1){
			ret = mul(ret, b);
		}
		x >>= 1;
		b = mul(b, b);
	}

	return ret;
}

struct node {
	int nxt[30];
	int x;
	int fail;
};

struct ac {
	int tc;
	int root;
	node tree[maxn * 10];

	int insert(string str, int y){
		int pos = root;

		for(int i=0;i<str.length();i++){
			int x = str[i] - 'a';
			if(!tree[pos].nxt[x]){
				tree[pos].nxt[x] = ++tc;
			}
			pos = tree[pos].nxt[x];
		}

		tree[pos].x = y;

		return 0;
	}

	int build(){
		int i, j;

		queue <int> q;

		tree[root].fail = root;
		for(i=0;i<26;i++){
			if(tree[root].nxt[i]){
				tree[tree[root].nxt[i]].fail = root;
				q.push(tree[root].nxt[i]);
			}
		}

		while(!q.empty()){
			int pos = q.front();
			q.pop();

			for(i=0;i<26;i++){
				if(!tree[pos].nxt[i])continue;
				j = tree[pos].fail;
				while(j != root and !tree[j].nxt[i]){
					j = tree[j].fail;
				}
				if(tree[j].nxt[i])j = tree[j].nxt[i];
				tree[tree[pos].nxt[i]].fail = j;
				tree[tree[pos].nxt[i]].x += tree[j].x;
				q.push(tree[pos].nxt[i]);
			}

		}

		return 0;
	}

	int getmatrix(matrix &M){
		int i, j;
		int pos;

		for(pos=1;pos<=tc;pos++){
			for(i=0;i<26;i++){
				int x = tree[pos].nxt[i];
				if(x){
					M.f[pos][x] = tree[x].x;
				}else{
					j = tree[pos].fail;
					while(j != root and !tree[j].nxt[i]){
						j = tree[j].fail;
					}
					if(tree[j].nxt[i])j = tree[j].nxt[i];
					M.f[pos][j] = tree[j].x;
				}
			}
		}

		return 0;
	}

	ac(){root = tc = 1;}
} AC;

int main(){
	int i, j;

	E.f[1][1] = 0;

	cin >> n >> l;

	for(i=1;i<=n;i++){
		cin >> a[i];
	}

	for(i=1;i<=n;i++){
		cin >> str[i];
		AC.insert(str[i], a[i]);
	}

	AC.build();
	AC.getmatrix(G);

	F = qpow(G, l);

	long long ans = 0;

	for(i=1;i<=AC.tc;i++){
		ans = max(ans, F.f[1][i]);
	}

	cout << ans << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int maxn = 200 + 5;
const long long inf = 0x3f3f3f3f3f3f3f3f;

int n;
long long l;

int a[maxn];
string str[maxn];

struct matrix {
	long long f[maxn][maxn];

	matrix(){memset(f, 0xc0, sizeof(f));}
};

matrix E, F, G;

matrix mul(matrix &A, matrix &B){
	matrix ret;

	for(int i=0;i<maxn;i++){
		for(int j=0;j<maxn;j++){
			for(int k=0;k<maxn;k++){
				ret.f[i][j] = max(ret.f[i][j], A.f[i][k] + B.f[k][j]);
			}
		}
	}

	return ret;
}

matrix qpow(matrix b, long long x){
	matrix ret = E;

	while(x){
		if(x & 1){
			ret = mul(ret, b);
		}
		x >>= 1;
		b = mul(b, b);
	}

	return ret;
}

struct node {
	int nxt[30];
	int x;
	int fail;
};

struct ac {
	int tc;
	int root;
	node tree[maxn * 10];

	int insert(string str, int y){
		int pos = root;

		for(int i=0;i<str.length();i++){
			int x = str[i] - 'a';
			if(!tree[pos].nxt[x]){
				tree[pos].nxt[x] = ++tc;
			}
			pos = tree[pos].nxt[x];
		}

		tree[pos].x += y;

		return 0;
	}

	int build(){
		int i, j;

		queue <int> q;

		tree[root].fail = root;
		for(i=0;i<26;i++){
			if(tree[root].nxt[i]){
				tree[tree[root].nxt[i]].fail = root;
				q.push(tree[root].nxt[i]);
			}
		}

		while(!q.empty()){
			int pos = q.front();
			q.pop();

			for(i=0;i<26;i++){
				if(!tree[pos].nxt[i])continue;
				j = tree[pos].fail;
				while(j != root and !tree[j].nxt[i]){
					j = tree[j].fail;
				}
				if(tree[j].nxt[i])j = tree[j].nxt[i];
				tree[tree[pos].nxt[i]].fail = j;
				tree[tree[pos].nxt[i]].x += tree[j].x;
				q.push(tree[pos].nxt[i]);
			}

		}

		return 0;
	}

	int getmatrix(matrix &M){
		int i, j;
		int pos;

		for(pos=1;pos<=tc;pos++){
			for(i=0;i<26;i++){
				int x = tree[pos].nxt[i];
				if(x){
					M.f[pos][x] = tree[x].x;
				}else{
					j = tree[pos].fail;
					while(j != root and !tree[j].nxt[i]){
						j = tree[j].fail;
					}
					if(tree[j].nxt[i])j = tree[j].nxt[i];
					M.f[pos][j] = tree[j].x;
				}
			}
		}

		return 0;
	}

	ac(){root = tc = 1;}
} AC;

int main(){
	int i, j;

	E.f[1][1] = 0;

	cin >> n >> l;

	for(i=1;i<=n;i++){
		cin >> a[i];
	}

	for(i=1;i<=n;i++){
		cin >> str[i];
		AC.insert(str[i], a[i]);
	}

	AC.build();
	AC.getmatrix(G);

	F = qpow(G, l);

	long long ans = 0;

	for(i=1;i<=AC.tc;i++){
		ans = max(ans, F.f[1][i]);
	}

	cout << ans << endl;

	return 0;
}


#define _USE_MATH_DEFINES
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <complex>
#include <cmath>
#include <numeric>
#include <bitset>
#include <functional>

using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}

typedef long long int64;
typedef pair<int, int> ii;
const int64 INF = 1LL << 60;
const int MOD = 1e9 + 7;

const int SIGMA = 26;

struct Node {
  Node* child[SIGMA];
  Node* fail;
  int64 cnt;
};

const int N = 200 + 10;
Node pool[N], *last;

Node* new_node(Node* fail) {
  Node* p = last++;
  p->fail = fail;
  fill(p->child, p->child + SIGMA, (Node*)nullptr);
  p->cnt = 0;
  return p;
}

void insert(char* s, int len, int cnt, Node* root) {
  Node* p = root;
  for (int i = 0; i < len; ++i) {
    int k = s[i] - 'a';
    if (!p->child[k]) {
      p->child[k] = new_node(root);
    }
    p = p->child[k];
  }
  p->cnt += cnt;
}

void build_ac_automaton(Node* root) {
  queue<Node*> Q;
  for (int k = 0; k < SIGMA; ++k) {
    if (root->child[k]) {
      Q.push(root->child[k]);
    }
  }
  while (!Q.empty()) {
    Node* p = Q.front();
    Q.pop();
    for (int k = 0; k < SIGMA; ++k) {
      if (!p->child[k]) {
        p->child[k] = p->fail->child[k];
      } else {
        p->child[k]->fail = p->fail->child[k] ? p->fail->child[k] : root;
        Q.push(p->child[k]);
      }
    }
    p->cnt += p->fail->cnt;
  }
}

char s[N];
int64 a[N][N], ret[N][N], t[N][N];
int64 A[N][N];
int v[N];

void mul(int64 a[N][N], int64 b[N][N], int64 c[N][N], int n) {
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      c[i][j] = -INF;
      for (int k = 0; k < n; ++k) {
        c[i][j] = max(c[i][j], a[i][k] + b[k][j]);
      }
    }
  }
}

int main() {
  int m;
  int64 n;
  scanf("%d%lld", &m, &n);
  for (int i = 0; i < m; ++i) {
    scanf("%d", &v[i]);
  }
  last = pool;
  Node* root = new_node(nullptr);
  for (int i = 0; i < m; ++i) {
    scanf("%s", s);
    int len = strlen(s);
    insert(s, len, v[i], root);
  }
  build_ac_automaton(root);
  int sz = last - pool;
  // trace(sz);
  for (int i = 0; i < sz; ++i) {
    for (int j = 0; j < sz; ++j) {
      a[i][j] = -INF;
    }
  }
  for (Node* p = pool; p != last; ++p) {
    int x = p - pool;
    for (int k = 0; k < SIGMA; ++k) {
      Node* q = p->child[k] ? p->child[k] : root;
      int y = q - pool;
      // trace(x, y, q->cnt);
      if (a[x][y] == -INF) {
        a[x][y] = q->cnt;
      } else {
        a[x][y] += q->cnt;
      }
    }
  }
  bool first = true;
  for (; n; n >>= 1) {
    if (n & 1) {
      if (first) {
        memcpy(ret, a, sizeof(ret));
        first = false;
      } else {
        mul(ret, a, t, sz);
        memcpy(ret, t, sizeof(ret));
      }
    }
    mul(a, a, t, sz);
    memcpy(a, t, sizeof(a));
  }
  int64 ans = 0;
  for (int i = 0; i < sz; ++i) {
    ans = max(ans, ret[0][i]);
  }
  printf("%lld\n", ans);
  return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200;
int a[MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

struct vertex {
    int cost;
    int next[26];
    vertex() {
        memset(next, -1, sizeof(next));
    }
};

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

vertex t[2 * MAXN + 1];
int sz = 0;

void add(string& s) {
    int n = (int)s.size();
    int v = 0;
    for(int i = 0; i < n; i++) {
        char c = s[i] - 'a';
        if (t[v].next[c] == -1)
            t[v].next[c] = sz++;
        v = t[v].next[c];
    }
    string temp = "";
    for(int i = n - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    for(int i = 0; i < n; i++)
        add(str[i]);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            if(t[i].next[j] == -1)
                continue;
            int nxt = t[i].next[j];
            dp.f[i][nxt] = t[nxt].cost;
        }
        for(int j = 0; j < 26; j++) {
            if(t[0].next[j] == -1)
                continue;
            int nxt = t[0].next[j];
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200;
int a[MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

struct vertex {
    int cost;
    int next[26];
    int link;
    int p;
    char pch;
    int go[26];
    vertex() {
        memset(next, -1, sizeof(next));
        memset(go, -1, sizeof(go));
        link = -1;
        cost = 0;
    }
};

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

vertex t[2 * MAXN + 1];
int sz = 0;

void add(string& s) {
    int n = (int)s.size();
    int v = 0;
    for(int i = 0; i < n; i++) {
        char c = s[i] - 'a';
        if (t[v].next[c] == -1) {
            t[sz].p = v;
            t[sz].pch = c;
            t[v].next[c] = sz++;
        }
        v = t[v].next[c];
    }
    string temp = "";
    for(int i = n - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

int go (int v, char c);

int get_link (int 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;
}

int go (int 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];
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    for(int i = 0; i < n; i++)
        add(str[i]);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            int nxt = go(i, j);
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200, K = 26, NMAX = 200;
int a[MAXN + 1], used[2 * MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

struct vertex {
    int next[K];
    bool leaf;
    int p;
    char pch;
    int link;
    int go[K];
    int cost;
};

vertex t[NMAX+1];
int sz;

void init() {
    t[0].p = t[0].link = -1;
    t[0].cost = 0;
    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, int index) {
    int 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].cost = 0;
            t[sz].link = -1;
            t[sz].p = v;
            t[sz].pch = c;
            t[v].next[c] = sz++;
        }
        v = t[v].next[c];
    }
    t[v].cost += a[index];
}

int go (int v, char c);

int get_link (int 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;
}

int go (int 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];
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    init();
    for(int i = 0; i < n; i++)
        add_string(str[i], i);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 1; i < sz; i++) {
        t[i].cost += t[get_link(i)].cost;
    }
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            int nxt = go(i, j);
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    /*for(int i = 0; i < sz; i++) {
        for(int j = 0; j < sz; j++) {
            cout << dp.f[i][j] << " ";
        }
        cout << "\n";
    }*/
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200;
int a[MAXN + 1], used[2 * MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

struct vertex {
    int cost;
    int next[26];
    int link;
    int p;
    char pch;
    int go[26];
    vertex() {
        memset(next, -1, sizeof(next));
        memset(go, -1, sizeof(go));
        link = -1;
        cost = 0;
        p = -1;
    }
};

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

vertex t[2 * MAXN + 1];
int sz = 1;

void add(string& s) {
    int n = (int)s.size();
    int v = 0;
    for(int i = 0; i < n; i++) {
        char c = s[i] - 'a';
        if (t[v].next[c] == -1) {
            t[sz].p = v;
            t[sz].pch = c;
            t[v].next[c] = sz++;
        }
        v = t[v].next[c];
    }
    if(used[v])
        return;
    used[v] = 1;
    string temp = "";
    for(int i = n - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

int go (int v, char c);

int get_link (int 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;
}

int go (int 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];
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    for(int i = 0; i < n; i++)
        add(str[i]);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            int nxt = go(i, j);
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    /*for(int i = 0; i < sz; i++) {
        for(int j = 0; j < sz; j++) {
            cout << dp.f[i][j] << " ";
        }
        cout << "\n";
    }*/
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200;
int a[MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

struct vertex {
    int cost;
    int next[26];
    vertex() {
        memset(next, -1, sizeof(next));
    }
};

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

vertex t[2 * MAXN + 1];
int sz = 0;

void add(string& s) {
    int n = (int)s.size();
    int v = 0;
    for(int i = 0; i < n; i++) {
        char c = s[i] - 'a';
        if (t[v].next[c] == -1)
            t[v].next[c] = sz++;
        v = t[v].next[c];
    }
    string temp = "";
    for(int i = n - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    for(int i = 0; i < n; i++)
        add(str[i]);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            if(t[i].next[j] == -1)
                continue;
            int nxt = t[i].next[j];
            if(dp.f[i][nxt] == -inf)
                dp.f[i][nxt] = 0;
            dp.f[i][nxt] += t[nxt].cost;
        }
        dp.f[i][0] = 0;
    }
    dp = power(dp, l + 1);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200, K = 26, NMAX = 200;
int a[MAXN + 1], used[2 * MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

struct vertex {
    int next[K];
    bool leaf;
    int p;
    char pch;
    int link;
    int go[K];
    int cost;
};

vertex t[NMAX+1];
int sz;

void init() {
    t[0].p = t[0].link = -1;
    t[0].cost = 0;
    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) {
    int 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].cost = 0;
            t[sz].link = -1;
            t[sz].p = v;
            t[sz].pch = c;
            t[v].next[c] = sz++;
        }
        v = t[v].next[c];
    }
}

void dfs(int v, string s = "") {
    for(int i = 0; i < 26; i++) {
        if(t[v].next[i] == -1)
            continue;
        dfs(t[v].next[i], s + (char)('a' + i));
    }
    string temp = "";
    for(int i = (int)s.size() - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

int go (int v, char c);

int get_link (int 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;
}

int go (int 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];
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    init();
    for(int i = 0; i < n; i++)
        add_string(str[i]);
    dfs(0);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            int nxt = go(i, j);
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    /*for(int i = 0; i < sz; i++) {
        for(int j = 0; j < sz; j++) {
            cout << dp.f[i][j] << " ";
        }
        cout << "\n";
    }*/
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200;
int a[MAXN + 1], used[2 * MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

struct vertex {
    int cost;
    int next[26];
    int link;
    int p;
    char pch;
    int go[26];
    vertex() {
        memset(next, -1, sizeof(next));
        memset(go, -1, sizeof(go));
        link = -1;
        cost = 0;
    }
};

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

vertex t[2 * MAXN + 1];
int sz = 0;

void add(string& s) {
    int n = (int)s.size();
    int v = 0;
    for(int i = 0; i < n; i++) {
        char c = s[i] - 'a';
        if (t[v].next[c] == -1) {
            sz++;
            t[sz].p = v;
            t[sz].pch = c;
            t[v].next[c] = sz;
        }
        v = t[v].next[c];
    }
    if(used[v])
        return;
    used[v] = 1;
    string temp = "";
    for(int i = n - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

int go (int v, char c);

int get_link (int 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;
}

int go (int 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];
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    for(int i = 0; i < n; i++)
        add(str[i]);
    sz++;
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            int nxt = go(i, j);
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    /*for(int i = 0; i < sz; i++) {
        for(int j = 0; j < sz; j++) {
            cout << dp.f[i][j] << " ";
        }
        cout << "\n";
    }*/
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200;
int a[MAXN + 1], used[2 * MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

struct vertex {
    int cost;
    int next[26];
    int link;
    int p;
    char pch;
    int go[26];
    vertex() {
        memset(next, -1, sizeof(next));
        memset(go, -1, sizeof(go));
        link = -1;
        cost = 0;
    }
};

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

vertex t[2 * MAXN + 1];
int sz = 1;

void add(string& s) {
    int n = (int)s.size();
    int v = 0;
    for(int i = 0; i < n; i++) {
        char c = s[i] - 'a';
        if (t[v].next[c] == -1) {
            t[sz].p = v;
            t[sz].pch = c;
            t[v].next[c] = sz++;
        }
        v = t[v].next[c];
    }
    if(used[v])
        return;
    used[v] = 1;
    string temp = "";
    for(int i = n - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

int go (int v, char c);

int get_link (int 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;
}

int go (int 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];
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    for(int i = 0; i < n; i++)
        add(str[i]);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            int nxt = go(i, j);
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    /*for(int i = 0; i < sz; i++) {
        for(int j = 0; j < sz; j++) {
            cout << dp.f[i][j] << " ";
        }
        cout << "\n";
    }*/
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200;
int a[MAXN + 1], used[2 * MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

struct vertex {
    int cost;
    int next[26];
    int link;
    int p;
    char pch;
    int go[26];
    vertex() {
        memset(next, -1, sizeof(next));
        memset(go, -1, sizeof(go));
        link = -1;
        cost = 0;
    }
};

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

vertex t[2 * MAXN + 1];
int sz = 0;

void add(string& s) {
    int n = (int)s.size();
    int v = 0;
    for(int i = 0; i < n; i++) {
        char c = s[i] - 'a';
        if (t[v].next[c] == -1) {
            t[sz].p = v;
            t[sz].pch = c;
            t[v].next[c] = sz++;
        }
        v = t[v].next[c];
    }
    if(used[v])
        return;
    used[v] = 1;
    string temp = "";
    for(int i = n - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

int go (int v, char c);

int get_link (int 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;
}

int go (int 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];
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    for(int i = 0; i < n; i++)
        add(str[i]);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            int nxt = go(i, j);
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    /*for(int i = 0; i < sz; i++) {
        for(int j = 0; j < sz; j++) {
            cout << dp.f[i][j] << " ";
        }
        cout << "\n";
    }*/
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define forn(i, n) for(int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll inf = 1e18;

struct Matrix {
    int n;
    ll f[250][250];
    Matrix(int sz) {
        n = sz;
        memset(f, 0, sizeof(f));
    }
};

const int MAXN = 200, K = 26, NMAX = 200;
int a[MAXN + 1], used[2 * MAXN + 1];
string str[MAXN + 1];
map<string, int> cost;

Matrix operator*(const Matrix& a, const Matrix& b) {
    int n = a.n;
    Matrix res(n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            ll mx = -inf;
            for(int k = 0; k < n; k++) {
                if(a.f[i][k] == -inf || b.f[k][j] == -inf)
                    continue;
                mx = max(mx, a.f[i][k] + b.f[k][j]);
            }
            res.f[i][j] = mx;
        }
    return res;
}

struct vertex {
    int next[K];
    bool leaf;
    int p;
    char pch;
    int link;
    int go[K];
    int cost;
};

vertex t[NMAX+1];
int sz;

void init() {
    t[0].p = t[0].link = -1;
    t[0].cost = 0;
    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) {
    int 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].cost = 0;
            t[sz].link = -1;
            t[sz].p = v;
            t[sz].pch = c;
            t[v].next[c] = sz++;
        }
        v = t[v].next[c];
    }
    if(t[v].leaf)
        return;
    t[v].leaf = true;
    string temp = "";
    for(int i = (int)s.size() - 1; i >= 0; i--) {
        temp = s[i] + temp;
        t[v].cost += cost[temp];
    }
}

int go (int v, char c);

int get_link (int 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;
}

int go (int 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];
}

Matrix power(Matrix &dp, ll n) {
    Matrix res(dp.n);
    for(int i = 0; i < dp.n; i++) {
        for(int j = 0; j < dp.n; j++) {
            if(i == j)
                res.f[i][j] = 0;
            else
                res.f[i][j] = -inf;
        }
    }
    while(n) {
        if(n & 1)
            res = res * dp;
        dp = dp * dp;
        n >>= 1LL;
    }
    return res;
}

int main() {
    //ios_base::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    ll l;
    cin >> n >> l;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for(int i = 0; i < n; i++) {
        cin >> str[i];
        cost[str[i]] += a[i];
    }
    init();
    for(int i = 0; i < n; i++)
        add_string(str[i]);
    Matrix dp(sz);
    for(int i = 0; i < sz; i++)
        for(int j = 0; j < sz; j++)
            dp.f[i][j] = -inf;
    for(int i = 0; i < sz; i++) {
        for(int j = 0; j < 26; j++) {
            int nxt = go(i, j);
            dp.f[i][nxt] = t[nxt].cost;
        }
    }
    /*for(int i = 0; i < sz; i++) {
        for(int j = 0; j < sz; j++) {
            cout << dp.f[i][j] << " ";
        }
        cout << "\n";
    }*/
    dp = power(dp, l);
    ll ans = 0;
    for(int i = 0; i < sz; i++)
        ans = max(ans, dp.f[0][i]);
    cout << ans << "\n";
    return 0;
}


#include<bits/stdc++.h>
#define all(v) (v).begin(),(v).end()
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define ri(x) scanf("%d",&(x))
#define ri2(x,y) scanf("%d %d",&(x),&(y))
#define ri3(x,y,z) scanf("%d %d %d",&(x),&(y),&(z))
#define rll(x) scanf("%lld",&(x))
#define rll2(x,y) scanf("%lld %lld",&(x),&(y))
#define rll3(x,y,z) scanf("%lld %lld %lld",&(x),&(y),&(z))
#define gc(x) ((x) = getchar())
using namespace::std;

const long double PI = acos(-1);
const long long MOD = 1000000000 +7;

typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<ll,pll> tll;
typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<ll> vll;
typedef vector<pll> vpll;
typedef vector<tll> vtll;
typedef vector<string> vs;
typedef set<int> si;
typedef set<ii> sii;
typedef set<iii> siii;

ll gcd(ll a, ll b){ return b==0?a:gcd(b,a%b);}

ll add(ll a, ll b, ll m = MOD){
	if(a >= m) a %= m;
	if(b >= m) b %= m;
	if(a < 0) a += m;
	if(b < 0) b += m;
	ll res = a+b;
	if(res >= m or res <= -m) res %= m;
	if(res < 0) res += m;
	return res;
}

ll mul(ll a, ll b, ll m = MOD){
	if(a >= m) a %= m;
	if(b >= m) b %= m;
	if(a < 0) a += m;
	if(b < 0) b += m;
	ll res = a*b;
	if(res >= m or res <= -m) res %= m;
	if(res < 0) res += m;
	return res;
}

ll pow_mod(ll a, ll b, ll m = MOD){
	ll res = 1LL;
	a = a%m;
	while(b){
		if(b&1) res = mul(res,a,m);
		b >>= 1;
		a = mul(a,a,m);
	}
	return res;
}

ll fastexp(ll a, ll b){
	ll res = 1LL;
	while(b){
		if(b&1) res = res*a;
		b >>= 1;
		a *= a;
	}
	return res;
}

int gcdExtendido(int a, int b, int *x, int *y){
	if(a == 0){
		*x = 0;
		*y = 1;
		return b;
	}
	int x1, y1;
	int gcd = gcdExtendido(b%a,a,&x1,&y1);

	*x = y1-(b/a)*x1;
	*y = x1;
	return gcd;
}

int modInverso(int a, int m){
	int x, y;
	int g = gcdExtendido(a,m,&x,&y);
	if(g!=1) return -1;
	else return (x%m + m)%m;
}

/****************************************
*************P*L*A*N*T*I*L*L*A************
*****************************************/

const int SUML = 200+5;
const int E = 26;

int n;
ll l;
int a[SUML];
int p[SUML];
char s[SUML];
int nodes = 1;
int suf[SUML];
int val[SUML];
bool vis[SUML];
int super[SUML];
int enter[SUML];
int go[SUML][E];
ll C[SUML][SUML];
ll R[SUML][SUML];
ll M[SUML][SUML];
int trie[SUML][E];

void insert(int npat){
	int pos = 0;
	int len = strlen(s);
	for(int i=0; i<len; i++){
		int nxt = s[i] - 'a';
		if(trie[pos][nxt] == 0){
			p[nodes] = pos;
			enter[nodes] = nxt;
			trie[pos][nxt] = nodes++;
		}
		pos = trie[pos][nxt];
	}
	val[pos] += a[npat];
}

int getSuffixLink(int);

int getGo(int u, int c){
	if(go[u][c] != -1) return go[u][c];
	if(trie[u][c]) return go[u][c] = trie[u][c];
	return go[u][c] = u ? getGo(getSuffixLink(u),c) : 0;
}

int getSuffixLink(int u){
	if(suf[u] != -1) return suf[u];
	if(p[u] == 0) return suf[u] = 0;
	return suf[u] = getGo(getSuffixLink(p[u]),enter[u]);
}

int getSuperLink(int u){
	if(super[u] != -1) return super[u];
	if(u == 0) return super[u] = 0;
	if(val[getSuffixLink(u)]) return super[u] = getSuffixLink(u);
	return super[u] = getSuperLink(getSuffixLink(u));
}

int getCost(int u){
	if(vis[u]) return val[u];
	vis[u] = true;
	val[u] += getCost(getSuperLink(u));
	return val[u];
}

void buildAutomaton(int n_pat){
	for(int i=1; i<=n_pat; i++){
		scanf("%s",s);
		insert(i);
	}
	for(int i=0; i<nodes; i++){
		suf[i] = super[i] = -1;
		for(int j=0; j<E; j++){
			go[i][j] = -1;
		}
	}
	for(int i=0; i<nodes; i++){
		getSuffixLink(i);
		getSuperLink(i);
		for(int j=0; j<E; j++){
			getGo(i,j);
		}
		getCost(i);
	}
}

void buildMatrix(){
	for(int i=0; i<nodes; i++){
		for(int j=0; j<nodes; j++){
			M[i][j] = -1;
		}
	}
	for(int i=0; i<nodes; i++){
		for(int j=0; j<E; j++){
			int nxt = getGo(i,j);
			M[i][nxt] = val[nxt];
		}
	}
}

void multiply(int type){
	for(int i=0; i<nodes; i++){
		for(int j=0; j<nodes; j++){
			C[i][j] = -1;
			for(int k=0; k<nodes; k++){
				if(type){
					if(R[i][k] == -1 or M[k][j] == -1) continue;
					C[i][j] = max(C[i][j],R[i][k] + M[k][j]);
				}
				else{
					if(M[i][k] == -1 or M[k][j] == -1) continue;
					C[i][j] = max(C[i][j],M[i][k] + M[k][j]);
				}
			}
		}
	}
	for(int i=0; i<nodes; i++){
		for(int j=0; j<nodes; j++){
			if(type) R[i][j] = C[i][j];
			else M[i][j] = C[i][j];
		}
	}
}

void fastexpo(ll x){
	for(int i=0; i<nodes; i++){
		for(int j=0; j<nodes; j++){
			R[i][j] = -1;
		}
	}
	R[0][0] = 0;
	while(x > 0){
		if(x & 1) multiply(1);
		multiply(0);
		x >>= 1;
	}
}

int main(){
	ri(n);
	rll(l);
	for(int i=1; i<=n; i++) ri(a[i]);
	buildAutomaton(n);
	buildMatrix();
	fastexpo(l);
	ll ans = 0LL;
	for(int i=0; i<nodes; i++){
		ans = max(ans,R[0][i]);
	}
	cout << ans << endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define pb push_back
#define fi first
#define se second
#define ld long double
#define PI 3.141592653589793238462643383279
#define endl '\n'

const int NN = 205;
int sz;
const ll inf = 1e17;
class matrix{
public:
	ll mat[NN][NN];
	matrix(){
		for(int i = 0; i < NN; i++)
			for(int j = 0; j < NN; j++)
				mat[i][j] = - inf;
	}
	inline matrix operator * (const matrix &a){
		matrix temp;
		for(int i = 0; i < sz; i++)
			for(int j = 0; j < sz; j++){
				temp.mat[i][j] = - inf;
				for(int k = 0; k < sz; k++)
				temp.mat[i][j] = max(temp.mat[i][j], mat[i][k] + a.mat[k][j]);
			}
		return temp;
	}
	inline void operator = (const matrix &b){
		for(int i = 0; i < sz; i++)
			for(int j = 0; j < sz; j++)
				mat[i][j] = b.mat[i][j];
	}
};
matrix matpow(matrix a,ll k){
	bool b = 1;
	matrix ans;
	while(k){
		if(k & 1)
		{
			if(b)
				ans = a,b = 0;
			else
				ans = ans * a;
		}
		a = a * a;
		k >>= 1;
	}
	return ans;
}
const int CHAR = 26;
const int N = 205;

int go[N][CHAR];
#define conv(ch) ch - 'a'
class AhoCora {
public:
	struct Node {
		int ch[CHAR];
		int link;
		ll val;
	}nd[N];
	int Q[N], qs, qe;
	int size;
	int createNode() {
		int ret = size++;
		for (int i = 0; i<CHAR; i++) {
			nd[ret].ch[i] = -1;
		}
		nd[ret].val = 0;
		return ret;
	}
	void init() {
		size = 0;
		createNode();
	}
	template<typename A>
	void add(A str,const int &sz,const int &val) {
		int cur = 0;
		for (int i = 0; i<sz; i++) {
			int c = conv(str[i]);
			if (nd[cur].ch[c] == -1) {
				int nnd = createNode();
				nd[cur].ch[c] = nnd;
			}
			cur = nd[cur].ch[c];
		}
		nd[cur].val = nd[cur].val + val;
	}
	inline int next(int u, const int &c) {
		if(go[u][c])
			return go[u][c] - 1;
		if(nd[u].ch[c] != -1)
			return nd[u].ch[c];
		if(!u)
			return 0;
		go[u][c] = 1 + next(nd[u].link, c);
		return go[u][c] - 1;
	}
	void computelink() {
		qs = qe = 0;
		nd[0].link = 0;
		for (int x, i = 0; i<CHAR; i++) {
			if ((x = nd[0].ch[i]) >= 0) {
				Q[qe++] = x;
				nd[x].link = 0;
			}
		}
		while (qs<qe) {
			int u = Q[qs++];
			for (int v, i = 0; i<CHAR; i++) {
				if ((v = nd[u].ch[i]) >= 0) {
					Q[qe++] = v;
					int m = nd[u].link;
					int L = nd[v].link = next(m, i);
					nd[v].val += nd[L].val;
				}
			}
		}
	}
}acc;
int a[N];
char s[N];
signed main()
{
	//freopen("inp.txt","r",stdin);
	int n;
	ll l;
	acc.init();
	scanf("%d %lld",&n,&l);
	for(int i = 1; i <= n; i++)
		scanf("%d ",&a[i]);
	for(int i = 1; i <= n; i++){
		scanf("%s",s);
		acc.add(s,strlen(s),a[i]);
	}
	acc.computelink();
	sz = acc.size;
	matrix p;
	for(int i = 0; i < sz; i++){
		for(int j = 0; j < 26; j++){
			int k = acc.next(i,j);
			p.mat[i][k] = acc.nd[k].val;
		}
	}
	p = matpow(p,l);
	ll maxi = - 1;
	for(int i = 0; i < sz; i++)
		maxi = max(maxi, p.mat[0][i]);
	printf("%lld",maxi);
	return 0;
}