#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define DIM (1 << 13)
#define MAXN 752
#define MAXM 1252
#define MAX(x, y) ( ((x) > (y)) ? (x) : (y) )
#define MIN(x, y) ( ((x) < (y)) ? (x) : (y) )
#define foreach(V) for(edge *it = (V); it; it = it->link)
#define INF 4294967295
int K, N, M, __K[16], pos, len;
unsigned int pr_dist[16][16][16], // pr[i][j][k] -> distance from __K[i] to __K[j] through edges of capacity >= k
dist[MAXN], comb[16][1 << 15];
bool prisoner[MAXN];
char buf[DIM];
struct edge{
short int node;
char maxCnt;
unsigned int cost;
edge *link;
inline edge *new_edge(short int _node, char _maxCnt, int _cost){
edge *New = new edge;
New->node = _node, New->maxCnt = _maxCnt, New->cost = _cost, New->link = this;
return New;
}
} *G[MAXN]; // the graph edges
int size; // size of heap
struct heap_elem{
short int node;
unsigned int cost;
} Heap[MAXM];
inline int r_int32(){
while (buf[pos] < '0' || buf[pos] > '9'){
if (++pos >= DIM) len = fread(buf, 1, DIM, stdin), pos = 0;
}
int val = 0;
while (buf[pos] >= '0' && buf[pos] <= '9'){
if (pos == len) break;
val = val * 10 + buf[pos] - '0';
if (++pos == DIM) len = fread(buf, 1, DIM, stdin), pos = 0;
}
return val;
}
inline void w_int32(int k){
char lim[16], *s;
s = lim + 15, *s = 0;
do{
*--s = k % 10 + '0';
k /= 10;
} while (k);
puts(s);
}
inline void heap_pop(){
Heap[1] = Heap[size--];
heap_elem curr = Heap[1];
short int now = 1, next = 2;
if (next + 1 <= size && Heap[next + 1].cost < Heap[next].cost) ++next;
while (next <= size && Heap[now].cost > Heap[next].cost){
Heap[now] = Heap[next];
now = next;
next <<= 1;
if (next + 1 <= size && Heap[next + 1].cost < Heap[next].cost) ++next;
}
Heap[now] = curr;
}
inline void heap_ins(short int node, unsigned int cost){
Heap[++size].node = node;
Heap[size].cost = cost;
heap_elem curr = Heap[size];
short int now = size, next = now >> 1;
for (; next && Heap[next].cost > Heap[now].cost; Heap[now] = Heap[next], now = next, next >>= 1);
Heap[now] = curr;
}
void Dijkstra(char source_idx, int cnt){
memset(dist, 255, sizeof(int) * (N + 1));
dist[__K[(int)source_idx]] = 0;
heap_ins(__K[(int)source_idx], 0);
while (size){
heap_elem now = Heap[1];
heap_pop();
if (now.cost > dist[now.node]) continue;
foreach(G[now.node])
if (it->maxCnt >= cnt && dist[it->node] > now.cost + it->cost * (cnt + 1))
dist[it->node] = now.cost + it->cost * (cnt + 1),
heap_ins(it->node, now.cost + it->cost * (cnt + 1));
}
for (int i = 1; i <= K; ++i) pr_dist[(int)source_idx][i][cnt] = dist[__K[i]];
}
inline char bitcount(int x){
char cnt = 0;
for (; x; ++cnt, x -= x & -x);
return cnt;
}
int main(){
assert(freopen("gather.in", "r", stdin));
freopen("gather.out", "w", stdout);
K = r_int32(), N = r_int32(), M = r_int32();
__K[0] = 1;
for (int i = 1; i <= K; ++i) __K[i] = r_int32(), prisoner[__K[i]] = 1;
while (M--){
short int A, B;
unsigned int cost;
char cnt;
A = r_int32(), B = r_int32(), cost = r_int32(), cnt = r_int32();
if (cnt > K) cnt = K;
assert(cost >= 0);
G[A] = G[A]->new_edge(B, cnt, cost);
G[B] = G[B]->new_edge(A, cnt, cost);
}
for (int i = 0; i <= K; ++i)
memset(pr_dist[i], 255, sizeof (int) * (K + 1) * 16);
Dijkstra(0, 0);
for (int i = 1; i <= K; ++i)
for (int j = 1; j < K; ++j)
Dijkstra(i, j);
unsigned int ans = INF;
for (int i = 0; i < K; ++i)
memset(comb[i], 255, sizeof(int) * (1 << K));
for (int i = 1; i < (1 << K); ++i){
for (int j = 0; j < K; ++j)
if ((i & (1 << j))){
int x = i ^ (1 << j);
char bits = bitcount(i);
if (!x) comb[j][i] = pr_dist[0][j + 1][0];
else for (int k = 0; k < K; ++k)
if (x & (1 << k) && pr_dist[k + 1][j + 1][bits - 1] != INF && comb[k][x] != INF)
comb[j][i] = MIN(comb[j][i], comb[k][x] + pr_dist[k + 1][j + 1][bits - 1]);
if ((i == (1 << K) - 1) && comb[j][i] < ans)
ans = comb[j][i];
}
}
w_int32(ans);
return 0;
}