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

// int/long:		-2,147,483,648 - 2,147,483,647 (-2^31 <= int < 2^31)
// long/long long:	-9,223,372,036,854,775,808 - 9,223,372,036,854,775,807 (-2^63 <= long < 2^63)

// lower_bound(A.begin(), A.end(), N)
// upper_bound(...

// A.erase(unique(A.begin(), A.end()), A.end())

// bit: &/and, |/or, ^/xor, ~/not

// getline(cin, String)
// while (getline(cin, S)) {}

// cout <<fixed <<setprecision(10)

// priority_queue<int> q;
// priority_queue<int, vector<int>, less<int>> q; // Default: vector, less
// priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> q;

// Graph
// Warshall-Floyd: Distance between each node, N^3
// Dijkstra: Distance from the start node, N^2
// DFS(Depth-First Search)

//
// Notes
//
// When specified less than N, try full scan.
// RE: empty vector
// Check Qs
// long/int
// xor -> count each bit
// Check values
// 	1,000,000 -> Loop
// 	100,000	-> vector(int:400KB, long:800KB) 

#define	INF (1<<30)
//1,073,741,824
//= 536,870,912 *2

#define	MOD 1000000007

#define	Rep0(i, n)	for (int i=0; i<n; i++)
#define	Rep1(i, n)	for (int i=1; i<=n; i++)
#define Sort(P)	sort(P.begin(), P.end())
#define Rev(P)	reverse(P.begin(), P.end())

int	get_g(int i, vector<int> &grp) {
	if (i==grp.at(i)) return i;
	return get_g(grp.at(i), grp);
}

int     main() {
	// N: Number of nodes
	// M: Number of links
	int N, M, K;
	cin >>N >>M >>K;
	// Data store
	// grp: Group#
	// grp_depth: Steps to the group root
	vector<int> grp(N+1, 0);
	vector<int> grp_depth(N+1, 0);
	// Read data for each node
	// Initialize group# as each own
	for (int i=1; i<=N; i++)
		grp.at(i)=i;
	// Links
	// Each link connects nodes x and y
	// (Swap rules)
	vector<int> C(N+1, 0);
	vector<int> x(M, 0);
	vector<int> y(M, 0);
	for (int i=0; i<M; i++) {
		cin >>x.at(i) >>y.at(i);
		C.at(x.at(i))++;
		C.at(y.at(i))++;
	}
	// Grouping
	for (int i=0; i<M; i++) {
		int xx=x.at(i);
		int yy=y.at(i);
		xx=get_g(xx, grp);
		yy=get_g(yy, grp);
		// Already in same group, do nothing
		if (xx==yy) continue;
		// Put into one group
		if (grp_depth.at(xx)==grp_depth.at(yy)) {
			// Groups have same height
			// Merge into less-number-group
			grp.at(max(xx, yy)) = get_g(min(xx, yy), grp);
			grp_depth.at(min(xx, yy))++;
		} else if (grp_depth.at(xx)>grp_depth.at(yy)) {
			// x is higher
			// Merge into x so that the hight will not increase
			// (height for y will be +1)
			grp.at(yy) = xx;
		} else
			// y is higher
			// Merget into y
			grp.at(xx) = yy;
	}
	vector<vector<int>> B(N+1);
	Rep0(i, K) {
		int a, b;
		cin >>a >>b;
		B.at(a).push_back(b);
		B.at(b).push_back(a);
	}
	Rep1(i, N)
		Sort(B.at(i));
	vector<vector<int>> G(N+1);
	Rep1(i, N)
		G.at(get_g(i, grp)).push_back(i);
	/*
	Rep1(i, N) {
		int g=get_g(i, grp);
		int S=0;
		int ix=0;
		int ig=0;
		while(ig<G.at(g).size()) {
			if (ix==B.at(i).size()) { // No more Blcok
				S++;
				ig++;
			} else if (B.at(i).at(ix)==G.at(g).at(ig)) { // Skip Block
				ix++;
				ig++;
			} else { // OK
				S++;
				if (B.at(i).at(ix)<G.at(g).at(ig))
					ix++;
				ig++;
			}
		}
		cout <<S-C.at(i)-1 <<' ';
	}
	*/
	vector<int> CC(N+1, 0);
	Rep1(i, N) {
		int g=get_g(i, grp);
		CC.at(i)=G.at(g).size()-1;
		Rep0(j, B.at(i).size())
			if (g==get_g(B.at(i).at(j), grp))
				CC.at(i)--;
		cout <<CC.at(i)-C.at(i) <<' ';
	}
	cout <<endl;
	return 0;
};


Measured memory_bytes: 11904