// #include {{{
#include <array>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <numeric>
#include <functional>
#include <iterator>
#include <tuple>
#include <utility>
#include <random>
#include <limits>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdint>
#include <cassert>
// }}}

using namespace std;

// macros {{{
template<typename T, size_t N>
constexpr size_t NELEMS(T (&)[N]) { return N; }

template<typename InputIt>
void PRINT_RANGE(InputIt first, InputIt last)
{
    for(; first != last; ++first)
        cout << *first << (first==last ? "" : " ");
    cout << "\n";
}

template<typename T>
void PRINT_MATRIX(T mat, size_t nr, size_t nc)
{
    for(size_t r = 0; r < nr; ++r) {
        for(size_t c = 0; c < nc; ++c) {
            cout << mat[r][c] << (c==nc-1 ? "" : " ");
        }
        cout << "\n";
    }
}

#define FOR(i, start, end) for(int i = (start); i < (end); ++i)
#define REP(i, n) FOR(i, 0, n)
// }}}

// types {{{
using ll  = long long;
using ull = unsigned long long;
// }}}

constexpr int INF = numeric_limits<int>::max();

struct Edge {
    int to;
    int cost;
    Edge(int to_arg, int cost_arg) : to(to_arg), cost(cost_arg) {}
};

struct Node {
    int v;
    int cost;
    Node(int v_arg, int cost_arg) : v(v_arg), cost(cost_arg) {}
};

struct NodeGreater {
    bool operator()(const Node& lhs, const Node& rhs) const
    {
        return lhs.cost > rhs.cost;
    }
};

int N;
int M;
int R;
vector<int> RS;
vector<Edge> G[200];

void dijkstra(int start, vector<int>& cost)
{
    deque<bool> done(N);
    priority_queue<Node, vector<Node>, NodeGreater> que;

    fill(begin(cost), end(cost), INF);
    cost[start] = 0;
    que.push(Node(start, 0));

    while(!que.empty()) {
        Node minnode = que.top(); que.pop();
        int minv     = minnode.v;
        int mincost  = minnode.cost;
        done[minv] = true;

        if(cost[minv] < mincost) continue;

        for(Edge e : G[minv]) {
            if(done[e.to]) continue;
            int cost_new = cost[minv] + e.cost;
            if(cost_new < cost[e.to]) {
                cost[e.to] = cost_new;
                que.push(Node(e.to, cost_new));
            }
        }
    }
}

void solve()
{
    vector<vector<int>> costs(R);
    for(auto& cost : costs) {
        cost.resize(N);
    }

    REP(i, R) {
        int start = RS[i];
        vector<int>& cost = costs[i];
        dijkstra(start, cost);
#ifdef DEBUG
        PRINT_RANGE(begin(cost), end(cost));
#endif
    }

    vector<int> indices(R);
    iota(begin(indices), end(indices), 0);
    int cost_total_min = INF;
    do {
        int cost_total = 0;
        REP(i, R-1) {
            //int from = RS[indices[i]];
            int to   = RS[indices[i+1]];
            vector<int>& cost = costs[indices[i]];
            cost_total += cost[to];
        }
        if(cost_total < cost_total_min) {
            cost_total_min = cost_total;
        }
    } while(next_permutation(begin(indices), end(indices)));

    cout << cost_total_min << "\n";
}

int main()
{
    cin >> N;
    cin >> M;
    cin >> R;

    RS.resize(R);
    REP(i, R) {
        cin >> RS[i];
        --RS[i];
    }

    REP(_, M) {
        int a, b, c;
        cin >> a >> b >> c;
        --a;
        --b;

        G[a].emplace_back(b, c);
        G[b].emplace_back(a, c);
    }

    solve();

    return 0;
}


Measured memory_bytes: 768