/*
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
#deFe nod first.first
#deFe cost first.second
#deFe nbr second
#deFe val first
#deFe 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 <fstream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
class Triple
{ public: int p1, p2, p3; Triple();
Triple(int _p1, int _p2, int _p3)
{ p1 = _p1; p2 = _p2; p3 = _p3; }
};
typedef pair<int,int> Pair;
#define push_Triple(deFe1, deFe2, deFe3) push_back(Triple(deFe1, deFe2, deFe3))
#define insert_pair(deFe1, deFe2) insert(make_pair(deFe1, deFe2))
const int oo = 0x3f3f3f3f;
int I[16], Drum[1 << 15][16];
int D[16][16][755], Lg[1 << 15];
vector<Triple> V[755];
int N, M, K;
set< Pair > S;
int main()
{
ifstream F("gather.in");
ofstream G("gather.out");
Lg[1] = 1;
for (int i = 2; i < (1 << 15); ++i)
Lg[i] = Lg[i >> 1] + 1;
F >> K >> N >> M;
for (int i = 1; i <= K; ++i)
F >> I[i];
for (int i = 1, nod1, nod2, maxp, cost; i <= M; ++i)
{
F >> nod1 >> nod2 >> cost >> maxp;
V[nod1].push_Triple(nod2, cost, maxp);
V[nod2].push_Triple(nod1, cost, maxp);
}
for (int i = 1; i <= K; ++i)
for (int k = 0; k <= K; ++k)
{
for (int j = 1; j <= N; ++j)
if (j != I[i])
D[i][k][j] = oo;
for (vector<Triple>::iterator it = V[I[i]].begin(); it != V[I[i]].end(); ++it)
if (k <= it->p3)
D[i][k][it->p1] = it->p2;
for (int j = 1; j <= N; ++j)
if (j != I[i])
S.insert_pair(D[i][k][j], j);
while (!S.empty())
{
Pair now = *S.begin();
S.erase(S.begin());
if (now.first > D[i][k][now.second]) continue;
for (vector<Triple>::iterator it = V[now.second].begin(); it != V[now.second].end(); ++it)
if (k <= it->p3)
if (D[i][k][now.second] + it->p2 < D[i][k][it->p1])
{
D[i][k][it->p1] = D[i][k][now.second] + it->p2;
S.insert_pair(D[i][k][it->p1], it->p1);
}
}
}
for (int i = 1; i < (1 << K); ++i)
{
int nrB = 0, aux = i;
while (aux)
++nrB, aux &= aux - 1;;
aux = i;
while (aux)
{
int last = aux & -aux, aux2 = i ^ last;
Drum[i][Lg[last]] = oo;
if (aux2 == 0)
Drum[i][Lg[last]] = D[Lg[last]][0][1];
while (aux2)
{
int last2 = aux2 & -aux2;
if (D[Lg[last]][nrB - 1][I[Lg[last2]]] != oo)
Drum[i][Lg[last]] = min(Drum[i][Lg[last]], Drum[i ^ last][Lg[last2]] + nrB * D[Lg[last]][nrB - 1][I[Lg[last2]]]);
aux2 &= aux2 - 1;
}
aux &= aux - 1;
}
}
int result = oo;
for (int i = 1; i <= K; ++i)
result = min(result, Drum[(1 << K) - 1][i]);
G << result;
F.close();
G.close();
}