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

typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> PL;
#define int ll

const ll MOD = 1000000007;
const ll INF_LL = (ll)1000000007 * 1000000007;
const int INF_INT = (int)1000000007;
const double PI = 3.14159265358979323846;

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define rrep(i, n) for (int i = ((int)(n)-1); i >= 0; i--)
#define irep(itr, st) for (auto itr = (st).begin(); itr != (st).end(); ++itr)
#define irrep(itr, st) for (auto itr = (st).rbegin(); itr != (st).rend(); ++itr)

#define m0(x) memset((x), 0, sizeof((x)))
#define m1(x) memset((x), -1, sizeof((x)))

// xにはvectorなどのコンテナ
#define ALL(x) (x).begin(), (x).end()  // sortなどの引数を省略したい
#define RALL(x) (x).rbegin(), (x).rend()  // sortなどの引数を省略したい
#define SIZE(x) ((ll)(x).size())     // sizeをsize_tからllに直しておく
#define MAX(x) *max_element(ALL(x))  //最大値を求める
#define MIN(x) *min_element(ALL(x))  //最小値を求める
#define all(x) (x).begin(), (x).end()

//略記
#define pb emplace_back  // vectorヘの挿入
#define mp make_pair     // pairのコンストラクタ
#define F first          // pairの一つ目の要素
#define S second         // pairの二つ目の要素

#define BITCOUNT __builtin_popcount
#define BITCOUNT_LL(x) __builtin_popcountll(x)

#define perm(c)             \
  sort(all(c));             \
  for (bool c##p = 1; c##p; \
       c##p = next_permutation(all(c)))  //順列 123 132 213 231 312 321

#define BIT(n) (1LL << (n))

#ifdef DEBUG
#define PRINT(A) std::cout << (#A) << ": " << (A) << std::endl;
#else
#define PRINT(A)
#endif

//入力高速化
struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

// Union-Find木(素集合データ構造) -
// グループ分けを木構造で管理する。任意の２要素が同じグループに所属するか判定する
// union by size + path having
class UnionFind {
 public:
  vector<ll> par;  // 各元の親を表す配列
  vector<ll> siz;  // 素集合のサイズを表す配列(1 で初期化)

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1LL) {
    for (ll i = 0; i < sz_; ++i) par[i] = i;  // 初期では親は自分自身
  }
  void init(ll sz_) {
    par.resize(sz_);
    siz.assign(sz_, 1LL);  // resize だとなぜか初期化されなかった
    for (ll i = 0; i < sz_; ++i) par[i] = i;  // 初期では親は自分自身
  }

  // Member Function
  // Find
  ll root(ll x) {  // 根の検索
    while (par[x] != x) {
      x = par[x] = par[par[x]];  // x の親の親を x の親とする
    }
    return x;
  }

  // Union(Unite, Merge)
  bool unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    // merge technique（データ構造をマージするテク．小を大にくっつける）
    if (siz[x] < siz[y]) swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool same(ll x, ll y) {  // 連結判定
    return root(x) == root(y);
  }

  ll size(ll x) {  // 素集合のサイズ
    return siz[root(x)];
  }
};

signed main() {
  int N, M, K;
  cin >> N >> M >> K;

  UnionFind uf(N);

  vector<vector<int>> fr(N);

  rep(i, M) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    uf.unite(a, b);
    fr[a].pb(b);
    fr[b].pb(a);
  }

  vector<vector<int>> hate(N);

  rep(i, K) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    hate[a].pb(b);
    hate[b].pb(a);
  }

  rep(i, N) {
    PRINT(i + 1)
    int ans = uf.size(i);
    PRINT(ans)
    for (auto v : hate[i]) {
      if (uf.same(i, v)) {
        PRINT(v + 1)
        ans--;
      }
    }
    for (auto v : fr[i]) {
      if (uf.same(i, v)) {
        PRINT(v + 1)
        ans--;
      }
    }
    ans--;
    ans = max(0ll, ans);
    cout << ans << " ";
  }
  cout << endl;
}

Measured memory_bytes: 14580