use std::io;
use std::cmp;
use std::cmp::Ordering;
use std::collections::BinaryHeap;

// read a line(without line feed)
fn read_line() -> String {
    let mut in_str = String::new();
    io::stdin().read_line(&mut in_str).unwrap();
    return in_str.trim().to_string();
}

// read wods on a line
pub fn read_words_in_line() -> Vec<String> {
    let s = read_line();
    return s.split_whitespace().map(|x| x.to_string()).collect::<Vec<String>>()
}

// read type t on a line
pub fn read_t_in_line<T : std::str::FromStr>() -> Vec<T> {
    let mut v : Vec<T> = Vec::new();
    for e in read_words_in_line().iter().map(|x| x.parse::<T>()) {
        if let Ok(r) = e {
            v.push(r);
        }
        else{
            return Vec::new();
        }
    }
    return v;
}

// sort slice
pub fn sort<T : std::cmp::Ord>(slice : &mut [T]) {
    slice.sort();
}
// sort slice by reverse order
pub fn sort_rev<T : std::cmp::Ord>(slice : &mut [T]) {
    slice.sort_by(|x, y| y.cmp(x));
}

pub fn min<T : std::cmp::Ord>(a : T, b : T) -> T{
    return cmp::min(a, b);
}

pub fn max<T : std::cmp::Ord>(a : T, b : T) -> T{
    return cmp::max(a, b);
}

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
struct State {
    cost     : i32,
    node     : i32,
    vismask  : i32
}

impl Ord for State {
    fn cmp(&self, other: &State) -> Ordering {
        other.cost.cmp(&self.cost)
    }
}

impl PartialOrd for State {
    fn partial_cmp(&self, other : &State) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}


fn main() {

    let n_m_r = read_t_in_line::<i32>();
    let (n, m, r) = (n_m_r[0], n_m_r[1], n_m_r[2]);
    let towns : Vec<_> = read_t_in_line::<i32>().iter().map(|x| x - 1).collect();
    let mut g = vec![vec![] ; n as usize];

    for _ in 0..m {
        let a_b_c = read_t_in_line::<i32>();
        let f = a_b_c[0] - 1;
        let t = a_b_c[1] - 1;
        let c = a_b_c[2];
        g[f as usize].push((t, c));
        g[t as usize].push((f, c));
    }
    
    
    let mut dist : Vec<Vec<_>> = vec![(0..(1 << r)).map(|_| i32::max_value()).collect() ; n as usize];
    let mut pq = BinaryHeap::new();


    for i in 0..n {
        let mut vis = 0;
        for j in 0..r {
            let town = towns[j as usize];
            if town == i {
                vis |= 1 << j;
                break;
            }
        }
        dist[i as usize][vis] = 0;
        pq.push(State{cost : 0, node : i, vismask : vis as i32} );
    }

    
    while let Some(State{cost, node, vismask}) = pq.pop() {
        if cost > dist[node as usize][vismask as usize] {
            continue;
        }

        // println!("*");
        // println!("{} {} {}", cost, node, vismask);

        for &(nnode, rcost) in &g[node as usize] {
            let mut nvismask = vismask;
            for j in 0..r {
                let town = towns[j as usize];
                if town == nnode {
                    nvismask |= 1 << j;
                    break;
                }
            }
            // println!("{} {} {}", rcost+cost, nnode, nvismask);

            let nstate = State{cost : rcost + cost, node : nnode, vismask : nvismask};

            if nstate.cost < dist[nnode as usize][nvismask as usize] {
                dist[nnode as usize][nvismask as usize] = nstate.cost;
                pq.push(nstate);
            }
        }
    }
    
    let mut res = i32::max_value();
    // すべてのtownを通過したものから、最短の距離のものを求める
    for i in 0..n {
        let last_vis = (1 << r) - 1;
        let d = dist[i as usize][last_vis as usize];
        res = cmp::min(res, d);
    }
    println!("{}", res);
}


Measured memory_bytes: 8444