#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
#define re2(i, l, r) for (int i=l; i<r; i++)
#define re3(i, l, r) for (int i=l; i<=r; i++)
#define rre(i, n) for (int i=n-1; i>=0; i--)
#define rre1(i, n) for (int i=n; i>0; i--)
#define rre2(i, r, l) for (int i=r-1; i>=l; i--)
#define rre3(i, r, l) for (int i=r; i>=l; i--)
#define ll long long
const int MAXN = 50010, MAXM = 7000010, INF = ~0U >> 2;
struct edge {
    int b, w, next;
} E[MAXM];
int n, m = 0, s, t, n0, A0[MAXN][10], hd[MAXN], tl[MAXN], WW[10], dist[MAXN], No[MAXN], pos[MAXN], res = 0;
ll A[MAXN], B0[10];
char sss[20];
void init()
{
	scanf("%d", &n);
	re(i, 10) scanf("%d", &WW[i]);
	re(i, n) {scanf("%s", sss); A[i] = 0; re(j, 10) A[i] = A[i] * 10 + sss[j] - 48;}
}
void add_edge(int a, int b, int w)
{
	E[m].b = b; E[m].w = w; E[m].next = -1; if (hd[a] == -1) hd[a] = m; else E[tl[a]].next = m; tl[a] = m++;
}
void prepare()
{
	ll sw = A[0], tw = A[n - 1], x; sort(A, A + n);
	re(i, n) {
		if (A[i] == sw) s = i; if (A[i] == tw) t = i; hd[i] = tl[i] = -1;
		x = A[i]; rre(j, 10) {A0[i][j] = x % 10; x /= 10;}
	}
	B0[9] = 1; rre(i, 9) B0[i] = B0[i + 1] * 10;
	int l, r, mid, kk; ll y;
	re(i, n) {
		re(j, 10) {
			x = A[i] - A0[i][j] * B0[j];
			re(k, 10) {
				if (k != A0[i][j]) {
					l = 0; r = n - 1; kk = -1;
					while (l <= r) {mid = l + r >> 1; y = A[mid]; if (y == x) {kk = mid; break;} else if (y < x) l = mid + 1; else r = mid - 1;}
					if (kk >= 0) add_edge(i, kk, WW[j]);
				}
				x += B0[j];
			}
		}
		re(j, 9) re2(k, j+1, 10) if (A0[i][j] != A0[i][k]) {
			x = A[i] - A0[i][j] * B0[j] - A0[i][k] * B0[k];
			x += A0[i][k] * B0[j] + A0[i][j] * B0[k];
			l = 0; r = n - 1; kk = -1;
			while (l <= r) {mid = l + r >> 1; y = A[mid]; if (y == x) {kk = mid; break;} else if (y < x) l = mid + 1; else r = mid - 1;}
			if (kk >= 0) add_edge(i, kk, WW[j]);
		}
	}
}
void swap(int s1, int s2)
{
	pos[No[s1]] = s2; pos[No[s2]] = s1; int tmp = No[s1]; No[s1] = No[s2]; No[s2] = tmp;
}
void heap_up(int x)
{
	int y; while (x > 1 && dist[No[x]] < dist[No[y = x >> 1]]) {swap(x, y); x = y;}
}
void heap_down(int x)
{
	int lc = x << 1;
	if (lc > n0) return; else if (lc == n0) {
		if (dist[No[x]] > dist[No[lc]]) swap(x, lc); return;
	} else {
		int d0 = dist[No[x]], d1 = dist[No[lc]], d2 = dist[No[lc + 1]];
		if (d0 <= d1 && d0 <= d2) return; else if (d1 <= d2) {swap(x, lc); heap_down(lc);} else {swap(x, lc + 1); heap_down(lc + 1);}
	}
}
void del_root()
{
	swap(1, n0); n0--; heap_down(1);
}
void solve()
{
	re(i, n) {No[i + 1] = i; pos[i] = i + 1; dist[i] = INF;} dist[s] = 0; swap(1, s + 1);
	int x, y, d0, d1; n0 = n;
	re2(i, 1, n) {
		x = No[1]; del_root(); d0 = dist[x];
		for (int p=hd[x]; p != -1; p=E[p].next) {
			y = E[p].b; d1 = d0 + E[p].w;
			if (d1 < dist[y]) {dist[y] = d1; heap_up(pos[y]);}
		}
	}
	res = dist[t];
}
void pri()
{
	if (res == INF) printf("%d\n", -1); else printf("%d\n", res);
}
int main()
{
	init();
	prepare();
	solve();
	pri();
	return 0;
}
