#include <time.h>

#include <stdlib.h>
#include <cstdint>
#include <cassert>
#include <algorithm>
#include <functional>
#include <iostream>
#include <limits>
#include <cstdint>
#include <cassert>
#include <algorithm>
#include <functional>
#include <iostream>
#include <limits>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <numeric>

using namespace std;

#include <cstdint>
#include <limits>
#include <vector>
#include <queue>
class Vertex;
class Edge{
	friend class Vertex;
	friend class Graph;
	Vertex* from;
	Vertex* to;
	int64_t cost;
public:
	Edge(Vertex* from,Vertex* to,int64_t cost=0){
		this->from=from;
		this->to=to;
		this->cost=cost;
	}

};
struct Dijkstra{
	int64_t d;
	Vertex* parent;
	bool searched;
};

class Vertex{
	friend class Graph;
	std::vector<Edge*> departure;
	std::vector<Edge*> arrival;

public:
	Dijkstra dijk_data;
	int32_t id;
	void add_edge(Edge* d){
		departure.push_back(d);
		d->to->arrival.push_back(d);
	}
	void initialize_Dijkstra(){
		dijk_data.d=std::numeric_limits<int64_t>::max();
		dijk_data.parent=NULL;
		dijk_data.searched=false;
		for(auto i=departure.begin();i!=departure.end();i++){
			Edge *temp=(*i);
			if(temp->to->dijk_data.d!=std::numeric_limits<int64_t>::max()||temp->to->dijk_data.parent!=NULL||temp->to->dijk_data.searched){
				temp->to->initialize_Dijkstra();
			}else{
			}
		}
	}
};
class dijkstra_calc{
public:
	int64_t current_cost;
	Vertex* from;
	Vertex* to;
	dijkstra_calc(const int64_t cost, Vertex* c1,Vertex* c2):current_cost(cost),from(c1),to(c2){

	}
};
bool operator<(const dijkstra_calc& a,const dijkstra_calc& b){
	return a.current_cost<b.current_cost;
}
bool operator>(const dijkstra_calc& a,const dijkstra_calc& b){
	return a.current_cost>b.current_cost;
}


class Graph{
private:
	std::vector<Vertex> v;
	std::vector<Edge> e;
	static void dijkstra(Vertex* source,Vertex* goal=NULL){
		std::priority_queue<dijkstra_calc,std::vector<dijkstra_calc>,std::greater<dijkstra_calc> > queue;
		queue.push(dijkstra_calc(0,NULL,source));
		while(true){
			const dijkstra_calc temp=queue.top();
			queue.pop();
			if(!(temp.to->dijk_data.searched)){
				temp.to->dijk_data.searched=true;
				temp.to->dijk_data.parent=temp.from;
				temp.to->dijk_data.d=temp.current_cost;

				for(auto i=temp.to->departure.begin();i!=temp.to->departure.end();i++){
					const Edge *j=(*i);
					if(!j->to->dijk_data.searched){
						dijkstra_calc a(temp.current_cost+(j->cost),j->from,j->to);
						queue.push(a);
					}
				}
				if(temp.to==goal){
					return;
				}
			}
			if(queue.empty()){
				return;
			}
		}
	}
public:
	Graph(int32_t num_v){
		v.resize(num_v);
		for(int32_t i1=0;i1<num_v;i1++){
			v.at(i1).id=i1;
		}
	}
	void add_edge(int32_t from,int32_t to,int32_t cost=0){
		Edge *temp=new Edge(&(v[from-1]),&(v[to-1]),cost);
		e.push_back(*temp);
		v[from-1].add_edge(temp);
	}
	void dijkstra(int32_t start){
		v[start-1].initialize_Dijkstra();
		dijkstra(&v[start-1]);
	}
	void dijkstra(int32_t start,int32_t goal){
		v[start-1].initialize_Dijkstra();
		dijkstra(&v[start-1],&v[goal-1]);
	}
	Vertex getVertex(int place) const{
		return v[place-1];
	}
};

int32_t ans=100000000;
int32_t R;
int32_t **cost;

int main() {
	int32_t N,M;
	cin>>N>>M>>R;
	Graph graph(N);
	vector<int32_t> visit;
	for(int32_t i1=0;i1<R;i1++){
		int32_t temp;
		cin>>temp;
		visit.push_back(temp);
	}
	for(int32_t i1=0;i1<M;i1++){
		int32_t from,to,cost;
		cin>>from>>to>>cost;
		graph.add_edge(from,to,cost);
		graph.add_edge(to,from,cost);
	}
	cost=new int32_t*[R];
	for(int i1=0;i1<R;i1++){
		cost[i1]=new int32_t[R];
	}
	for(int32_t i1=0;i1<R;i1++){

		graph.dijkstra(visit.at(i1));
		for(int32_t i2=0;i2<R;i2++){
			cost[i1][i2]=graph.getVertex(visit.at(i2)).dijk_data.d;
		}
	}

	vector<int32_t> a;
	for(int i=0;i<R;i++){
		a.push_back(i);
	}
	while(true){
		int64_t temp_sum=0;
		for(int i=0;i<R-1;i++){
			temp_sum+=cost[a.at(i)][a.at(i+1)];
		}
		if(temp_sum<ans){
			ans=temp_sum;
		}
		if(!next_permutation(a.begin(),a.end())){
			break;
		}
	}

	cout<<ans<<endl;

}

Measured memory_bytes: 4548