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):
def main():
    import sys
    buf = sys.stdin.buffer

    class UnionFind:
        def __init__(self, size):
            self.parent = [-1] * size
            self.rank = [1] * size

        def get_root(self, node):
            parent = self.parent[node]
            if parent == -1:
                root = node
            else:
                root = self.get_root(parent)
                self.parent[node] = root  
            return root

        def in_same_group(self, node1, node2):
            root1 = self.get_root(node1)
            root2 = self.get_root(node2)
            return root1 == root2

        def unite(self, node1, node2):
            if self.in_same_group(node1, node2):
                return
            main_root = self.get_root(node1)
            sub_root = self.get_root(node2)
            if self.rank[main_root] < self.rank[sub_root]:  
                main_root, sub_root = sub_root, main_root

            self.parent[sub_root] = main_root
            self.rank[main_root] += self.rank[sub_root]

    n, m, k = map(int, buf.readline().split())
    uf = UnionFind(n)
    minus_count = [1] * n

    query = list(map(int, buf.read().split()))
    follows = query[:2*m]
    blocks = query[2*m:]

    for a, b in zip(follows[0::2], follows[1::2]):
        uf.unite(a-1, b-1)
        minus_count[a-1] += 1
        minus_count[b-1] += 1

    for a, b in zip(blocks[0::2], blocks[1::2]):
        if uf.in_same_group(a-1, b-1):
            minus_count[a-1] += 1
            minus_count[b-1] += 1

    result = [uf.rank[uf.get_root(i)] - minus_count[i] for i in range(n)]
    print(*result)


if __name__ == '__main__':
    main()

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()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())


N, M, K = map(int, input().split())
uf = UnionFind(N)
not_friend_candidates = [1]*N
for _ in range(M):
    A, B = map(int, input().split())
    uf.union(A-1, B-1)
    not_friend_candidates[A-1] += 1
    not_friend_candidates[B-1] += 1
for _ in range(K):
    C, D = map(int, input().split())
    if uf.same(C-1, D-1):
        not_friend_candidates[C-1] += 1
        not_friend_candidates[D-1] += 1
for hito in range(N):
    print(uf.size(hito) - not_friend_candidates[hito], end=" ")
print()

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

    
    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 self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

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

n,m,k=map(int,input().split())
A=UnionFind(n)

friend=[0 for i in range(n+1)]
blocked={i:[] for i in range(1,n+1)}
for i in range(m):
    a,b=map(int,input().split())
    friend[a]+=1
    friend[b]+=1
    A.union(a,b)
    
    
for j in range(k):
    x,y=map(int,input().split())
    
    blocked[x].append(y)
    blocked[y].append(x)
    
for i in range(1,n+1):
    A.find(i)
    
parent=A.par

howmany={i:0 for i in range(n+1)}

for i in range(1,n+1):
    x=parent[i]
    howmany[parent[i]]+=1
    


lists=[]
for i in range(1,n+1):
    sums=howmany[parent[i]]-1-friend[i]
    for some in blocked[i]:
        if parent[i]==parent[some]:
            sums-=1
    lists.append(sums)
print(*lists)

Solution (Python):
def main():
    import sys
    buf = sys.stdin.buffer

    class UnionFind:
        def __init__(self, size):
            self.parent = [-1] * size
            self.rank = [1] * size

        def get_root(self, node):
            parent = self.parent[node]
            if parent == -1:
                root = node
            else:
                root = self.get_root(parent)
                self.parent[node] = root  
            return root

        def in_same_group(self, node1, node2):
            root1 = self.get_root(node1)
            root2 = self.get_root(node2)
            return root1 == root2

        def unite(self, node1, node2):
            if self.in_same_group(node1, node2):
                return
            main_root = self.get_root(node1)
            sub_root = self.get_root(node2)
            if self.rank[main_root] < self.rank[sub_root]:  
                main_root, sub_root = sub_root, main_root

            self.parent[sub_root] = main_root
            self.rank[main_root] += self.rank[sub_root]

    n, m, k = map(int, buf.readline().split())
    uf = UnionFind(n)
    minus_count = [1] * n

    def gen():
        for num in buf.read().split():
            yield int(num)

    generator = gen()
    for _ in range(m):
        a, b = generator.__next__(), generator.__next__()
        uf.unite(a-1, b-1)
        minus_count[a-1] += 1
        minus_count[b-1] += 1

    for i in range(k):
        a, b = generator.__next__(), generator.__next__()
        if uf.in_same_group(a-1, b-1):
            minus_count[a-1] += 1
            minus_count[b-1] += 1

    result = []
    for i in range(n):
        parent = uf.get_root(i)
        count = uf.rank[parent]
        ans = count - minus_count[i]
        result.append(ans)

    print(*result)

if __name__ == '__main__':
    main()

Solution (Python):
class UnionFind():
    def __init__(self, n):
        self.n = n
        
        self.parent = list(range(n))
        
        self.count = [0] * n

    def root(self, x):
        
        if self.parent[x] == x:
            return x
        else:
            return self.root(self.parent[x])

    def union(self, x, y):
        
        x0 = self.root(x)
        y0 = self.root(y)
        if x0 == y0:
            return
        if x0 > y0:
            x0, y0 = y0, x0
        self.parent[y0] = x0
        self.count[x0] += self.count[y0] + 1

    def size(self, x):
        
        return self.count[self.root(x)] + 1

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


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

F, B = [0] * N, [0] * N
lst = []
for m in range(M):
    a, b = map(int, input().split())
    tree.union(a - 1, b - 1)
    lst.append((a, b))
for a, b in lst:
    if tree.same(a - 1, b - 1):
        F[a - 1] += 1
        F[b - 1] += 1
for k in range(K):
    c, d = map(int, input().split())
    if tree.same(c - 1, d - 1):
        B[c - 1] += 1
        B[d - 1] += 1

print(*[tree.size(n) - F[n] - B[n] - 1 for n in range(N)])

Solution (Python):
def main():
    import sys
    from operator import itemgetter
    buf = sys.stdin.buffer

    class UnionFind:
        def __init__(self, size):
            self.parent = [-1] * size
            self.rank = [1] * size

        def get_root(self, node):
            parent = self.parent[node]
            if parent == -1:
                root = node
            else:
                root = self.get_root(parent)
                self.parent[node] = root  
            return root

        def in_same_group(self, node1, node2):
            root1 = self.get_root(node1)
            root2 = self.get_root(node2)
            return root1 == root2

        def unite(self, node1, node2):
            if self.in_same_group(node1, node2):
                return
            main_root = self.get_root(node1)
            sub_root = self.get_root(node2)
            if self.rank[main_root] < self.rank[sub_root]:  
                main_root, sub_root = sub_root, main_root

            self.parent[sub_root] = main_root
            self.rank[main_root] += self.rank[sub_root]

    n, m, k = map(int, buf.readline().split())
    uf = UnionFind(n)
    minus_count = [1] * n

    query = map(int, buf.read().split())

    def gen():
        for num in query:
            yield num

    generator = gen()
    for _ in range(m):
        a, b = generator.__next__(), generator.__next__()
        uf.unite(a-1, b-1)
        minus_count[a-1] += 1
        minus_count[b-1] += 1

    for i in range(k):
        a, b = generator.__next__(), generator.__next__()
        if uf.in_same_group(a-1, b-1):
            minus_count[a-1] += 1
            minus_count[b-1] += 1

    result = []
    for i in range(n):
        parent = uf.get_root(i)
        count = uf.rank[parent]
        ans = count - minus_count[i]
        result.append(ans)

    print(*result)

if __name__ == '__main__':
    main()

Solution (Python):
from collections import deque
from copy import deepcopy

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())
UF = UnionFind(N+1)
direct_connect = [0]*(N+1)
for _ in range(M):
  a, b = map(int, input().split())
  UF.union(a, b)
  direct_connect[a] += 1
  direct_connect[b] += 1
for _ in range(K):
  a, b = map(int, input().split())
  if UF.same(a, b):
    direct_connect[a] += 1
    direct_connect[b] += 1
print(" ".join([str(UF.size(i)-direct_connect[i]-1) for i in range(1, N+1)]))

Solution (Python):
import sys
from io import StringIO
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
import unittest

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 
        
        elif(self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            
            if(self.rnk[x] == self.rnk[y]):
                self.rnk[y] += 1
    
    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 resolve():
    n,m,k=map(int, readline().split())
    

    uf = UnionFind(n)

    res=[[] for i in range(n)]
    frd=[0 for i in range(n)]
    blk=[0 for i in range(n)]

    for i in range(m):
        
        a,b=map(int, readline().split())
        a-=1
        b-=1
        uf.Unite(a,b)
        frd[a]+=1
        frd[b]+=1
    
    for i in range(k):
        
        a,b=map(int, readline().split())
        a-=1
        b-=1
        if uf.isSameGroup(a,b):
            blk[a]+=1
            blk[b]+=1
    
    rescnt=[]

    for i in range(n):
        ri=uf.Count(i)-1-blk[i]-frd[i]
        rescnt.append(str(ri))
        
    
    print(" ".join(rescnt))

resolve()

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

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


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())
uf = UnionFind(N)

n_friend = [0]*N
for i in range(M):
    a, b = map(int, input().split())
    uf.union(a-1, b-1)
    n_friend[a-1] += 1
    n_friend[b-1] += 1

n_block_in_friend_cluster = [0]*N
for i in range(K):
    c, d = map(int, input().split())
    if uf.same(c-1, d-1):
        n_block_in_friend_cluster[c-1] += 1
        n_block_in_friend_cluster[d-1] += 1

ans = [uf.size(i) - n_friend[i] - n_block_in_friend_cluster[i] - 1 for i in range(N)]
print(*ans)

Solution (Python):
from collections import deque
from copy import deepcopy

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())
UF = UnionFind(N+1)
direct_connect = [0]*(N+1)
for _ in range(M):
  a, b = map(int, input().split())
  UF.union(a, b)
  direct_connect[a] += 1
  direct_connect[b] += 1
for _ in range(K):
  a, b = map(int, input().split())
  if UF.same(a, b):
    direct_connect[a] += 1
    direct_connect[b] += 1
ans = ""
for i in range(1, N+1):
  ans += "%d "%(UF.size(i)-direct_connect[i]-1)
print(ans)

Solution (Python):

class UnionFindTree():
    
    
    
    
    def __init__(self, node_size):
        
        
        
        
        
        self.parent =[-1]*node_size
 
        self.size = [1] * node_size
        self.rank = [1] * node_size
    
    def find_root(self,node):
        
        
        if self.parent[node] == -1:             
            root = node
        else:                                   
            root = self.find_root(self.parent[node]) 
            self.parent[node] = root            
        return root

    def unite(self,node0, node1):
        
        
        
        root_node0 = self.find_root(node0) 
        root_node1 = self.find_root(node1)

        if root_node0 != root_node1:
            
            
            if self.rank[root_node0] == self.rank[root_node1]: 
                self.parent[root_node1] = root_node0
                self.rank[root_node0] += 1
                self.size[root_node0] += self.size[root_node1]

            elif self.rank[root_node0] > self.rank[root_node1]:
                self.parent[root_node1] = root_node0
                self.size[root_node0] += self.size[root_node1]

            else:
                self.parent[root_node0] = root_node1

                self.size[root_node1] += self.size[root_node0]

    def same(self,node0,node1):
        
        return self.find_root(node0)==self.find_root(node1)


    
    


N,M,K = map(int,input().split())

ut = UnionFindTree(N)
friend_dict = {i:0 for i in range(N)}

for i in range(M):
    x,y = map(int,input().split())
    x-=1
    y-=1
    ut.unite(x,y)
    friend_dict[x]+=1
    friend_dict[y]+=1
    
    





block_dict = {i:0 for i in range(N)}

for i in range(K):
    x,y = map(int,input().split())
    x-=1
    y-=1
    if ut.same(x,y):
        block_dict[x]+=1
        block_dict[y]+=1
        
        

ans =""
for i in range(N):
    group =  ut.find_root(i)
    group_size = ut.size[group]

    
    cand = group_size - friend_dict[i] - block_dict[i] - 1
    ans += str(cand) + " "
print(ans)

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

def same(x, y):
    if find(x) == find(y):
        return True
    else:
        return False

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

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

N, M, K = map(int, input().split())
par = [-1 for i in range(N + 1)]
rank = [0] * (N + 1)
frendCnt = [0] * (N + 1)
bloc = [[] for _ in range(N + 1)]
for i in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    frendCnt[a] += 1
    frendCnt[b] += 1
    unite(a, b)

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

for i in range(N):
    ans = uCnt(i) - frendCnt[i] - 1
    for j in bloc[i]:
      if same(i, j):
           ans -= 1
    print(ans, end=' ')

Solution (Python):
import sys
sys.setrecursionlimit(100000)

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)]



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


def find(x,y,li):
    return root(x,li) == root(y,li)


def union(x,y,li):
    x = root(x,li)
    y = root(y,li)
    if x==y:
        return
    else:
        li[x]=y

li1 = [i for i in range(N)]
li2 = [i for i in range(N)]

for i in range(M):
    a = AB[i][0]
    b = AB[i][1]
    
    union(min(a-1,b-1),max(a-1,b-1),li1)





mm = [0 for i in range(max(li1)+1)]
for i in range(N):
    m = root(i,li1)
    mm[m] += 1



ans = [mm[li1[i]]-1 for i in range(N)]


for i in range(M):
    a = AB[i][0]
    b = AB[i][1]
    ans[a-1] -= 1
    ans[b-1] -= 1


for i in range(K):
    c = CD[i][0]
    d = CD[i][1]
    if find(c-1,d-1,li1):
        ans[c-1] -= 1
        ans[d-1] -= 1
print(*ans)

Solution (Python):
N,M,K=map(int,input().split())  
par=[i for i in range(N)]
rank=[0]*(N)
friend=[0]*N
block=[0]*N
size=[1]*N
def find(x):
  if par[x]==x:
    return x
  else:
    par[x]=find(par[x])
    return par[x]


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

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


for i in range(M):
  a,b=map(int,input().split())
  a-=1
  b-=1
  union(a,b)
  friend[a]+=1
  friend[b]+=1

for i in range(K):
  c,d=map(int,input().split())
  c-=1
  d-=1
  if same(c,d):
    block[c]+=1
    block[d]+=1
    
ans=[]
for i in range(N):
  ans.append(size[find(i)]-friend[i]-block[i]-1)
print(*ans)

Solution (Python):
import sys
input = sys.stdin.readline




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)]

N, M, K = map(int, input().split())
par = [-1 for i in range(N)]
rank = [0] * N
frendCnt = [0] * N
bloc = [[] for _ in range(N)]
for i in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    frendCnt[a] += 1
    frendCnt[b] += 1
    unite(a, b)

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

for i in range(N):
    ans = size(i) - frendCnt[i] - 1
    for j in bloc[i]:
      if same(i, j):
           ans -= 1
    print(ans, end=' ')

Solution (Python):
import sys
from io import StringIO
import unittest

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 
        
        elif(self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            
            if(self.rnk[x] == self.rnk[y]):
                self.rnk[y] += 1
    
    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 resolve():
    n,m,k=list(map(int,input().strip().split()))

    uf = UnionFind(n)

    res=[[] for i in range(n)]
    frd=[0 for i in range(n)]
    blk=[0 for i in range(n)]

    for i in range(m):
        a,b=list(map(int,input().strip().split()))
        a-=1
        b-=1
        uf.Unite(a,b)
        frd[a]+=1
        frd[b]+=1
    
    for i in range(k):
        a,b=list(map(int,input().strip().split()))
        a-=1
        b-=1
        if uf.isSameGroup(a,b):
            blk[a]+=1
            blk[b]+=1
    
    rescnt=[]

    for i in range(n):
        ri=uf.Count(i)-1-blk[i]-frd[i]
        rescnt.append(str(ri))
        
    
    print(" ".join(rescnt))

resolve()

Solution (Python):
import sys
int1 = lambda x: int(x) - 1
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(500000)


class UnionFind(object):

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

    def is_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, readline().split())

uf = UnionFind(N)
f = [0] * N
bl = [0] * N

for _ in range(M):
    a, b = map(int1, readline().split())
    f[a] += 1
    f[b] += 1
    uf.unite(a, b)

for i in range(K):
    c, d = map(int1, readline().split())
    if uf.find(c) == uf.find(d):
        bl[c] += 1
        bl[d] += 1

ans = [0] * N

for i in range(N):
    ans[i] = uf.size(i) - f[i] - bl[i] - 1

print(*ans)

Solution (Python):



from collections import defaultdict
import sys
sys.setrecursionlimit(10**5+10)

def main():
  n, m, k = map(int, input().strip().split())
  friends = defaultdict(lambda :{'children':list(), 'x':-1, 'visited':False})
  blocks = defaultdict(list)
  visited = set()
  
  for _ in range(m):
    a, b = map(int, input().strip().split())
    friends[a]['children'].append(b)
    friends[b]['children'].append(a)

  for _ in range(k):
    c, d = map(int, input().strip().split())
    blocks[c].append((d))
    blocks[d].append((c))
    
  def dfs(i, x):
    friends[i]['x'] = x
    friends[i]['visited'] = True
    count = 1
    for child in friends[i]['children']:
      if friends[child]['visited']:
        continue
      count += dfs(child, x)
    return count
  
  num = 1
  size = dict()
  for i in range(1, n+1):
    if friends[i]['visited']:
      continue
    count = dfs(i, num)
    size[num] = count
    num += 1
    
  ans = []
  for i in range(1, n+1):
    nblock = 0
    for ib in blocks[i]:
      if friends[i]['x'] == friends[ib]['x']:
        nblock += 1
    ans.append(size[friends[i]['x']] - len(friends[i]['children']) - nblock - 1)
  print(' '.join(list(map(str, ans))))
  
if __name__=='__main__':
  main()

Solution (Python):
import sys
from io import StringIO
import unittest

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 
        
        elif(self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            
            if(self.rnk[x] == self.rnk[y]):
                self.rnk[y] += 1
    
    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 resolve():
    n,m,k=list(map(int,input().strip().split()))

    uf = UnionFind(n)

    res=[[] for i in range(n)]
    frd=[[] for i in range(n)]
    blk=[[] for i in range(n)]

    for i in range(m):
        a,b=list(map(int,input().strip().split()))
        a-=1
        b-=1
        uf.Unite(a,b)
        frd[a].append(b)
        frd[b].append(a)
    
    for i in range(k):
        a,b=list(map(int,input().strip().split()))
        a-=1
        b-=1
        
        
        frd[a].append(b)
        frd[b].append(a)
    
    rescnt=[]

    for i in range(n):
        ri=uf.Count(i)-1
        for f in frd[i]:
            if uf.isSameGroup(f,i):
                ri-=1
        rescnt.append(str(ri))
        
    
    print(" ".join(rescnt))

resolve()