Problem:
 Score : 400 points    Problem Statement 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 1 4 4 1
2 1
1 3
3 2
3 4
4 1      Sample Output 1 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.       Sample Input 2 5 10 0
1 2
1 3
1 4
1 5
3 2
2 4
2 5
4 3
5 3
4 5      Sample Output 2 0 0 0 0 0  Everyone is a friend of everyone else and has no friend candidate.       Sample Input 3 10 9 3
10 1
6 7
8 2
2 5
8 4
7 3
10 9
6 4
5 8
2 6
7 5
3 1      Sample Output 3 1 3 5 4 3 3 3 3 1 0

Solution (Python):
import sys, re
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees
from collections import deque, defaultdict, Counter
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop, heapify
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

class UnionFind():
    def __init__(self, n):
        self.n = n
        
        
        self.parents = [-1] * n
    def find(self, x):
        if 0 > self.parents[x]:
            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 0 > x]
    
    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()

tree = UnionFind(N)
friends = [[] for _ in range(N)]

for _ in range(M):
	A, B = MAP()
	tree.union(A-1, B-1)
	friends[A-1].append(B-1)
	friends[B-1].append(A-1)

blocks = [[] for _ in range(N)]

for _ in range(K):
	C, D = MAP()
	blocks[C-1].append(D-1)
	blocks[D-1].append(C-1)

for i in range(N):
	blocks_cnt = 0
	for j in blocks[i]:
		if tree.same(i, j):
			blocks_cnt += 1
	print(tree.size(i) - len(friends[i]) - 1 - blocks_cnt, end=" ")
print()

Solution (Python):
import sys, re
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees
from collections import deque, defaultdict, Counter
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop, heapify
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

class UnionFind():
    def __init__(self, n):
        self.n = n
        
        
        self.parents = [-1] * n
    def find(self, x):
        if 0 > self.parents[x]:
            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 0 > x]
    
    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()

tree = UnionFind(N)
friends = [[] for _ in range(N)]

for _ in range(M):
	A, B = MAP()
	tree.union(A-1, B-1)
	friends[A-1].append(B-1)
	friends[B-1].append(A-1)

blocks = [[] for _ in range(N)]

for _ in range(K):
	C, D = MAP()
	blocks[C-1].append(D-1)
	blocks[D-1].append(C-1)

for i in range(N):
	ans = tree.size(i) - 1 - len(friends[i])
	blocks_cnt = 0
	for j in  blocks[i]:
		if tree.same(i, j):
			blocks_cnt += 1
	ans -= blocks_cnt
	print(ans, end=" ")
print()

Solution (Python):
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

class UnionFind:
    def __init__(self, n):
        self.parents = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]
        self.length = [1 for _ in range(n)] 

    def makeSet(self, n):
        self.parents = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]
        self.length = [1 for _ in range(n)]

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

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.rank[x] < self.rank[y]:
            self.parents[x] = y
            self.length[y] += self.length[x]
        else:
            self.parents[y] = x
            self.length[x] += self.length[y]
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    def getLength(self, x):
        x = self.find(x)
        return self.length[x]        

    def isSameGroup(self, x, y):
        return self.find(x) == self.find(y)
 
def main():
    N, M, K = map(int, readline().split())
    friend = [set() for _ in range(N)]
    block = [set() for _ in range(N)]
    uf = UnionFind(N)
    for _ in range(M):
        a, b = map(int, readline().split())
        a-=1
        b-=1
        friend[a].add(b)
        friend[b].add(a)
        uf.unite(a, b)

    for _ in range(K):
        c, d = map(int, readline().split())
        c-=1
        d-=1
        block[c].add(d)
        block[d].add(c)

    for i in range(N):
        cnt = 0
        for blk in block[i]:
            if uf.isSameGroup(i, blk):
                cnt += 1    
        ans = uf.getLength(i)-cnt-len(friend[i])-1
        if i == N-1:
            print(ans)
        else:
            print(ans, end=" ")
if __name__ == '__main__': 
    main()

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 5 + 10)
def input(): return sys.stdin.readline().strip()

def resolve():
    
    class UnionFind(object):
        def __init__(self, n=1):
            
            
            
            self.par = [i for i in range(n)]
            
            self.rank = [0 for _ in range(n)]
            self.size = [1 for _ in range(n)]
    
        def find(self, x):
            """
            x が属するグループを探索：
            ある２つの要素が属する木の根が同じかどうかをチェックすればよい。
            つまり、親の親の親の・・・と根にたどり着くまで走査すればよい。
            再帰。
            """
            
            if self.par[x] == x:
                return x
            
            else:
                
                
                self.par[x] = self.find(self.par[x])
                return self.par[x]
    
        def union(self, x, y):
            """
            x と y のグループを結合
            """
            
            x = self.find(x)
            y = self.find(y)
            
            if x != y:
                if self.rank[x] < self.rank[y]:
                    x, y = y, x
                
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1
                
                self.par[y] = x
                self.size[x] += self.size[y]
    
        def is_same(self, x, y):
            """
            x と y が同じグループか否か
            """
            return self.find(x) == self.find(y)
    
        def get_size(self, x):
            """
            x が属するグループの要素数
            """
            x = self.find(x)
            return self.size[x]
    
    N,M,K=map(int,input().split())
    uf = UnionFind(N)  
    friends_cnt=[0]*N
    for i in range(M):
        
        A, B = map(int, input().split())
        A-=1
        B-=1
        friends_cnt[A]+=1
        friends_cnt[B]+=1
    
        
        uf.union(A, B)
    
    blocks=[[] * N for i in range(N)]
    for i in range(K):
        x, y = map(int, input().split())
        x, y = x - 1, y - 1
        blocks[x].append(y)
        blocks[y].append(x) 
    
    for i in range(N):
        ans=uf.get_size(i)-friends_cnt[i]-1
        for j in blocks[i]:
            if uf.is_same(i,j):
                ans-=1
        print(ans,end=' ')
    print()

    
    

    

resolve()

Solution (Python):
import sys, re
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees
from collections import deque, defaultdict, Counter
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop, heapify
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

class UnionFind():
    def __init__(self, n):
        self.n = n
        
        
        self.parents = [-1] * n
    def find(self, x):
        if 0 > self.parents[x]:
            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 0 > x]
    
    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()
friends = defaultdict(list)
tree = UnionFind(N)
for _ in range(M):
	A, B = MAP()
	tree.union(A-1, B-1)
	friends[A-1].append(B-1)
	friends[B-1].append(A-1)

blocks = defaultdict(list)
for _ in range(K):
	C, D = MAP()
	blocks[C-1].append(D-1)
	blocks[D-1].append(C-1)

for i in range(N):
	minus = 0
	for b in blocks[i]:
		if tree.same(i, b):
			minus += 1
	print(tree.size(i)-len(friends[i])-1-minus, end = " ")
print()

"""
print("friends")
print(friends)

print("blocks")
print(blocks)

i = 1
print("i={}".format(i))
print("tree.size(i)={}".format(tree.size(i)))
print("tree.find(i))={}".format(tree.find(i)))
print("tree.members(i)={}".format(tree.members(i)))
print("tree.roots={}".format(tree.roots()))
print("tree.group_count={}".format(tree.group_count()))
print("tree.all_group_members={}".format(tree.all_group_members()))
"""

Solution (Python):
import sys
sys.setrecursionlimit(10**5)

def DFS(i,g):
    if i not in done:
        done.add(i)
        circle.add(i)
        g_list[i]=g
        for f in F[i]:
            DFS(f,g)
    else:
        return

N,M,K=map(int,input().split())
F=[[] for _ in range(N)]
B=[[] for _ in range(N)]

for f in range(M):
    f1,f2=map(int,input().split())
    F[f1-1].append(f2-1)
    F[f2-1].append(f1-1)
for b in range(K):
    b1,b2=map(int,input().split())
    B[b1-1].append(b2-1)
    B[b2-1].append(b1-1)

Group=[]
circle=set()
done=set()
g_list=[0 for _ in range(N)]
g=0
for i in range(N):
    if i not in done:
        DFS(i,g)
        Group.append(circle)
        circle=set()
        g+=1

ans=[-1 for _ in range(N)]
for i in range(N):
    G=g_list[i]
    ans[i]+=len(Group[G])
    for fr in F[i]:
        if fr in Group[G]:
            ans[i]-=1
    for bl in B[i]:
        if bl in Group[G]:
            ans[i]-=1

print(*ans)

Solution (Python):
import sys
import collections
def input():
    return sys.stdin.readline()[:-1]
sys.setrecursionlimit(10000000)
n,m,k=map(int,input().split())
gf = [[]for i in range(n)]
gb = [[]for i in range(n)]
for i in range(m):
    a,b = map(int,input().split())
    gf[a-1].append(b-1)
    gf[b-1].append(a-1)

for i in range(k):
    a,b = map(int,input().split())
    gb[a-1].append(b-1)
    gb[b-1].append(a-1)

seen = [0 for i in range(n)]

def dfs(i,k):
    for nec in gf[i]:
        if seen[nec]!=0:
            continue
        seen[nec]=k
        dfs(nec,k)
k=1

for i in range(n):
    if seen[i]==0:
        seen[i]=k
        dfs(i,k)
        k+=1
c = collections.Counter(seen)
lis = []
for i in range(n):
    dec = 0
    for k in gb[i]:
        if seen[i]==seen[k]:
            dec += 1
    lis.append(c[seen[i]]-len(gf[i])-dec-1)
print(*lis)

Solution (Python):

class UnionFind():
    def __init__(self, n):
        
        self.par = [i for i in range(n)]
        self.rank = [0] * n
        self.size = [1] * n

    
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

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

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

def main():
    N,M,K = map(int, input().split())
    
    
    uftree = UnionFind(N)
    count = [0] * N
    for i in range(M):
        A,B = map(lambda x:x-1, map(int, input().split()))
        uftree.union(A,B)
        count[A] += 1
        count[B] += 1
    for i in range(K):
        C,D = map(lambda x:x-1, map(int, input().split()))
        if uftree.same_check(C,D):
            count[C] += 1
            count[D] += 1
    ans = [0] * N
    for i in range(N):
        ans[i] = uftree.getSize(i) - 1 - count[i] 
    print(*ans)

main()

Solution (Python):
n,m,k=map(int,input().split())
 
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
 
def unite(x,y):
    x = find(x)
    y = find(y)
    
    if x == y:
        return False
    else:
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True
 
def same(x,y):
    return find(x) == find(y)
 
def size(x):
    return -par[find(x)]
 
par = [-1]*n
 
ans=[0]*n
nxt=[0]*n
block=[[] for _ in range(n)]
 
for _ in range(m):
    a,b=map(int,input().split())
    unite(a-1,b-1)
    nxt[a-1]+=1
    nxt[b-1]+=1
 
for _ in range(k):
    c,d=map(int,input().split())
    block[c-1].append(d-1)
    block[d-1].append(c-1)
 
for i in range(n):
    ans[i]=size(i)-nxt[i]-1
    for j in block[i]:
        if same(j,i):
            ans[i]-=1
print(*ans)

Solution (Python):
n,m,k=map(int,input().split())

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

def unite(x,y):
    x = find(x)
    y = find(y)
    
    if x == y:
        return False
    else:
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

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

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

par = [-1]*n

ans=[0]*n
nxt=[0]*n
block=[[] for _ in range(n)]

for _ in range(m):
    a,b=map(int,input().split())
    unite(a-1,b-1)
    nxt[a-1]+=1
    nxt[b-1]+=1

for _ in range(k):
    c,d=map(int,input().split())
    block[c-1].append(d-1)
    block[d-1].append(c-1)

for i in range(n):
    ans[i]=size(i)-nxt[i]-1
    for j in block[i]:
        if same(j,i):
            ans[i]-=1
print(*ans)

Solution (Python):
from collections import deque
n,m,k=map(int,input().split())
fl=[set() for _ in range(n+1)]
bl=[set() for _ in range(n+1)]
for i in range(m):
  a,b=map(int,input().split())
  fl[a].add(b)
  fl[b].add(a)
for i in range(k):
  c,d=map(int,input().split())
  bl[c].add(d)
  bl[d].add(c)
stack = deque()
ans = [0]*(n+1)
visited = [0]*(n+1)
for i in range(1, n+1):
    if visited[i]:
        continue
    link = {i}
    visited[i] = 1
    stack.append(i)
    while stack:
        n = stack.pop()
        for j in fl[n]:
            if visited[j] == 0:
                stack.append(j)
                visited[j] = 1
                link.add(j)
    for i in link:
        ans[i] = len(link) - len(link & fl[i]) - len(link & bl[i]) -1
print(*ans[1:])

Solution (Python):
N, M, K = map(int, input().split())
INF = 10**9
 
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())
 
 
union_find = UnionFind(N)
friend_num_list = [0]*N
block_num_list = [0]*N
 
for _ in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    friend_num_list[a] += 1
    friend_num_list[b] += 1
    union_find.union(a, b)
 
for _ in range(K):
    c, d = map(int, input().split())
    c -= 1
    d -= 1
    if union_find.same(c, d):
        block_num_list[c] += 1
        block_num_list[d] += 1
 
ans_list = [0]*N
for i in range(N):
    ans = union_find.size(i) - friend_num_list[i] - block_num_list[i] - 1
    ans_list[i] = ans
print(*ans_list)

Solution (Python):
import sys
input = sys.stdin.readline
N, M, K = map(int, input().split())
class UnionFind():
  def __init__(self, n):
    self.n = n
    self.root = [-1]*(n+1)
    self.rnk = [0]*(n+1)
  def Find_Root(self, x):
    if(self.root[x] < 0):
      return x
    else:
      self.root[x] = self.Find_Root(self.root[x])
      return self.root[x]
  def Unite(self, x, y):
    x = self.Find_Root(x)
    y = self.Find_Root(y)
    if(x == y):
      return 
    if self.root[x] > self.root[y]:
      x, y = y, x
    self.root[x] += self.root[y]
    self.root[y] = x 
  def isSameGroup(self, x, y):
    return self.Find_Root(x) == self.Find_Root(y)
  def Count(self, x): 
    return -self.root[self.Find_Root(x)]
  def Members(self, x): 
    return [i for i in range(self.n) if self.Find_Root(i)==self.Find_Root(x)]
  def Roots(self): 
    return [i for i, x in enumerate(self.root) if x < 0]
  def Group_Count(self): 
    return len(self.Roots())

uf = UnionFind(N+1)
roots = {i:0 for i in range(1, N+1)}
each_root = [0]*(N+1)
ad = [0]*(N+1)

for _ in range(M):
  a, b = map(int, input().split())
  uf.Unite(a, b)
  ad[a] += 1
  ad[b] += 1

for i in range(1, N+1):
  r = uf.Find_Root(i)
  roots[r] += 1
  each_root[i] = r

for _ in range(K):
  c, d = map(int, input().split())
  if each_root[c] == each_root[d]:
    ad[c] += 1
    ad[d] += 1

for i in range(1, N+1):
  print(roots[each_root[i]]-ad[i]-1, end=" ")

Solution (Python):
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()}

n, m, k = map(int, input().split())
fr = UnionFind(n)
bl = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    bl[a-1].append(b-1)
    bl[b-1].append(a-1)
    fr.union(a-1, b-1)

for _ in range(k):
    c, d = map(int, input().split())
    if fr.same(c-1, d-1):
        bl[c-1].append(d-1)
        bl[d-1].append(c-1)

ans = []
for i in range(n):
    s = fr.size(i) - len(bl[i]) - 1
    ans.append(s)

print(*ans)

Solution (Python):
import sys

sys.setrecursionlimit(10 ** 6)
INF = float("inf")
MOD = 10 ** 9 + 7


def input():
    return sys.stdin.readline().strip()


class UnionFind:
    def __init__(self, n_nodes):
        self.n_nodes = n_nodes

        
        
        self.parents = [-1] * n_nodes

    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 unite(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 get_size(self, x):
        return -self.parents[self.find(x)]

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

    def get_members(self, x):
        parent = self.find(x)
        return [i for i in range(self.n_nodes) if self.find(i) == parent]

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

    def get_n_groups(self):
        return len(self.get_parent_list())

    def get_members_dict(self):
        return {par: self.get_members(par) for par in self.get_parent_list()}


def main():
    N, M, K = map(int, input().split())
    tree = UnionFind(N)

    friends = [[] for _ in range(N)]
    for _ in range(M):
        a, b = map(int, input().split())
        a -= 1
        b -= 1
        tree.unite(a, b)
        friends[a].append(b)
        friends[b].append(a)

    ng = [[] for _ in range(N)]
    for _ in range(K):
        c, d = map(int, input().split())
        c -= 1
        d -= 1
        ng[c].append(d)
        ng[d].append(c)

    ans = []
    for i in range(N):
        n_ng = 0
        for j in ng[i]:
            if tree.is_same(i, j):
                n_ng += 1

        n_member = tree.get_size(i)
        n_friends = len(friends[i])
        
        ans.append(n_member - n_friends - n_ng - 1)

    print(*ans, sep=" ")


if __name__ == "__main__":
    main()

Solution (Python):
import sys
from collections import Counter
n,m,k = map(int,input().split())
fgraph = [list() for i in range(n)]
bgraph = [list() for i in range(n)]
cgraph = [list() for i in range(n)]

rks = [None] * n
sys.setrecursionlimit(10**9)


def dfs(graph, s, r):
    if rks[s] is None:
        rks[s] = r
    for i in range(len(graph[s])):
        if rks[graph[s][i]-1] is not None:
            continue
        dfs(graph,graph[s][i]-1,r)

for i in range(m):
    a,b = map(int,input().split())
    fgraph[a-1].append(b)
    fgraph[b-1].append(a)


c = -1
for i in range(n):
    if rks[i] is None:
        c += 1
        dfs(fgraph, i, c)

for i in range(k):
    c,d = map(int,input().split())
    
    if rks[c-1] == rks[d-1]:
        bgraph[d-1].append(c)
        bgraph[c-1].append(d)

counter = Counter(rks)
for i in range(n):
    print(counter[rks[i]] - len(fgraph[i]) - len(bgraph[i]) - 1, end=' ')

Solution (Python):
import sys
from collections import deque

input = sys.stdin.readline


def calc_group(N, G, group_id, group_cnt):
    g_id = 0
    for i in range(N):
        if group_id[i] != -1:
            continue
        cnt = 1
        group_id[i] = g_id
        stack = deque([i])
        while stack:
            v = stack.pop()
            for u in G[v]:
                if group_id[u] != -1:
                    continue
                cnt += 1
                group_id[u] = g_id
                stack.append(u)
        g_id += 1
        group_cnt.append(cnt)


def main():
    N, M, K = map(int, input().split())
    G = [[] for _ in range(N)]
    for _ in range(M):
        A, B = map(int, input().split())
        A -= 1
        B -= 1
        G[A].append(B)
        G[B].append(A)
    B = [[] for _ in range(N)]
    for i in range(K):
        C, D = map(int, input().split())
        C -= 1
        D -= 1
        B[C].append(D)
        B[D].append(C)

    group_id = [-1] * N
    group_cnt = []
    calc_group(N, G, group_id, group_cnt)

    ans = [0] * N
    for i in range(N):
        n_neighbor = len(G[i])
        n_block = sum(1 for j in B[i] if group_id[i] == group_id[j])
        ans[i] = (group_cnt[group_id[i]] - 1) - n_neighbor - n_block

    print(" ".join(map(str, ans)))


if __name__ == "__main__":
    main()

Solution (Python):
import sys
from collections import deque

input = sys.stdin.readline


def calc_group(N, G, group_id, group_cnt):
    g_id = 0
    for i in range(N):
        if group_id[i] != -1:
            continue
        cnt = 1
        group_id[i] = g_id
        stack = deque([i])
        while stack:
            v = stack.pop()
            for u in G[v]:
                if group_id[u] != -1:
                    continue
                cnt += 1
                group_id[u] = g_id
                stack.append(u)
        g_id += 1
        group_cnt.append(cnt)


def main():
    N, M, K = map(int, input().split())
    G = [[] for _ in range(N)]
    for _ in range(M):
        A, B = map(int, input().split())
        A -= 1
        B -= 1
        G[A].append(B)
        G[B].append(A)
    B = [[] for _ in range(N)]
    for i in range(K):
        C, D = map(int, input().split())
        C -= 1
        D -= 1
        B[C].append(D)
        B[D].append(C)

    group_id = [-1] * N
    group_cnt = []
    calc_group(N, G, group_id, group_cnt)

    ans = [0] * N
    for i in range(N):
        n_neighbor = len(G[i])
        n_block = sum(1 for j in B[i] if group_id[i] == group_id[j])
        ans[i] = (group_cnt[group_id[i]] - 1) - n_neighbor - n_block

    print(" ".join(map(str, ans)))


if __name__ == "__main__":
    main()

Solution (Python):
import sys
from collections import deque

input = sys.stdin.readline


def calc_group(N, G, group_id, group_cnt):
    g_id = 0
    for i in range(N):
        if group_id[i] != -1:
            continue
        g_id += 1
        group_id[i] = g_id
        group_cnt[g_id] = 1
        stack = deque([i])
        while stack:
            v = stack.pop()
            for u in G[v]:
                if group_id[u] != -1:
                    continue
                group_id[u] = g_id
                group_cnt[g_id] += 1
                stack.append(u)


def main():
    N, M, K = map(int, input().split())
    G = [[] for _ in range(N)]
    for _ in range(M):
        A, B = map(int, input().split())
        A -= 1
        B -= 1
        G[A].append(B)
        G[B].append(A)
    B = [[] for _ in range(N)]
    for i in range(K):
        C, D = map(int, input().split())
        C -= 1
        D -= 1
        B[C].append(D)
        B[D].append(C)

    group_id = [-1] * N
    group_cnt = {}
    calc_group(N, G, group_id, group_cnt)

    ans = [0] * N
    for i in range(N):
        n_neighbor = len(G[i])
        n_block = sum(1 for j in B[i] if group_id[i] == group_id[j])
        ans[i] = (group_cnt[group_id[i]] - 1) - n_neighbor - n_block

    print(" ".join(map(str, ans)))


if __name__ == "__main__":
    main()