#include "bits/stdc++.h"
using namespace std;

// GNU C Compiler
//template<class T> inline string toString(T x) { ostringstream sout; sout << x; return sout.str(); }

// type
using ll = int_fast64_t;
using ull = uint_fast64_t;
using LL = long long;
using ULL = unsigned long long;
using PII = pair<int, int>;
//using pair<T1, T2> = p12;

//container
#define PB emplace_back
#define MP make_pair 
#define SZ(a) int((a).size())
#define ALL(v) v.begin(),v.end()

//repetition
#define REP(n) for(int i=0; i<(n); i++)
#define REPj(n) for(int j=0; j<(n); j++)
#define REPinit(i,a,n) for(int i=(a); i<(n); i++)
#define REPinitj(j,a,n) for(int j=(a); j<(n); j++)

//algorithm
//#define SORT(c) sort((c).begin(),(c).end())

//constant

//clear memory
#define CLR(a) memset((a), 0 ,sizeof(a))

//Optimizer
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

/*
    add utility Algorithm
*/

struct UnionFind {
    // if par[x] = y, parent of x is y
    vector<int> par;
    vector<int> rank;
    vector<ll> Size;
    UnionFind(int n = 1) {
        init(n);
    }

    /*
        all of i equals to root, rank to zero, and size of tree to zero
    */
    void init(int n = 1) {
        par.resize(n + 1); rank.resize(n + 1); Size.resize(n + 1);
        for (int i = 0; i <= n; ++i) par[i] = i, rank[i] = 0, Size[i] = 1;
    }
    
    /*
        trace from x to the root recursively 
    */
    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        else {
            int r = root(par[x]);
            return par[x] = r;
        }
    }

    /*
        judge whether x and y both blong to the same tree
    */
    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    /*
        merge tree
    */
    bool merge(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        // adjust x rank higher than y
        if (rank[x] < rank[y]) swap(x, y);
        if (rank[x] == rank[y]) ++rank[x];
        // merge tree of y to tree of x
        par[y] = x;
        Size[x] += Size[y];
        return true;
    }

    /*
        get tree size
    */
    ll size(int x) {
        return Size[root(x)];
    }
};

int N, M, K;
int A[105000], B[105000], C[105000], D[105000];
int ans[105000];

int main(int argc, char const* argv[])
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, M, K;
    cin >> N >> M >> K;
    
    REPinit(i, 0, M) {
        cin >> A[i] >> B[i];
    }

    REPinit(i, 0, K) {
        cin >> C[i] >> D[i];
    }

    // 各ノードが根（深さ1, ノード数1の森）
    UnionFind uni(N + 1);
    for (int i = 1; i <= N; i++) ans[i] = 0;

    // union-find木を作っていく
    for (int i = 0; i < M; i++) {
        uni.merge(A[i], B[i]);
    }

    // 自分が属するunion-find木のサイズ（自分を含めない）
    for (int i = 1; i <= N; i++) {
        ans[i] = uni.size(uni.root(i)) - 1;
    }

    // 友達関係について
    // A[i], B[i]が同じ木に属す→A[i], B[i]は既に友達関係なので友達候補から除外
    for (int i = 0; i < M; i++) {
        if (!uni.issame(A[i], B[i])) continue;
        ans[A[i]]--;
        ans[B[i]]--;
    }

    // ブロック関係について
    // C[i], D[i]が同じ木に属す→C[i], D[i]は既にブロック関係なので友達候補から除外
    for (int i = 0; i < K; i++) {
        if (!uni.issame(C[i], D[i])) continue;
        ans[C[i]]--;
        ans[D[i]]--;
    }

    // 出力
    for (int i = 1; i <= N; i++) {
        if (i != 1) cout << " ";
        cout << ans[i];
    }
    cout << endl;

    return 0;
}


Measured memory_bytes: 4352