#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;
const int maxn = 1000010, inf = 1e9 + 233;
struct edge{int too, pre;}e[maxn << 1];

int n, m, tot;
int last[maxn];
char s[maxn];
bool vis[maxn];

inline void add(int x, int y) {e[++tot] = (edge){y, last[x]}; last[x] = tot;}

inline void ins(int x, int y) {add(x, y); add(y, x);}

void dfs(int x)
{
    vis[x] = 1;
    for (int i = last[x], too; i; i = e[i].pre)
        if (!vis[too = e[i].too])
            dfs(too);
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%s", s + 1);
        for (int j = 1; j <= m; j++)
            if (s[j] == '#')
                ins(i, j + n);
    }

    ins(1, 1 + n); ins(1, m + n);
    ins(n, 1 + n); ins(n, m + n);

    int ans1 = -1;
    for (int i = 1; i <= n; i++)
        if (!vis[i])
            dfs(i), ans1++;

    memset(vis, 0, sizeof(vis));

    int ans2 = -1;
    for (int i = n + 1; i <= n + m; i++)
        if (!vis[i])
            dfs(i), ans2++;

    printf("%d\n", min(ans1, ans2));
}

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
//#define cerr if(false) cerr
#ifdef DEBUG
#define show(...) cerr << #__VA_ARGS__ << " = ", debug(__VA_ARGS__);
#else
#define show(...) 42
#endif
using namespace std;
using ll = long long;
using pii = pair<int, int>;
template<typename T = int> using V = vector<T>;
template<typename T = int> using VV = vector<vector<T>>;
template <typename T, typename S>
ostream& operator<<(ostream& os, pair<T, S> a) {
    os << '(' << a.first << ',' << a.second << ')';
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, vector<T> v) {
    for (auto x : v) os << x << ' ';
    return os;
}
void debug() {
    cerr << '\n';
}
template <typename H, typename... T>
void debug(H a, T... b) {
    cerr << a;
    if (sizeof...(b)) cerr << ", ";
    debug(b...);
}
vector<int>g[200005];
int c[20];
int dp[1<<17][17];
vector<int>d[20];
int n;
void bfs(int s){
    int k = c[s];
    queue<int> q;
    q.push(k);
    vector<int>a(n, 1<<30);
    a[k] = 0;
    while(q.size()){
        int x = q.front();
        q.pop();
        for(int t:g[x]){
            if(a[t] == 1<<30){
                a[t] = a[x] + 1;
                q.push(t);
            }
        }
    }
    d[s] = a;
}
int main(){
    int m;
    cin >> n >> m;
    while(m--){
        int a, b;
        cin >> a >> b;
        a--;b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    int k;
    cin >> k;
    rep(i,k){
        cin >> c[i];
        c[i]--;
    }
    rep(i,k)bfs(i);
    rep(i,1<<k)rep(j,k)dp[i][j] = 1<<29;
    rep(i,k)dp[1<<i][i] = 1;
    rep(i,1<<k){
        rep(j,k){
            if(i >> j & 1){
                rep(l,k){
                    dp[i][j] = min(dp[i][j], dp[i^(1<<j)][l] + d[l][c[j]]);
                }
            }
        }
    }
    int ans = 1<<29;
    rep(j,k){
        ans = min(ans, dp[(1<<k)-1][j]);
    }
    if(ans == 1<<29)ans = -1;
    cout << ans << endl;
}
