#include <bits/stdc++.h>
using namespace std;
// Problem: Graph with n nodes and m edges
// k nodes are "special" - cannot add edges between special nodes
// Find maximum edges we can add without connecting special nodes
struct DSU {
vector<int> p; // parent array
vector<int> sz; // size of each component
DSU(int n = 0) {
init(n);
}
void init(int n) {
p.resize(n + 1);
sz.assign(n + 1, 1);
iota(p.begin(), p.end(), 0); // each node is its own parent initially
}
// Find root of node u with path compression
int find(int u) {
while (p[u] != u) {
p[u] = p[p[u]]; // compress path
u = p[u];
}
return u;
}
// Merge two components using union by size
void merge(int u, int v) {
u = find(u);
v = find(v);
if (u == v) return;
if (sz[u] < sz[v]) swap(u, v); // make u the larger component
p[v] = u;
sz[u] += sz[v];
}
};
class Solution {
public:
long long maxEdgesToAdd(int n, vector<array<int, 2>>& e, vector<int>& sp) {
// Build connected components from existing edges
DSU d(n);
for (auto& x : e) {
d.merge(x[0], x[1]);
}
// Mark which components contain special nodes
// (components inherit "special" property from their nodes)
vector<bool> isSp(n + 1, false);
for (int x : sp) {
isSp[d.find(x)] = true;
}
// Collect all component roots
vector<int> comp;
for (int i = 1; i <= n; i++) {
if (d.find(i) == i) {
comp.push_back(i);
}
}
// Max edges in a complete graph of k nodes: k*(k-1)/2
auto maxE = [](long long k) {
return k * (k - 1) / 2;
};
// If no special nodes, merge everything into one complete graph
if (sp.empty()) {
return maxE(n) - (long long)e.size();
}
// Find size of largest special component and total non-special nodes
long long maxSp = 0;
long long totNonSp = 0;
for (int r : comp) {
long long s = d.sz[r];
if (isSp[r]) {
maxSp = max(maxSp, s);
} else {
totNonSp += s;
}
}
// Greedy strategy:
// - Merge ALL non-special components with the LARGEST special component
// (this maximizes edges since we create one big component)
// - Keep other special components isolated (can't connect them anyway)
long long maxPos = 0;
// Count edges in the merged super-component
// (largest special component + all non-special nodes)
maxPos += maxE(maxSp + totNonSp);
// Add edges within other special components (they stay separate)
bool skip = false;
for (int r : comp) {
if (!isSp[r]) continue;
long long s = d.sz[r];
// Skip the largest special component (already counted above)
if (s == maxSp && !skip) {
skip = true;
continue;
}
// Each remaining special component forms its own complete graph
maxPos += maxE(s);
}
// Answer = max possible edges - edges already present
return maxPos - (long long)e.size();
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, k;
cin >> n >> m >> k;
// Input: m edges
vector<array<int, 2>> e(m);
for (int i = 0; i < m; i++) {
cin >> e[i][0] >> e[i][1];
}
// Input: k special nodes
vector<int> sp(k);
for (int i = 0; i < k; i++) {
cin >> sp[i];
}
Solution sol;
cout << sol.maxEdgesToAdd(n, e, sp) << "\n";
return 0;
}