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
from io import StringIO
import unittest
import os




class UnionFind:
    def __init__(self, n):
        """
        コンストラクタ
        :要素数 n:
        """
        self.n = n
        
        
        
        self.parents = [-1] * n

    def getroot(self, x):
        """
        所属する集合(ルートの番号)を取得する。
        :調査する要素 x:
        """
        
        if self.parents[x] < 0:
            return x
        else:
            
            
            self.parents[x] = self.getroot(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        """
        2つの要素が所属する集合をを同じ集合に結合する。
        :結合する要素(1つ目) x:
        :結合する要素(2つ目) y:
        """
        
        x = self.getroot(x)
        y = self.getroot(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):
        """
        指定した集合に属する要素数を取得する。
        :調査する集合 x:
        """
        
        return -self.parents[self.getroot(x)]

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

    def members(self, x):
        root = self.getroot(x)
        return [i for i in range(self.n) if self.getroot(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())



def resolve():
    
    
    
    n, m, k = map(int, input().split())
    friends = [list(map(int, input().split())) for i in range(m)]
    blocks = [list(map(int, input().split())) for i in range(k)]

    
    uf = UnionFind(n + 1)

    
    
    omits = [[] for i in range(n + 1)]

    
    for friend in friends:
        uf.union(friend[0], friend[1])

        
        omits[friend[0]].append(friend[1])
        omits[friend[1]].append(friend[0])

    
    for block in blocks:
        
        if uf.is_same(block[0], block[1]):
            omits[block[0]].append(block[1])
            omits[block[1]].append(block[0])

    
    ans = []
    for i in range(1, n + 1):
        
        ans.append(str(uf.size(i) - len(omits[i]) - 1))

    print(" ".join(ans))


class TestClass(unittest.TestCase):
    def assertIO(self, assert_input, output):
        stdout, sat_in = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(assert_input)
        resolve()
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, sat_in
        self.assertEqual(out, output)

    def test_input_1(self):
        test_input = """4 4 1
2 1
1 3
3 2
3 4
4 1"""
        output = """0 1 0 1"""
        self.assertIO(test_input, output)

    def test_input_2(self):
        test_input = """5 10 0
1 2
1 3
1 4
1 5
3 2
2 4
2 5
4 3
5 3
4 5"""
        output = """0 0 0 0 0"""
        self.assertIO(test_input, output)

    def test_input_3(self):
        test_input = """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"""
        output = """1 3 5 4 3 3 3 3 1 0"""
        self.assertIO(test_input, output)

    
    def tes_t_1original_1(self):
        test_input = """データ"""
        output = """データ"""
        self.assertIO(test_input, output)



if __name__ == "__main__":
    if os.environ.get("USERNAME") is None:
        
        resolve()

    else:
        
        unittest.main()

Solution (Python):
from collections import deque
N, M, K = map(int, input().split())
F = [[] for _ in range(N)]
B = [[] for _ in range(N)]


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


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



D = {}

parent = [-1] * N

visited = [False] * N

for root in range(N):
    cnt = 0
    if visited[root]:
        continue

    
    
    stack = [root]
    
    while stack:
        
        n = stack.pop()
        
        if visited[n]:
            continue
        visited[n] = True
        cnt +=1
        
        parent[n] = root

        
        for to in F[n]:
            if visited[to]:
                continue
            
            stack.append(to)
    if cnt!=0:
        D[root]=cnt

ans = [0]*N
for iam in range(N):
    
    tmp_ans = D[parent[iam]]
    tmp_ans -=1
    tmp_ans -= len(F[iam])
    for block in B[iam]:
        if parent[block]==parent[iam] :
            tmp_ans -=1
    ans[iam]=tmp_ans
print(*ans, sep=' ')

Solution (Python):
from collections import deque

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

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

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












alre = [False]*n
parent = [-1]*n
gro = {}
y = deque()

for i in range(n):
    
    
    
    y.append(i)
    leader = i
    cnt = 0 
    while len(y)>0:
        x = y.popleft()
        if parent[x]!=-1:
            continue
            
        parent[x]=leader
        y.extend(cango[x])
        cnt +=1
    if cnt!=0:
        gro[leader]=cnt


ans = [0]*n

for iam in range(n):
    
    tmp_ans = gro[parent[iam]]
    tmp_ans -=1
    tmp_ans -= len(cango[iam])
    for block in cannotgo[iam]:
        if parent[block]==parent[iam] :
            tmp_ans -=1
    ans[iam]=tmp_ans
print(*ans, sep=' ')

Solution (Python):
import sys
f=lambda:tuple(map(int,sys.stdin.readline().split()))
n,m,k=f()
lta=[f() for _ in range(m)]
ltb=[f() for _ in range(k)]
p=[-1]*n
def root(x):
  while p[x]>=0: x=p[x]
  return x
def unite(x,y):
  x,y=root(x),root(y)
  if x==y: return
  if x>y: x,y=y,x
  p[x]+=p[y]
  p[y]=x
def same(x,y):
  return root(x)==root(y)
def size(x):
  return -p[root(x)]
l=[0]*n
for a,b in lta:
  unite(a-1,b-1)
  l[a-1]-=1
  l[b-1]-=1
for c,d in ltb:
  if same(c-1,d-1):
    l[c-1]-=1
    l[d-1]-=1
for i in range(n):
  l[i]+=size(i)-1
print(*l)

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




def solve(N, M, K, ABs, CDs):
    friend_map = [[] for _ in range(N + 1)]
    for a, b in ABs:
        friend_map[a].append(b)
        friend_map[b].append(a)

    block_map = [[] for _ in range(N + 1)]
    for c, d in CDs:
        block_map[c].append(d)
        block_map[d].append(c)

    def dfs(group_num, members, now_n):
        belongs[now_n] = group_num
        members.append(now_n)
        for f in friend_map[now_n]:
            if belongs[f] == -1:
                members = dfs(group_num, members, f)
        return members

    friend_groups = []
    belongs = [-1] * (N + 1)
    for i in range(1, N + 1):
        if belongs[i] == -1:
            m = dfs(len(friend_groups), [], i)
            m.sort()
            friend_groups.append(m)

    ans = ''
    for n in range(1, N + 1):
        block = 0
        group = friend_groups[belongs[n]]
        for b in block_map[n]:
            if belongs[n] == belongs[b]:
                block += 1
        ans += ' ' + str(len(group) - len(friend_map[n]) - block - 1)
    print(ans[1:])


if __name__ == '__main__':
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    N, M, K = map(int, input().split())
    ABs = [[int(i) for i in input().split()] for _ in range(M)]
    CDs = [[int(i) for i in input().split()] for _ in range(K)]
    solve(N, M, K, ABs, CDs)

Solution (Python):
import bisect
import sys
sys.setrecursionlimit(10 ** 6)




def solve(N, M, K, ABs, CDs):
    friend_map = [[] for _ in range(N + 1)]
    for a, b in ABs:
        friend_map[a].append(b)
        friend_map[b].append(a)

    block_map = [[] for _ in range(N + 1)]
    for c, d in CDs:
        block_map[c].append(d)
        block_map[d].append(c)

    
    
    
    
    
    
    

    def dfs(group_num, members, now_n):
        belongs[now_n] = group_num
        members.append(now_n)
        for f in friend_map[now_n]:
            if belongs[f] == -1:
                members = dfs(group_num, members, f)
        return members

    friend_groups = []
    belongs = [-1] * (N + 1)
    for i in range(1, N + 1):
        if belongs[i] == -1:
            m = dfs(len(friend_groups), [], i)
            m.sort()
            friend_groups.append(m)

    
    
    

    
    
    ans = ''
    for n in range(1, N + 1):
        block = 0
        group = friend_groups[belongs[n]]
        for b in block_map[n]:
            
            
            
            
            x = bisect.bisect_left(group, b)
            
            
            if belongs[n] == belongs[b]:
                block += 1
        
        ans += ' ' + str(len(group) - len(friend_map[n]) - block - 1)
    print(ans[1:])


if __name__ == '__main__':
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    N, M, K = map(int, input().split())
    ABs = [[int(i) for i in input().split()] for _ in range(M)]
    CDs = [[int(i) for i in input().split()] for _ in range(K)]
    solve(N, M, K, ABs, CDs)

Solution (Python):

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
    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())
Friend = [[] for _ in range(N)]

par = [-1] * N
for i in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    unite(a, b)
    Friend[a].append(b)
    Friend[b].append(a)

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

Ans = []
for i in range(N):
    ans = size(i) - 1
    ans -= len(Friend[i])
    for b in Block[i]:
        if same(i, b):
            ans -= 1
    Ans.append(str(ans))

print(' '.join(Ans))

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

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

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


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(self, x, y):
        return self.find(x) == self.find(y)


UF = UnionFind(N)
for iam in range(N):
    for friend in F[iam]: 
        UF.union(iam, friend) 

ans = [UF.size[UF.find(iam)] - 1 for iam in range(N)] 

for iam in range(N):
    ans[iam] -= len(F[iam]) 

for iam in range(N):
    for block in B[iam]:
        if UF.same(iam, block): 
            ans[iam] -= 1

print(*ans, sep=' ')

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

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

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


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(self, x, y):
        return self.find(x) == self.find(y)

    
    def all_find(self):
        for n in range(len(self.par)):
            self.find(n)


UF = UnionFind(N)
for iam in range(N):
    for friend in F[iam]: 
        UF.union(iam, friend) 

ans = [UF.size[UF.find(iam)] - 1 for iam in range(N)] 

for iam in range(N):
    ans[iam] -= len(F[iam]) 

for iam in range(N):
    for block in B[iam]:
        if UF.same(iam, block): 
            ans[iam] -= 1

print(*ans, sep=' ')

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

def find(parent, i):
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, t)
    parent[i] = t
    return t


def unite(parent, i, j):
    i = find(parent, i)
    j = find(parent, j)
    if i == j:
        return
    parent[j] += parent[i]
    parent[i] = j

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

parent = [-1] * n
friends = [[] for _ in range(n)]

for a, b in ab:
    unite(parent, a-1, b-1)
    friends[a-1].append(b-1)
    friends[b-1].append(a-1)
    
blocks = [[] for _ in range(n)]
for c, d in cd:
    blocks[c-1].append(d-1)
    blocks[d-1].append(c-1)

result = []

for i in range(n):
    p = find(parent, i)
    t = -parent[p] - 1
    t -= len(friends[i])
    for b in blocks[i]:
        if p == find(parent, b):
            t -= 1
    result.append(t)
    
print(*result)

Solution (Python):
from collections import deque
N,M,K=map(int,input().split())
friend=[deque([]) for _ in range(N+1)]
block=[deque([]) for _ in range(N+1)]
for i in range(M):
  a,b=map(int,input().split())
  friend[a].append(b)
  friend[b].append(a)
for i in range(K):
  c,d=map(int,input().split())
  block[c].append(d)
  block[d].append(c)
stack=deque()
group=[-1]*(N+1)
visited=[-1]*(N+1)
dic={}
for i in range(1,N+1):
  stack.append(i)
  main=i
  cnt=0
  while len(stack)>0:
    now=stack.popleft()
    if group[now]!=-1:
        continue
    stack.extend(friend[now])
    group[now]=main
    cnt+=1
  if cnt!=0:
    dic[main]=cnt

for i in range(1,N+1):
  ans=dic[group[i]]
  ans-=1
  ans-=len(friend[i])
  for j in block[i]:
    if group[j]==group[i]:
      ans-=1
  print(ans)

Solution (Python):
from collections import deque
N, M, K = map(int,input().split())
friendlist = [[] for _ in range(N+1)]
for n in range(M):
    A, B = map(int,input().split())
    friendlist[A].append(B)
    friendlist[B].append(A)

blocklist = [[] for _ in range(N+1)]
for n in range(K):
    C, D = map(int, input().split())
    blocklist[C].append(D)
    blocklist[D].append(C)

whatgroup = [-1 for _ in range(N+1)]
visited = [-1] * (N+1)
d = deque()
leaderdic = {}
for person in range(1,N+1):
    d.append(person)
    leader = person
    cnt = 0
    while len(d)>0:
        nowwho = d.popleft()
        if whatgroup[nowwho] != -1:
            continue
        d.extend(friendlist[nowwho])
        whatgroup[nowwho] = leader
        cnt += 1
    if cnt != 0:
        leaderdic[leader] = cnt
for person in range(1,N+1):
    ans = leaderdic[whatgroup[person]]
    ans -= 1
    ans -= len(friendlist[person])
    for block in blocklist[person]:
        if whatgroup[person]==whatgroup[block]:
            ans -= 1
    print(ans)

Solution (Python):
from collections import deque
N, M, K = map(int,input().split())
friendlist = [[] for _ in range(N+1)]
for n in range(M):
    A, B = map(int,input().split())
    friendlist[A].append(B)
    friendlist[B].append(A)

blocklist = [[] for _ in range(N+1)]
for n in range(K):
    C, D = map(int, input().split())
    blocklist[C].append(D)
    blocklist[D].append(C)

whatgroup = [-1 for _ in range(N+1)]
visited = [-1] * (N+1)
d = deque()
leaderdic = {}
for person in range(1,N+1):
    d.append(person)
    leader = person
    cnt = 0
    while len(d)>0:
        nowwho = d.popleft()
        if whatgroup[nowwho] != -1:
            continue
        d.extend(friendlist[nowwho])
        whatgroup[nowwho] = leader
        cnt += 1
    if cnt != 0:
        leaderdic[leader] = cnt
for person in range(1,N+1):
    ans = leaderdic[whatgroup[person]]
    ans -= 1
    ans -= len(friendlist[person])
    for block in blocklist[person]:
        if whatgroup[person]==whatgroup[block]:
            ans -= 1
    print(ans)

Solution (Python):
def main():
  import sys
  sys.setrecursionlimit(10**5+10)
  N, M, K = map(int,input().split())
  class UnionFind:
      def __init__(self, N):
          self.par = [-1 for i in range(N+1)]
          self.rank = [1]*(N+1)

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

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

      def union(self, x, y):
          x = self.find(x)
          y = self.find(y)

          if self.rank[x] > self.rank[y]:
              self.par[x] += self.par[y]
              self.par[y] = x
          else:
              self.par[y] += self.par[x]
              self.par[x] = y
              if self.rank[x] == self.rank[y]:
                  self.rank[x] += 1

  UF = UnionFind(N)
  friendlist = [[] for _ in range(N+1)]
  for n in range(M):
      A, B = map(int,input().split())
      friendlist[A].append(B)
      friendlist[B].append(A)
      if not UF.same_check(A,B):
          UF.union(A, B)
  blocklist = [[] for _ in range(N+1)]
  for n in range(K):
      C, D = map(int, input().split())
      blocklist[C].append(D)
      blocklist[D].append(C)

  for person in range(1,N+1):
      root = UF.find(person)
      ans = -UF.par[root]-1
      ans -= len(friendlist[person])
      for l in blocklist[person]:
          if UF.same_check(person,l):
              ans -= 1
      print(ans)

if __name__ == '__main__':
  main()

Solution (Python):
import sys
sys.setrecursionlimit(10**5+10)
N, M, K = map(int,input().split())
class UnionFind:
    def __init__(self, N):
        self.par = [-1 for i in range(N+1)]
        self.rank = [1]*(N+1)
    
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]
        
    def same_check(self, x, y):
        return self.find(x) == self.find(y)
    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        
        if self.rank[x] > self.rank[y]:
            self.par[x] += self.par[y]
            self.par[y] = x
        else:
            self.par[y] += self.par[x]
            self.par[x] = y
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

UF = UnionFind(N)
friendlist = [[] for _ in range(N+1)]
for n in range(M):
    A, B = map(int,input().split())
    friendlist[A].append(B)
    friendlist[B].append(A)
    if not UF.same_check(A,B):
        UF.union(A, B)
blocklist = [[] for _ in range(N+1)]
for n in range(K):
    C, D = map(int, input().split())
    blocklist[C].append(D)
    blocklist[D].append(C)

for person in range(1,N+1):
    root = UF.find(person)
    ans = -UF.par[root]-1
    ans -= len(friendlist[person])
    for l in blocklist[person]:
        if UF.same_check(person,l):
            ans -= 1
    print(ans)

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)
friends = [0] * n
blocks = [0] * n

for i in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    uf.union(a, b)
    friends[a] += 1
    friends[b] += 1
for k in range(k):
    c, d = map(int, input().split())
    c -= 1
    d -= 1
    if uf.same(c, d):
        blocks[c] += 1
        blocks[d] += 1
    

for i in range(n):
    print(uf.size(i) - friends[i] - blocks[i] - 1, end=" ")

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

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

    def unite(self, x, y):  
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

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

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


N, M, K = map(int, input().split())
A, B = [0] * M, [0] * M  
C, D = [0] * K, [0] * K  

direct =[[] for _ in range(N)]  
uf = UnionFind(N)  

for i in range(M):
    A[i], B[i] = map(int, input().split())
    A[i] -= 1
    B[i] -= 1
    direct[A[i]].append(B[i])
    direct[B[i]].append(A[i])
    uf.unite(A[i], B[i])

for i in range(K):
    C[i], D[i] = map(int, input().split())
    C[i] -= 1
    D[i] -= 1
    if uf.is_same(C[i], D[i]):
        direct[C[i]].append(D[i])
        direct[D[i]].append(C[i])

ans = [0] * N
for i in range(N):
    ans[i] = uf.group_size(i) - len(direct[i]) - 1
print(*ans)

Solution (Python):
from sys import setrecursionlimit


def find(parent, i):
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, t)
    parent[i] = t
    return t


def unite(parent, i, j):
    i = find(parent, i)
    j = find(parent, j)
    if i == j:
        return
    parent[j] += parent[i]
    parent[i] = j


setrecursionlimit(10 ** 5)


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

parent = [-1] * N
friends = [[] for _ in range(N)]
for A, B in AB:
    unite(parent, A - 1, B - 1)
    friends[A-1].append(B-1)
    friends[B-1].append(A-1)
blocks = [[] for _ in range(N)]
for C, D in CD:
    blocks[C-1].append(D-1)
    blocks[D-1].append(C-1)

result = []
for i in range(N):
    p = find(parent, i)
    t = -parent[p] - 1
    t -= len(friends[i])
    for b in blocks[i]:
        if p == find(parent, b):
            t -= 1
    result.append(t)
print(*result)

Solution (Python):
n,m,k= map(int,input().split())
par = [-1]*n
def findsize(x):
    temp = par[x]
    if temp<0:return -1*temp
    else:return findsize(temp)
def find(x):
    if par[x]<0:return x
    else:
        par[x]=find(par[x])
        return par[x]
def unite(x,y):
    px,py=find(x),find(y)
    if px==py:return False
    else:
        if px<py:px,py=py,px
        par[px]+=par[py]
        par[py]=px
        return True
fl = []
for i in range(m):
    a,b= map(int,input().split())
    unite(a-1,b-1)
    fl.append((a-1,b-1))
bl = []
for i in range(k):
    c,d= map(int,input().split())
    bl.append((c-1,d-1))
points=[0]*n
for i in range(n):points[i]=findsize(find(i))-1
for i in range(m):
    (a1,b1)=fl[i]
    points[a1]-=1
    points[b1]-=1
for i in range(k):
    (c1,d1)=bl[i]
    if find(c1)==find(d1):
        points[c1]-=1
        points[d1]-=1
print(*points)

Solution (Python):


class UnionFind():
        def __init__(self, n):
            self.parents = list(range(n))
            self.size = [1] * 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 union(self, x, y):
            x = self.find(x)
            y = self.find(y)
            if x != y:
                if self.size[x] < self.size[y]:
                    x, y = y,x
                self.parents[y] = x
                self.size[x] += self.size[y]

def main():
    N, M, K = map(int, input().split())
    friend_adj = [[] for _ in range(N)]
    block_adj = [[] for _ in range(N)]
    uf = UnionFind(N)

    for _ in range(M):
        a, b = map(lambda x: int(x)-1, input().split())
        friend_adj[a].append(b)
        friend_adj[b].append(a)
        uf.union(a,b)
    for _ in range(K):
        c, d = map(lambda x: int(x)-1, input().split())
        if uf.find(c) == uf.find(d):
            friend_adj[c].append(d)
            friend_adj[d].append(c)

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

    for i in range(N):
        ans[i] -= len(friend_adj[i])        
        
        
        
    print(*ans)
    
    
    

if __name__ == "__main__":
    main()

Solution (Python):


class UnionFind():
        def __init__(self, n):
            self.parents = list(range(n))
            self.size = [1] * 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 union(self, x, y):
            x = self.find(x)
            y = self.find(y)
            if x != y:
                if self.parents[x] > self.parents[y]:
                    x, y = y,x
                self.parents[y] = x
                self.size[x] += self.size[y]

def main():
    N, M, K = map(int, input().split())
    friend_adj = [[] for _ in range(N)]
    block_adj = [[] for _ in range(N)]
    uf = UnionFind(N)

    for _ in range(M):
        a, b = map(lambda x: int(x)-1, input().split())
        friend_adj[a].append(b)
        friend_adj[b].append(a)
        uf.union(a,b)
    for _ in range(K):
        c, d = map(lambda x: int(x)-1, input().split())
        if uf.find(c) == uf.find(d):
            friend_adj[c].append(d)
            friend_adj[d].append(c)

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

    for i in range(N):
        ans[i] -= len(friend_adj[i])        
        
        
        
    print(*ans)
    
    
    

if __name__ == "__main__":
    main()

Solution (Python):
import sys
sys.setrecursionlimit(10**7)
n , m , k = map(int, input().split())
r = [[] for i in range(n)]
bk = [[] for i in range(n)]
for i in range(m):
    a , b = map(int, input().split())
    r[a-1].append(b-1)
    r[b-1].append(a-1)
for i in range(k):
    c , d = map(int, input().split())
    bk[c-1].append(d-1)
    bk[d-1].append(c-1)


v=[0]*n
l=[0]*n
w=[0]*n

def dfs(now,c):
    global ln
    if v[now]==1:
        return
    v[now]=1
    ln+=1
    w[now]=c
    l[c]=ln
    for i in r[now]:
        dfs(i,c)
    return

for i in range(n):
    ln=0
    dfs(i,i)

ans =[]
for i in range(n):
    d=0
    for j in bk[i]:
        if w[j]==w[i]:
            d+=1
    ans.append(str(l[w[i]]-1-d-len(r[i])))
print(' '.join(ans))