/*
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
#define nod first.first
#define cost first.second
#define nbr second
#define val first
#define key second
typedef pair<long long,long long> Pair;
typedef pair<Pair,long long> Triple;
const long long Nmax = 755;
const long long Mmax = 1255;
const long long Kmax = 17;
const long long oo = 0x3f3f3f3f;
long long N,M,K,act;
long long Nodes[Kmax];
vector< Triple > Leg[Nmax];
long long D[1<<Kmax][Kmax];
long long Dist[Kmax][Kmax][Kmax];
long long Marked[Nmax],Co;
long long Cost[Nmax];
ifstream F("gather.in");
ofstream G("gather.out");
priority_queue< Pair , vector< Pair > , greater< Pair > > Heap;
int main()
{
F>>K>>N>>M;
Nodes[0]=1;
for (long long i=1;i<=K;++i)
F>>Nodes[i];
for (long long i=1;i<=M;++i)
{
long long x,y,c,n;
F>>x>>y>>c>>n;
Leg[x].push_back( make_pair( make_pair( y , c ) , n ) );
Leg[y].push_back( make_pair( make_pair( x , c ) , n ) );
}
for (long long i=0;i<=K;++i)
for (long long j=0;j<=K ;++j)
{
long long Start = Nodes[i];
Heap.push( make_pair(0,Start) );
while ( Co < N )
{
while ( Marked[ Heap.top().key ] )
Heap.pop();
long long Nod = Heap.top().key ;
Marked[ Nod ] = 1, ++Co;
Cost[ Nod ] = Heap.top().val;
Heap.pop();
for ( vector<Triple>::iterator it=Leg[Nod].begin();it!=Leg[Nod].end();++it )
if ( !Marked[ it->nod ] && it->nbr >= j )
Heap.push( make_pair( it->cost + Cost[ Nod ] , it->nod ) );
}
for (long long k=1;k<=K;++k)
Dist[i][k][j] = Cost[ Nodes[k] ];
for (long long k=1;k<=N;++k) Marked[k]=Cost[k]=0;
Co=0;
while ( Heap.size() ) Heap.pop();
}
for (long long i=1;i<( 1<<K );++i)
{
long long det=0;
for ( long long j=i;j;j>>=1)
if ( j & 1 ) ++det;
for ( long long j=1,jj=1;j<=i;j<<=1,++jj)
if ( j & i )
{
D[i][jj]=oo;
long long Act = i-j;
if ( Act == 0 )
D[i][jj]= Nodes[jj] == 1 ? 0 : Dist[0][jj][0];
else
for ( long long k=1,kk=1;k<=Act;k<<=1,++kk)
if ( k & Act )
D[i][jj]= min ( D[i][jj] , Dist[kk][jj][det-1] * det + D[Act][kk] );
}
}
long long Sol=oo;
for (long long i=1;i<=K;++i)
Sol=min(Sol,D[(1<<K)-1][i]);
G<<Sol<<'\n';
}
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define MAX_N 755
#define MAX_K 16
#define FIN "gather.in"
#define FOUT "gather.out"
#define INF 0x3f3f3f3f
#define f first
#define s second
#define mp make_pair
#define pb push_back
int K, N, M, V[MAX_K], D[MAX_K][MAX_K][MAX_N], A[1<<MAX_K][MAX_K], Res;
vector< pair<int, pair<int, int> > > G[MAX_N];
priority_queue< pair<int, int> > Q;
void dijkstra(int src, int limit, int D[])
{
int n, d, t;
vector < pair<int, pair<int, int> > >::iterator it;
memset(D, 0x3f, N*sizeof(D[0]));
D[src] = 0;
for (Q.push(mp(0, src)); !Q.empty(); )
{
n = Q.top().s; d = -Q.top().f; Q.pop();
if (D[n] < d) continue;
for (it = G[n].begin(); it != G[n].end(); ++it)
{
if (it->s.s < limit) continue;
if (D[it->f] > (t = D[n]+it->s.f))
{
D[it->f] = t;
Q.push(mp(-t, it->f));
}
}
}
}
int main()
{
int i, j, k, a, b, cnt;
freopen(FIN, "r", stdin);
freopen(FOUT, "w", stdout);
scanf("%d %d %d", &K, &N, &M);
for (++K, i = 1; i < K; ++i)
{
scanf("%d", &j);
V[i] = --j;
}
for (; M; --M)
{
scanf("%d %d %d %d", &i, &j, &a, &b);
--i, --j;
G[i].pb(mp(j, mp(a, b)));
G[j].pb(mp(i, mp(a, b)));
}
for (i = 0; i <= K; ++i)
for (j = 1; j <= K; ++j)
dijkstra(V[i], j, D[i][j]);
memset(A, 0x3f, sizeof(A));
A[1][0] = 0;
for (i = 2; i < (1<<K); ++i)
{
for (cnt = -1, j = i; j; j &= j-1) ++cnt;
for (j = 0; j < K; ++j)
{
if (!(i&(1<<j))) continue;
for (k = 0; k < K; ++k)
{
if (A[i-(1<<j)][k] == INF || D[k][cnt][V[j]] == INF) continue;
A[i][j] = min(A[i][j], A[i-(1<<j)][k] + cnt*D[k][cnt][V[j]]);
}
}
}
Res = A[(1<<K)-1][0];
for (i = 0; i < K; ++i)
Res = min(Res, A[(1<<K)-1][i]);
printf("%d\n", Res);
return 0;
}