#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 150300
#define M 301300
#define INF 0x3f3f3f3f
int A[N],B[N],C[N],fa[N],tag[N],que[N],dis[N],n,D[20][20],f[20][N],vis[N];
struct node{
	int to,next;
}q[M];
int head[N],ss;
void addedge(int x,int y)
{
	q[++ss]=(node){y,head[x]};head[x]=ss;
	q[++ss]=(node){x,head[y]};head[y]=ss;
}
void dij(int S)
{
	int f=1,e=0;
	que[++e]=S;
	for (int i=1;i<=n;++i) vis[i]=0,dis[i]=INF;
	dis[S]=0;
	vis[S]=true;
	while(f<=e)
	{
		int u=que[f++];
		for (int j=head[u];j;j=q[j].next)
		{
			int t=q[j].to;
			if (vis[t]) continue;
			que[++e]=t;
			dis[t]=dis[u]+1;
			vis[t]=true;
		}
	}
}
int main()
{
	int m,k,ans=INF;
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;++i) scanf("%d%d",&A[i],&B[i]),addedge(A[i],B[i]);
	scanf("%d",&k);
	for (int i=1;i<=k;++i) scanf("%d",&C[i]),tag[C[i]]=i;
	for (int i=1;i<=k;++i)
	{
		dij(C[i]);
		for (int j=1;j<=k;++j) D[i][j]=dis[C[j]];
	}
	memset(f,0x3f,sizeof(f));
	for (int i=1;i<=k;++i) f[i][1<<i-1]=0;
	for (int S=0;S<(1<<k);++S)
	{
		for (int i=1;i<=k;++i)
		{
			if (f[i][S]==INF) continue;
			for (int j=1;j<=k;++j)
			{
				if (i==j||S&(1<<j-1)) continue;
				f[j][S|(1<<j-1)]=min(f[j][S|(1<<j-1)],f[i][S]+D[i][j]);
			}
		}
	}
	for (int i=1;i<=k;++i) ans=min(ans,f[i][(1<<k)-1]);
	printf("%d",ans==INF?-1:ans+1);
	return 0;
}

//by qlwpc
#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
using ld = long double;
using P = pair<ll, ll>;
using Vec = vector<ll>;
using VecP = vector<P>;
template <class T>
using Vec2 = vector<vector<T>>;
#define REP(i, m, n) for(ll i = (m); i < (n); ++i)
#define REPN(i, m, n) for(ll i = (m); i <= (n); ++i)
#define REPR(i, m, n) for(ll i = (m)-1; i >= (n); --i)
#define REPNR(i, m, n) for(ll i = (m); i >= (n); --i)
#define rep(i, n) REP(i, 0, n)
#define repn(i, n) REPN(i, 1, n)
#define repr(i, n) REPR(i, n, 0)
#define repnr(i, n) REPNR(i, n, 1)
#define all(s) (s).begin(), (s).end()
template <class T1, class T2>
bool chmax(T1 &a, const T2 b) { return a < b ? a = b, true : false; }
template <class T1, class T2>
bool chmin(T1 &a, const T2 b) { return a > b ? a = b, true : false; }
template <class T>
istream &operator>>(istream &is, vector<T> &v) { for (T &i : v) is >> i; return is; }
template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) { for (const T &i : v) os << i << ' '; return os; }
void _co() { cout << '\n'; }
template <class Head, class... Tail>
void _co(Head&& head, Tail&&... tail) { cout << ' ' << head; _co(forward<Tail>(tail)...); }
template <class Head, class... Tail>
void co(Head&& head, Tail&&... tail) { cout << head; _co(forward<Tail>(tail)...); }
void ce() { cerr << '\n'; }
template <class Head, class... Tail>
void ce(Head&& head, Tail&&... tail) { cerr << head << ' '; ce(forward<Tail>(tail)...); }
void sonic() { ios::sync_with_stdio(false); cin.tie(nullptr); }
void setp(const int n) { cout << fixed << setprecision(n); }
constexpr int64_t LINF = 1000000000000000001;
constexpr int64_t MOD = 1000000007;
constexpr int64_t MOD_N = 998244353;
constexpr long double EPS = 1e-11;
const double PI = acos(-1);

template <class T>
struct Graph {
    struct edge {
        int64_t from, to;
        T dist;

        bool operator<(const edge &rhs) const { return dist < rhs.dist; }

        bool operator>(const edge &rhs) const { return dist > rhs.dist; }

        edge &operator+=(const edge &rhs) {
            to = rhs.to;
            dist += rhs.dist;
            return *this;
        }
        edge operator+(const edge &rhs) { return edge(*this) += rhs; }
    };

    int64_t V;
    vector<T> dist;
    vector<vector<edge>> edges;

    Graph() {}
    Graph(int64_t v) : V(v) {
        edges = vector<vector<edge>>(V);
        dist = vector<T>(V, LINF);
    }

    void add_edge(int64_t a, int64_t b, T d = 1, bool is_dual = false) {
        edges[a].push_back(edge{a, b, d});
        if (is_dual) edges[b].push_back(edge{b, a, d});
    }

    void dijkstra(int64_t s) {
        dist.assign(V, LINF);
        priority_queue<edge, vector<edge>, greater<edge>> p_que;
        p_que.push(edge{s, s, T()});
        while (!p_que.empty()) {
            edge e = p_que.top();
            p_que.pop();
            if (e.dist >= dist[e.to]) continue;
            dist[e.to] = e.dist;
            for (auto i : edges[e.to]) p_que.push(e + i);
        }
    }
};

int main(void) {
    ll n, m;
    cin >> n >> m;
    Graph<ll> g(n);
    rep(i, m) {
        ll a, b;
        cin >> a >> b;
        g.add_edge(a - 1, b - 1, 1, true);
    }

    ll k;
    cin >> k;
    Vec c(k);
    cin >> c;

    vector<Graph<ll>> gs(k);
    rep(i, k) gs[i] = g;
    rep(i, k) gs[i].dijkstra(c[i] - 1);

    Vec2<ll> dp(1 << k, Vec(k, LINF));
    rep(i, k) {
        dp[1 << i][i] = 1;
    }

    rep(i, 1 << k) {
        rep(j, k) {
            rep(l, k) {
                if (!(i >> j & 1) || (i >> l & 1))
                    continue;
                chmin(dp[i | 1 << l][l], dp[i][j] + gs[j].dist[c[l] - 1]);
            }
        }
    }

    ll ans = LINF;
    rep(i, k) chmin(ans, dp[(1 << k) - 1][i]);
    if (ans == LINF)
        ans = -1;
    co(ans);

    return 0;
}