

#include <bits/stdc++.h>

#define loop(s, e, i) for (int i = s; i < e; ++i)
#define print(s) cout << s << endl;
#define DIV 1000000007
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int INF = 1e9+7;

ll ceildiv(ll a, ll b) { return (a+b-1)/b; } // 切り上げ
ll floordiv(ll a, ll b) { return a/b; } // 切り下げ

int show_matrix(vector<vector<ll>> &dp) {
  loop(0, dp.size(), i) {
    loop(0, dp[i].size(), j) {
      cout << dp[i][j] << " ";
    }
    cout << endl;
  }
  return 0;
}

struct Edge {
  ll from, to;
  ll cost;
  Edge() {};
  Edge(ll f, ll t, ll c) :from(f), to(t), cost(c) {};

  bool operator< (const Edge &e) {
    return cost < e.cost;
  }
};

struct Graph {
  vector<vector<Edge>> data;
  // Constructor
  Graph(ll v):data(v) {};

  void add_edge(Edge &e) {
    data[e.from].push_back(e);
  }

  void add_edge(ll from, ll to, ll cost) {
    data[from].emplace_back(from, to, cost);
  }

  size_t size() {
    return data.size();
  }
};

/* ダイクストラ法
*/
void dijkstra(vector<ll> &dist, Graph &g, ll s) {
  using state = pair<ll, ll>; // Pair of 'cost' and 'to'
  priority_queue<state, vector<state>, greater<state>> queue;
  dist.resize(g.size(), INF);
  // vector<ll> dist(g.size(), INF);
  dist[s] = 0;
  queue.push(state(0, s));

  while(!queue.empty()) {
    state p = queue.top(); queue.pop();
    ll v = p.second;
    if (dist[v] < p.first) continue;
    for (ll i=0; i<g.data[v].size(); i++) {
      Edge e = g.data[v][i];
      if (dist[e.to] > dist[v] + e.cost) {
        dist[e.to] = dist[v] + e.cost;
        queue.push(state(dist[e.to], e.to));
      }
    }
  }
}

/*
浮動小数点の入力
cout << fixed << setprecision(9) << endl;
*/

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  ll N, M;
  cin >> N >> M;

  Graph graph(N);

  loop(0, M, i) {
    ll a, b;
    cin >> a >> b;
    a--; b--;
    graph.add_edge(a, b, 1);
    graph.add_edge(b, a, 1);
  }
  ll K;
  cin >> K;
  vector<ll> C(K);
  loop(0, K, i) {
    cin >> C[i];
    C[i]--;
  }

  vector<vector<ll>> DIST(K, vector<ll>(K));
  loop(0, K, i) {
    vector<ll> dist;
    dijkstra(dist, graph, C[i]);
    loop(0, K, j) {
      ll to = C[j];
      DIST[i][j] = dist[to];
    }
  }


  vector<vector<ll>> DP((1<<K), vector<ll>(K, INF));

  loop(0, K, i) {
    DP[0][i] = 1;
  }

  for (ll bits=0; bits<(1<<K); bits++) {
    loop(0, K, i) {
      if (!(bits & (1 << i))) continue;
      loop(0, K, j) {
        ll bef = bits - (1 << i);
        DP[bits][j] = min(DP[bits][j], DP[bef][i] + DIST[i][j]);
      }
    }
  }

  ll result = INF;
  loop(0, K, i) {
    result = min(result, DP[(1<<K)-1][i]);
  }

  if (result == INF) {
    print(-1);
  } else {
    print(result);
  }
}

/*****************************
*  Author :: Πρασαννα Κ. Ροι  *
*****************************/

/***********************************
* Unus pro omnibus, omnes pro uno  *
***********************************/
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp> 
#include<ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
using namespace std;
using namespace std::chrono;

#define __AcHiLlEs ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __AnAkLuSmOs freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define int long long
#define span(a) begin(a), end(a)

template<typename t>
using vc = vector<t>;

vc<vc<int>> gph1;
vc<vc<int>> d, dp;
map<int, int> id;
int cnt(0);

void bfs(int u, int n) {
    queue<int> q;
    vc<int> dist(n + 1, -1);
    dist[u] = 0;
    q.push(u);
    while (!q.empty()){
        int v = q.front();
        q.pop();
        for (auto &i: gph1[v]) if (dist[i] == -1) {
            dist[i] = dist[v] + 1;
            q.push(i);
        }
    }
    for (int i = 1; i <= n; i++) if (id[i]) 
        d[id[u]][id[i]] = d[id[i]][id[u]] = dist[i];
}

int compute(int u, int vis, int k) {
    int res(1e18);
    if (vis == (1 << k) - 1) return 0;
    if (!dp[u][vis]) return (int)1e18;
    if (~dp[u][vis]) return dp[u][vis];

    dp[u][vis] = 0;
    for (int i = 0; i < k; i++) if (i + 1 != u)
        res = min(res, compute(i + 1, vis | (1 << i), k) + d[u][i + 1]);
    return dp[u][vis] = res;
}

void solve() {
    int n, m, x, y;
    cin >> n >> m;
    gph1.assign(n + 1, vc<int>());
    for (int i = 0; i < m; i++) cin >> x >> y, gph1[x].push_back(y), gph1[y].push_back(x);
    int k, cnt(0);
    cin >> k;
    vc<int> a(k);
    d.assign(k + 1, vc<int>(k + 1, -1));
    for (auto &i: a) cin >> i, id[i] = ++cnt;
    if (k == 1) return void(cout << 1 << "\n");
    for (auto &i: a) bfs(i, n);
    for (int i = 1; i <= k; i++) 
        for (int j = 1; j <= k; j++) if (d[i][j] == -1) return void(cout << -1 << "\n");
    dp.assign(k + 1, vc<int>(1 << k, -1));
    int res(LLONG_MAX);
    for(int i = 1; i <= k; i++) 
        res = min(res, compute(i, 1 << (i - 1), k));
    cout << res + 1 << "\n";
}

signed main() {
    // auto start = high_resolution_clock::now();

    __AcHiLlEs

    int t(1);
    // cin >> t;
    for (int i = 1; i <= t; /*cout << "Case " << i << ": ",*/ solve(), i++);
    // auto stop = high_resolution_clock::now();
    // double duration = duration_cast<microseconds>(stop - start).count();
    // cout << fixed << setprecision(4) << duration / 1000000 << "\n";  
    return 0;
}