1.先把每个连通块变成一个完全图(不改变连通块数量)
2.将2个连通块合并最多可以连siz1*siz2条边(连通块少一个)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 5e5 + 10;
int n, m, q, y, p, e, cnt, a[N];
ll sum, h[N], x;
vector<int> v[N];
bool vis[N];
void dfs(int u) {
    vis[u] = 1;
    p++;
    for (auto i:v[u]) {
        e++;
        if (vis[i])continue;
        dfs(i);
    }
}
int main() {
    scanf("%d%d%d", &n, &m, &q);
    while (m--) {
        scanf("%d%d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for (int i = 1; i <= n; i++) {
        if (vis[i])continue;
        p = e = 0;
        dfs(i);
        e >>= 1;
        a[++cnt] = p;
        sum += (ll) p * (p - 1) / 2 - e;
    }
    sort(a + 1, a + 1 + cnt, greater<int>());
    int pre = 0;
    for (int i = 1; i < cnt; i++) {
        pre += a[i];
        h[i] = (ll) pre * a[i + 1];
    }
    for (int i = 1; i < cnt; i++)h[i] += h[i - 1];
    while (q--) {
        scanf("%lld", &x);
        if (x <= sum)printf("%d\n", cnt);
        else {
            x -= sum;
            int s = lower_bound(h + 1, h + cnt, x) - h;
            cout << max(1, cnt - s) << endl;
        }
    }
    return 0;
}