#include <stdio.h>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <numeric>
#include <complex>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <cassert>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
const double EPS = 1e-9;
typedef vector<int> vint;
typedef vector<vector<int>> v2int;
typedef vector<ll> vll;
typedef vector<vector<ll>> v2ll;
typedef list<int> liint;
typedef pair<int, int> pint;
const int INF = int(2e9);
const ll LINF = ll(2e9) * ll(2e9);
#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << #a << " " << a << endl;
#define REP(i, x, n) for(int i = x; i < n; i++)
template<class T, class C> void chmax(T& a, C b) { a > b ? : a = b; }
template<class T, class C> void chmin(T& a, C b) { a < b ? : a = b; }

class union_find
{
private:
    std::vector<int> parent;
    std::vector<int> rank;
    vll size;
    int node_num;
public:
    union_find(int node_num);
    void unite(int x, int y);
    int find(int x);
    ll get_size(int x);
};

union_find::union_find(int node_num) :
    parent(node_num + 1, 0),
    rank(node_num + 1, 0),
    node_num(node_num),
    size(node_num + 1, 1)
{
    for (int i = 0; i <= node_num; i++) {
        parent[i] = i;
    }
}

void union_find::unite(int x, int y) {
    int x_root = find(x);
    int y_root = find(y);
    //既に同じ根なら、同じ所属なので何もしない
    if (x_root == y_root) return;
    //ランクが大きい方に小さい方をくっつける
    //結合後のランクは大きい方になる。
    if (rank[x_root] > rank[y_root]) {
        parent[y_root] = x_root;
        size[x_root] += size[y_root];
    }
    else {
        parent[x_root] = y_root;
        if (rank[x_root] == rank[y_root]) {
            //ランクが等しい場合は、必ずランクが1上がる。
            rank[y_root]++;
        }
        size[y_root] += size[x_root];
    }
}
ll union_find::get_size(int x) {
    return size[find(x)];
}
int union_find::find(int x) {
    if (x != parent[x]) {
        // findの結果を各parentに入れることで経路を圧縮。
        //ただし、変更コストが大きいのでランクは変えてない。
        parent[x] = find(parent[x]);
    }
    return parent[x];
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int N, M, K;
    cin >> N >> M >> K;

    unordered_map<int, unordered_set<int>> graph;
    union_find uf(N);
    vint a(M), b(M);
    rep(i, M) {
        cin >> a[i] >> b[i];
        uf.unite(a[i], b[i]);
    }
    //unordered_map<int, unordered_set<int>> block;
    //rep(i, K) {
    //    int c, d;
    //    cin >> c >> d;
    //    graph[c].insert(d);
    //    graph[d].insert(c);
    //}

    vll ans(N + 1, 0);
    REP(i, 1, N + 1) {
        ans[i] =uf.get_size(i) - 1;
    }

    rep(i, M) {
        ans[a[i]]--;
        ans[b[i]]--; 
    }

    rep(i, K) {
        int c, d;
        cin >> c >> d;
        if (uf.find(c) == uf.find(d)) {
            ans[c] = max(0LL, ans[c] - 1);
            ans[d] = max(0LL, ans[d] - 1);
        }
    }
    REP(i, 1, N + 1) {
        cout << ans[i] << " ";
    }
    cout << endl;
    return 0;
}

Measured memory_bytes: 3968