An SNS has N users - User 1, User 2, \cdots, User N.
Between these N users, there are some relationships - M friendships and K blockships.
For each i = 1, 2, \cdots, M, there is a bidirectional friendship between User A_i and User B_i.
For each i = 1, 2, \cdots, K, there is a bidirectional blockship between User C_i and User D_i.
We define User a to be a friend candidate for User b when all of the following four conditions are satisfied:
 - a \neq b.
 - There is not a friendship between User a and User b.
 - There is not a blockship between User a and User b.
 - There exists a sequence c_0, c_1, c_2, \cdots, c_L consisting of integers between 1 and N (inclusive) such that c_0 = a, c_L = b, and there is a friendship between User c_i and c_{i+1} for each i = 0, 1, \cdots, L - 1.
For each user i = 1, 2, ... N, how many friend candidates does it have?

-----Constraints-----
 - All values in input are integers.
 - 2 ≤ N ≤ 10^5
 - 0 \leq M \leq 10^5
 - 0 \leq K \leq 10^5
 - 1 \leq A_i, B_i \leq N
 - A_i \neq B_i
 - 1 \leq C_i, D_i \leq N
 - C_i \neq D_i
 - (A_i, B_i) \neq (A_j, B_j) (i \neq j)
 - (A_i, B_i) \neq (B_j, A_j)
 - (C_i, D_i) \neq (C_j, D_j) (i \neq j)
 - (C_i, D_i) \neq (D_j, C_j)
 - (A_i, B_i) \neq (C_j, D_j)
 - (A_i, B_i) \neq (D_j, C_j)

-----Input-----
Input is given from Standard Input in the following format:
N M K
A_1 B_1
\vdots
A_M B_M
C_1 D_1
\vdots
C_K D_K

-----Output-----
Print the answers in order, with space in between.

-----Sample Input-----
4 4 1
2 1
1 3
3 2
3 4
4 1

-----Sample Output-----
0 1 0 1

There is a friendship between User 2 and 3, and between 3 and 4. Also, there is no friendship or blockship between User 2 and 4. Thus, User 4 is a friend candidate for User 2.
However, neither User 1 or 3 is a friend candidate for User 2, so User 2 has one friend candidate.

Difficulty: MEDIUM

Solutions:
import sys
sys.setrecursionlimit(10 ** 6)
(N, M, K) = map(int, input().split())
par = [i for i in range(N + 1)]

def root(x):
	if par[x] == x:
		return x
	else:
		par[x] = root(par[x])
		return par[x]

def bool_same(x, y):
	return root(x) == root(y)

def unite(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		par[x] = y
AB = [list(map(int, input().split())) for i in range(M)]
CD = [list(map(int, input().split())) for i in range(K)]
for (a, b) in AB:
	unite(a, b)
for i in range(N + 1):
	root(i)
member = [0 for i in range(N + 1)]
for p in par:
	member[p] += 1
ans = [member[par[i]] - 1 for i in range(N + 1)]
for (a, b) in AB:
	if bool_same(a, b):
		ans[a] -= 1
		ans[b] -= 1
for (c, d) in CD:
	if bool_same(c, d):
		ans[c] -= 1
		ans[d] -= 1
print(' '.join(map(str, ans[1:])))


(n, m, k) = map(int, input().split())
import sys
sys.setrecursionlimit(10 ** 9)
root = [-1 for i in range(n + 1)]

def r(x):
	if root[x] < 0:
		return x
	else:
		root[x] = r(root[x])
		return root[x]

def unite(x, y):
	x = r(x)
	y = r(y)
	if x == y:
		return
	if x > y:
		(x, y) = (y, x)
	root[x] += root[y]
	root[y] = x
fre = [[] for _ in range(n + 1)]
bro = [[] for _ in range(n + 1)]
for i in range(m):
	(a, b) = map(int, input().split())
	unite(a, b)
	fre[a].append(b)
	fre[b].append(a)
for i in range(k):
	(a, b) = map(int, input().split())
	bro[a].append(b)
	bro[b].append(a)
ans = []
for i in range(1, n + 1):
	anser = -root[r(i)] - 1
	anser -= len(fre[i])
	for j in bro[i]:
		if r(i) == r(j):
			anser -= 1
	ans.append(str(anser))
print(' '.join(ans))


import collections, sys
sys.setrecursionlimit(10 ** 9)
(n, m, k) = map(int, input().split())
friend = [[] * (n + 1) for _ in range(n + 1)]
block = [[] * (n + 1) for _ in range(n + 1)]
teams = [0] * (n + 1)
for _ in range(m):
	(a, b) = map(int, input().split())
	friend[a].append(b)
	friend[b].append(a)
for _ in range(k):
	(c, d) = map(int, input().split())
	block[c].append(d)
	block[d].append(c)

def dfs(i):
	teams[i] = team
	for j in friend[i]:
		if teams[j] != 0:
			continue
		dfs(j)
team = 1
for i in range(1, n + 1):
	if teams[i] != 0:
		continue
	dfs(i)
	team += 1
c = collections.Counter(teams)
for i in range(1, n + 1):
	temp = c[teams[i]] - len(friend[i]) - 1
	for j in block[i]:
		if teams[j] == teams[i]:
			temp -= 1
	print(temp, end='')
	if i != n:
		print(' ', end='')


from collections import deque
(N, M, K) = map(int, input().split())
flst = []
blst = []
glooplst = [i for i in range(N + 1)]
colorlst = [0] * (N + 1)
countlst = [0] * (N + 1)
anslst = [0] * (N + 1)
d = deque()
for i in range(N + 1):
	flst.append([])
	blst.append([])
for i in range(M):
	(a, b) = map(int, input().split())
	flst[a].append(b)
	flst[b].append(a)
for i in range(K):
	(a, b) = map(int, input().split())
	blst[a].append(b)
	blst[b].append(a)
for i in range(1, N + 1):
	if colorlst[i] == 0:
		d.append(i)
		colorlst[i] = 1
		countlst[i] += 1
		while d:
			now = d.popleft()
			for j in flst[now]:
				if colorlst[j] == 0:
					d.append(j)
					colorlst[j] = 1
					glooplst[j] = i
					countlst[i] += 1
for i in range(1, N + 1):
	cnt = countlst[glooplst[i]] - len(flst[i]) - 1
	for j in blst[i]:
		if glooplst[i] == glooplst[j]:
			cnt -= 1
	print(cnt, end=' ')
print()


def find_parent(x):
	y = parent[x]
	if y < 0:
		return x
	parent[x] = find_parent(y)
	return parent[x]

def connect(a, b):
	c = find_parent(a)
	d = find_parent(b)
	if c == d:
		return
	if parent[c] < parent[d]:
		parent[c] += parent[d]
		parent[d] = c
	else:
		parent[d] += parent[c]
		parent[c] = d
	return
(N, M, K) = map(int, input().split())
AB = [list(map(int, input().split())) for i in range(M)]
CD = [list(map(int, input().split())) for i in range(K)]
parent = [-1] * (N + 1)
for (A, B) in AB:
	connect(A, B)
ans = [0] * (N + 1)
for i in range(1, N + 1):
	ans[i] = -parent[find_parent(i)] - 1
for (A, B) in AB:
	ans[A] -= 1
	ans[B] -= 1
for (C, D) in CD:
	if find_parent(C) == find_parent(D):
		ans[C] -= 1
		ans[D] -= 1
print(*ans[1:])


(n, m, k) = map(int, input().split())
A = [[] for i in range(n + 1)]
for i in range(m):
	(a, b) = map(int, input().split())
	A[a].append(b)
	A[b].append(a)
C = [[] for i in range(n + 1)]
for i in range(k):
	(c, d) = map(int, input().split())
	C[c].append(d)
	C[d].append(c)
from collections import deque
reach = [0] * (n + 1)
for i in range(1, n + 1):
	if reach[i] != 0:
		pass
	else:
		reach[i] = i
		q = deque([])
		q.append(i)
		while q:
			x = q.popleft()
			for s in A[x]:
				if reach[s] == 0:
					q.append(s)
					reach[s] = i
dis_count = [0] * (n + 1)
for (i, C0) in enumerate(C):
	for CC in C0:
		if reach[CC] == reach[i]:
			dis_count[i] += 1
import collections
D = collections.Counter(reach)
for i in range(1, n + 1):
	print(D[reach[i]] - len(A[i]) - dis_count[i] - 1, end='')
	print(' ', end='')
print('')


(N, M, K) = map(int, input().split())
a = [0] * M
b = [0] * M
c = [0] * K
d = [0] * K
for i in range(M):
	(a[i], b[i]) = map(int, input().split())
for i in range(K):
	(c[i], d[i]) = map(int, input().split())
l = list(range(N + 1))
r = [0] * (N + 1)
size = [1] * (N + 1)
la = N
di = [[] for _ in range(N + 1)]

def find(x):
	if l[x] == x:
		return x
	else:
		return find(l[x])

def union(x, y):
	X = find(x)
	Y = find(y)
	if r[X] > r[Y]:
		l[Y] = l[X]
		size[X] += size[Y]
	else:
		l[X] = l[Y]
		if r[X] == r[Y]:
			r[Y] += 1
		if X != Y:
			size[Y] += size[X]
for i in range(M):
	union(a[i], b[i])
	di[a[i]].append(b[i])
	di[b[i]].append(a[i])
for i in range(K):
	if find(c[i]) == find(d[i]):
		di[c[i]].append(d[i])
		di[d[i]].append(c[i])
t = []
for i in range(N + 1):
	p = size[find(i)] - 1 - len(di[i])
	t.append(p)
print(' '.join(map(str, t[1:])))


import sys
input = sys.stdin.readline
(n, m, k) = map(int, input().split())
friend = [[] for _ in range(n + 1)]
block = [[] for _ in range(n + 1)]
par = [-1] * (n + 1)

def find(x):
	if par[x] < 0:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def size(x):
	return -par[find(x)]

def unite(x, y):
	if find(x) == find(y):
		return False
	if size(x) < size(y):
		(x, y) = (y, x)
	X = find(x)
	Y = find(y)
	par[X] += par[Y]
	par[Y] = X
	return True

def is_same(x, y):
	return find(x) == find(y)
for _ in range(m):
	(a, b) = map(int, input().split())
	friend[a].append(b)
	friend[b].append(a)
	unite(a, b)
for _ in range(k):
	(c, d) = map(int, input().split())
	if is_same(c, d):
		block[c].append(d)
		block[d].append(c)
ans = [0] * (n + 1)
for i in range(1, n + 1):
	f = size(i) - 1 - len(friend[i])
	b = len(block[i])
	ans[i] = f - b
print(*ans[1:], sep=' ')


(n, m, k) = map(int, input().split())
g = [[] for i in range(n + 1)]
f = [0] * (n + 1)
b = []
for i in range(m):
	(u, v) = map(int, input().split())
	g[u].append(v)
	g[v].append(u)
	f[u] += 1
	f[v] += 1
for i in range(k):
	b.append(map(int, input().split()))
count = 0
renketu_list = [-1] * (n + 1)
renketu_size = [0]
stack = []
for i in range(1, n + 1):
	if renketu_list[i] == -1:
		count += 1
		renketu_list[i] = count
		renketu_size.append(1)
		while len(g[i]) > 0:
			stack.append(g[i].pop())
		while len(stack) > 0:
			v = stack.pop()
			if renketu_list[v] == -1:
				renketu_list[v] = count
				renketu_size[count] += 1
				while len(g[v]) > 0:
					stack.append(g[v].pop())
s = [0] * (n + 1)
for i in range(1, n + 1):
	s[i] += renketu_size[renketu_list[i]] - f[i] - 1
for i in range(k):
	(u, v) = b[i]
	if renketu_list[u] == renketu_list[v]:
		s[u] -= 1
		s[v] -= 1
print(' '.join(list(map(str, s[1:]))))


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
(n, m, k) = map(int, input().split())
V = [[] for i in range(n + 1)]
W = [0] * (n + 1)
uf = UnionFind(n + 1)
for _ in range(m):
	(a, b) = map(int, input().split())
	V[a].append(b)
	V[b].append(a)
	uf.union(a, b)
for _ in range(k):
	(c, d) = map(int, input().split())
	if uf.find(d) == uf.find(c):
		W[c] += 1
		W[d] += 1
for i in range(1, n + 1):
	ans = uf.size(i) - len(V[i]) - W[i] - 1
	print(ans, end='')
	print(' ', end='')
print()


from collections import deque
(n, m, k) = map(int, input().split())
tomodati = [[] for i in range(n + 1)]
group = [0] * (n + 1)
group_cnt = [0] * (n + 1)
block = [0] * (n + 1)
tansaku = deque()
for i in range(m):
	(a, b) = map(int, input().split())
	tomodati[a].append(b)
	tomodati[b].append(a)
num = 1
for i in range(1, n + 1):
	if group[i] == 0:
		tansaku.append(i)
		group[i] = num
		group_cnt[num] += 1
	else:
		continue
	while len(tansaku) > 0:
		for j in tomodati[tansaku[0]]:
			if group[j] == 0:
				group[j] = num
				group_cnt[num] += 1
				tansaku.append(j)
		tansaku.popleft()
	num += 1
for i in range(k):
	(c, d) = map(int, input().split())
	if group[c] == group[d]:
		block[c] += 1
		block[d] += 1
ans = []
for i in range(1, n + 1):
	ans.append(group_cnt[group[i]] - len(tomodati[i]) - block[i] - 1)
print(*ans)


(n, m, k) = map(int, input().split())
w = [i for i in range(n + 1)]
s = [1] * (n + 1)
g = [list(map(int, input().split())) for i in range(m)]

def root(x):
	if w[x] == x:
		return x
	x = w[x]
	return root(w[x])

def unite(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		if s[x] < s[y]:
			w[x] = y
			s[y] += s[x]
		else:
			w[y] = x
			s[x] += s[y]
for i in range(m):
	(a, b) = (g[i][0], g[i][1])
	unite(a, b)
for i in range(1, n + 1):
	w[i] = root(i)
	s[i] = s[w[i]]
for i in range(m):
	s[g[i][0]] -= 1
	s[g[i][1]] -= 1
for i in range(k):
	(a, b) = map(int, input().split())
	if w[a] == w[b]:
		s[a] -= 1
		s[b] -= 1
for i in range(1, n + 1):
	s[i] -= 1
print(*s[1:])


(N, M, K) = map(int, input().split())
AB = [list(map(int, input().split())) for _ in range(M)]
CD = [list(map(int, input().split())) for _ in range(K)]
root = [i for i in range(N + 1)]
size = [1] * (N + 1)

def find(x):
	y = root[x]
	if x == y:
		return x
	else:
		z = find(y)
		root[x] = z
		return z

def union(x, y):
	rx = find(x)
	ry = find(y)
	sx = size[rx]
	sy = size[ry]
	if rx == ry:
		return 0
	else:
		if sx >= sy:
			root[ry] = rx
			size[rx] = sx + sy
		else:
			root[rx] = ry
			size[ry] = sx + sy
		return sx * sy
for (a, b) in AB:
	union(a, b)
answer = []
for i in range(N + 1):
	answer.append(size[find(i)] - 1)
for (a, b) in AB:
	if find(a) == find(b):
		answer[a] -= 1
		answer[b] -= 1
for (c, d) in CD:
	if find(c) == find(d):
		answer[c] -= 1
		answer[d] -= 1
print(*answer[1:])


(n, m, k) = map(int, input().split())
frag = list(range(n + 1))

def takefrag(p):
	stock = []
	while frag[frag[p]] != frag[p]:
		stock.append(p)
		p = frag[p]
	p = frag[p]
	for i in stock:
		frag[i] = p
	return p
ans = [-1] * (n + 1)
for i in range(m):
	(a, b) = map(int, input().split())
	ans[a] -= 1
	ans[b] -= 1
	(a, b) = (takefrag(a), takefrag(b))
	(a, b) = (min(a, b), max(a, b))
	frag[a] = b
fragteam = [0] * (n + 1)
for i in range(n + 1):
	frag[i] = takefrag(i)
	fragteam[frag[i]] += 1
for i in range(k):
	(a, b) = map(int, input().split())
	if frag[a] == frag[b]:
		ans[a] -= 1
		ans[b] -= 1
for i in range(n + 1):
	ans[i] += fragteam[frag[i]]
for i in ans[1:-1]:
	print(i, end=' ')
print(ans[-1])


import sys
import math
import copy
import queue
input = sys.stdin.readline
(n, m, k) = map(int, input().split())
f = [[] for _ in range(n + 1)]
b = [[] for _ in range(n + 1)]
for _ in range(m):
	(x, y) = map(int, input().split())
	f[x].append(y)
	f[y].append(x)
for _ in range(k):
	(x, y) = map(int, input().split())
	b[x].append(y)
	b[y].append(x)
g = [0 for _ in range(n + 1)]
g_cnt = [0]
g_no = 0
for i in range(1, n + 1):
	if g[i] > 0:
		continue
	g_no += 1
	q = queue.Queue()
	q.put(i)
	cnt = 0
	while not q.empty():
		g[i] = g_no
		node = q.get()
		cnt += 1
		for n_node in f[node]:
			if g[n_node] == 0:
				q.put(n_node)
				g[n_node] = g_no
	g_cnt.append(cnt)
for i in range(1, n + 1):
	block = 0
	for x in b[i]:
		block += g[i] == g[x]
	print(g_cnt[g[i]] - len(f[i]) - block - 1, end=' ')
print()


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, v):
		if self.parents[v] < 0:
			return v
		else:
			self.parents[v] = self.find(self.parents[v])
			return self.parents[v]

	def unite(self, u, v):
		u = self.find(u)
		v = self.find(v)
		if u == v:
			return
		if self.parents[u] > self.parents[v]:
			(u, v) = (v, u)
		self.parents[u] += self.parents[v]
		self.parents[v] = u

	def size(self, v):
		return -self.parents[self.find(v)]

	def same(self, u, v):
		return self.find(u) == self.find(v)
(N, M, K) = map(int, input().split())
uf = UnionFind(N + 1)
F = [0] * (N + 1)
B = [0] * (N + 1)
for _ in range(M):
	(a, b) = map(int, input().split())
	uf.unite(a, b)
	F[a] += 1
	F[b] += 1
for _ in range(K):
	(c, d) = map(int, input().split())
	if uf.same(c, d):
		B[c] += 1
		B[d] += 1
for i in range(1, N + 1):
	ans = uf.size(i) - F[i] - B[i] - 1
	print(ans, end=' ')
print()


def init(n):
	par = list(range(n))
	size = [1] * n
	return (par, size)

def root(x):
	if par[x] == x:
		return x
	else:
		par[x] = root(par[x])
		return par[x]

def same(x, y):
	return root(x) == root(y)

def unite(x, y):
	x = root(x)
	y = root(y)
	if x == y:
		return
	if size[x] < size[y]:
		par[x] = y
		size[y] += size[x]
	else:
		par[y] = x
		size[x] += size[y]
(N, M, K) = map(int, input().split())
(par, size) = init(N + 1)
non_candidates = [1] * (N + 1)
for i in range(M):
	(a, b) = map(int, input().split())
	unite(a, b)
	non_candidates[a] += 1
	non_candidates[b] += 1
for i in range(K):
	(c, d) = map(int, input().split())
	if same(c, d):
		non_candidates[c] += 1
		non_candidates[d] += 1
for i in range(1, N + 1):
	print(size[root(i)] - non_candidates[i], end=' ')


from collections import deque
import numpy as np
(N, M, K) = [int(x) for x in input().split()]
friends = [[] for _ in range(N + 1)]
for i in range(M):
	(A, B) = [int(x) for x in input().split()]
	friends[A].append(B)
	friends[B].append(A)
block = [[] for _ in range(N + 1)]
for i in range(K):
	(C, D) = [int(x) for x in input().split()]
	block[C].append(D)
	block[D].append(C)
G = []
check = [False] * (N + 1)
for i in range(1, N + 1):
	if check[i] == False:
		check[i] = True
		g = [i]
		q = deque([i])
		while q:
			j = q.popleft()
			for k in friends[j]:
				if check[k] == False:
					check[k] = True
					g.append(k)
					q.append(k)
		G.append(g)
gr = np.array([0] * (N + 1))
fr = np.array([len(friends[i]) for i in range(N + 1)])
bl = np.array([0] * (N + 1))
for g in G:
	s = set(g)
	for v in g:
		gr[v] = len(g)
		b = set(block[v])
		bl[v] = len(s & b)
ans = gr - fr - bl - np.array([1] * (N + 1))
for i in range(1, N + 1):
	print(ans[i], end='')
	if i == N:
		print('')
	else:
		print(' ', end='')


(N, M, K) = map(int, input().split())
par = [0] * (N + 1)
num = [0] * (N + 1)
group = [1] * (N + 1)
for i in range(1, N + 1):
	par[i] = i

def root(x):
	if par[x] == x:
		return x
	return root(par[x])

def union(x, y):
	rx = root(x)
	ry = root(y)
	if rx == ry:
		return
	par[max(rx, ry)] = min(rx, ry)
	group[min(rx, ry)] += group[max(rx, ry)]

def same(x, y):
	return root(x) == root(y)
for _ in range(M):
	(a, b) = map(int, input().split())
	union(a, b)
	num[a] += 1
	num[b] += 1
for _ in range(K):
	(c, d) = map(int, input().split())
	if same(c, d):
		num[c] += 1
		num[d] += 1
for i in range(1, N + 1):
	print(group[root(i)] - num[i] - 1, end=' ')


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.root = [-1] * (n + 1)

	def find(self, x):
		if self.root[x] < 0:
			return x
		else:
			self.root[x] = self.find(self.root[x])
			return self.root[x]

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return False
		if self.root[x] > self.root[y]:
			(x, y) = (y, x)
		self.root[x] += self.root[y]
		self.root[y] = x

	def is_same(self, x, y):
		return self.find(x) == self.find(y)

	def size(self, x):
		return -self.root[self.find(x)]
(n, m, k) = map(int, input().split())
friends = UnionFind(n)
f_or_b = [1] * (n + 1)
for i in range(m):
	(a, b) = map(int, input().split())
	friends.unite(a, b)
	f_or_b[a] += 1
	f_or_b[b] += 1
for i in range(k):
	(c, d) = map(int, input().split())
	if friends.is_same(c, d):
		f_or_b[c] += 1
		f_or_b[d] += 1
print(*[friends.size(i) - f_or_b[i] for i in range(1, n + 1)])


f = lambda : map(int, input().split())

def r(x):
	while p[x] >= 0:
		x = p[x]
	return x

def u(x, y):
	(x, y) = (r(x), r(y))
	if x == y:
		return
	if x > y:
		(x, y) = (y, x)
	p[x] += p[y]
	p[y] = x
(n, m, k) = f()
(l, p) = ([0] * -~n, [-1] * -~n)
for _ in range(m):
	(a, b) = f()
	u(a, b)
	l[a] -= 1
	l[b] -= 1
for _ in range(k):
	(c, d) = f()
	if r(c) == r(d):
		l[c] -= 1
		l[d] -= 1
for i in range(n + 1):
	l[i] -= p[r(i)] + 1
print(*l[1:])