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):
class UnionFind:
    def __init__(self, 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

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

uf = UnionFind(N)
friend_suggested = [-1] * N


for i in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    friend_suggested[a] -= 1
    friend_suggested[b] -= 1
    uf.union(a, b)
for i in range(K):
    c, d = map(int, input().split())
    c -= 1
    d -= 1
    if uf.find(c) == uf.find(d):
        friend_suggested[c] -= 1
        friend_suggested[d] -= 1

for i in range(N):
    parent_size = -uf.parents[uf.find(i)]
    friend_suggested[i] += parent_size
print(*friend_suggested)

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


from collections import defaultdict
 
n, m, k = map(int, input().split())
uf = UnionFind(n+1)
friends = defaultdict(int)
block = defaultdict(int)


for _ in range(m):
    a, b = map(int, input().split())
    uf.union(a, b)
    friends[a] += 1
    friends[b] += 1



for _ in range(k):
    c, d = map(int, input().split())
    if uf.find(c) == uf.find(d):
        block[c] += 1
        block[d] += 1



ans = []
for i in range(1, n+1):
    group_sise = uf.size(i)
    friend_size = friends[i]
    block_size = block[i]
    ans.append(group_sise - friend_size - block_size - 1)
print(*ans)

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

def main():
    N,M,K = map(int,input().split())
    friend = [[] for _ in range(N)]
    for _ in range(M):
        a,b = map(int,input().split())
        friend[a-1].append(b-1)
        friend[b-1].append(a-1)
        
    brock = [[] for _ in range(N)]
    for _ in range(K):
        c,d = map(int,input().split())
        brock[c-1].append(d-1)
        brock[d-1].append(c-1)
        
    parent = [-1 for _ in range(N)]
    group = [0 for _ in range(N)]
    
    for i in range(N):
        put = []
        if parent[i] == -1:
            q = deque([i])
            parent[i] = i
            while q:
                now = q.pop()
                put.append(now)
                for fol in friend[now]:
                    if parent[fol] == -1:
                        parent[fol] = i
                        q.append(fol)
            l = len(put)
            for num in put:
                group[num] = l-1
                
        else:
            continue

    for i in range(N):
        group[i] -= len(friend[i])
        for dis in brock[i]:
            if parent[i] == parent[dis]:
                group[i] -= 1
    
    print(*group)
    
if __name__ == "__main__":
    main()

Solution (Python):
from collections import Counter


class UnionFind:
    def __init__(self, n):
        self.n = n
        self.p = [e for e in range(n)]
        self.rank = [0] * n

    def same(self, u, v):
        return self.find_set(u) == self.find_set(v)

    def unite(self, u, v):
        self.link(self.find_set(u), self.find_set(v))

    def find_set(self, u):
        if u != self.p[u]:
            self.p[u] = self.find_set(self.p[u])

        return self.p[u]

    def link(self, u, v):
        if self.rank[u] > self.rank[v]:
            self.p[v] = u
        else:
            self.p[u] = v
            if self.rank[u] == self.rank[v]:
                self.rank[v] += 1

    def update_p(self):
        for u in range(self.n):
            self.find_set(u)


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

uf = UnionFind(n)

for a, b in ab:
    a -= 1
    b -= 1
    uf.unite(a, b)

uf.update_p()

counter = Counter(uf.p)

ans = [counter[uf.p[i]] - 1 for i in range(n)]


def f(li):
    for e1, e2 in li:
        e1 -= 1
        e2 -= 1
        if uf.same(e1, e2):
            ans[e1] -= 1
            ans[e2] -= 1


f(ab)
f(cd)

print(*ans)

Solution (Python):
from collections import Counter


class UnionFind:
    def __init__(self, x):
        self.p = [e for e in range(x)]
        self.rank = [0] * x

    def same(self, u, v):
        return self.find_set(u) == self.find_set(v)

    def unite(self, u, v):
        self.link(self.find_set(u), self.find_set(v))

    def find_set(self, u):
        if u != self.p[u]:
            self.p[u] = self.find_set(self.p[u])

        return self.p[u]

    def link(self, u, v):
        if self.rank[u] > self.rank[v]:
            self.p[v] = u
        else:
            self.p[u] = v
            if self.rank[u] == self.rank[v]:
                self.rank[v] += 1


n, m, k = map(int, input().split())
ab = [list(map(int, input().split())) for _ in range(m)]
cd = [list(map(int, input().split())) for _ in range(k)]

uf = UnionFind(n)

for a, b in ab:
    a -= 1
    b -= 1
    uf.unite(a, b)

for i in range(n):
    uf.find_set(i)

counter = Counter(uf.p)

ans = [counter[uf.p[i]] - 1 for i in range(n)]


def f(li):
    for e1, e2 in li:
        e1 -= 1
        e2 -= 1
        if uf.same(e1, e2):
            ans[e1] -= 1
            ans[e2] -= 1


f(ab)
f(cd)

print(*ans)

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

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
        self.group = [set() for _ in range(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)
        if not self.group[root]:
            for i in range(self.n):
                if self.find(i) == root:
                    self.group[root].add(i)
        return self.group[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 main():
    N, M, K = map(int, input().split())
    uni = UnionFind(N)
    not_cand = [0] * N
    for _ in range(M):
        A, B = map(int, input().split())
        A -= 1
        B -= 1
        not_cand[A] += 1
        not_cand[B] += 1
        uni.union(A,B)
 
    for _ in range(K):
        C, D = map(int, input().split())
        C -= 1
        D -= 1
        if uni.same(C,D):
            not_cand[C] += 1
            not_cand[D] += 1
            
    
    ans = [0] * N
    for i in range(N):
        ans[i] = uni.size(i) - not_cand[i] - 1
    
    print(*ans)
 
 
if __name__ == "__main__":
    main()

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

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

class UnionFindTree:
    def __init__(self, n):
        self.parent = [-1 for _ in range(n)]

    def root(self, x):
        p, seq = self.parent[x], list()
        while p >= 0:
            seq.append(x)
            x, p = p, self.parent[p]
        for c in seq: self.parent[c] = x
        return x

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

    def count(self, x): return -self.parent[self.root(x)]

    def unite(self, x, y):
        if self.count(x) < self.count(y): x, y = y, x
        xr, yr = self.root(x), self.root(y)
        if xr == yr: return
        self.parent[xr] += self.parent[yr]
        self.parent[yr] = xr

friend_or_block = [set() for _ in range(N)]
friends_chain = UnionFindTree(N)

for _ in range(M):
    a, b = map(int, input().split())
    a, b = a-1, b-1
    friends_chain.unite(a, b)
    friend_or_block[a].add(b)
    friend_or_block[b].add(a)

for _ in range(K):
    c, d = map(int, input().split())
    c, d = c-1, d-1
    if friends_chain.same(c, d):
        friend_or_block[c].add(d)
        friend_or_block[d].add(c)

print(' '.join(map(str, [friends_chain.count(i) - len(friend_or_block[i]) - 1 for i in range(N)])))

Solution (Python):

class UnionFind:
    __slots__ = ["_size", "_first_idx", "_parents"]

    def __init__(self, size: int, first_index: int = 0) -> None:
        self._size = size
        self._first_idx = first_index
        self._parents = [-1] * (size + first_index)

    def find(self, x: int) -> int:
        """Find the group (root) of vertex x"""
        if self._parents[x] < 0:
            return x
        self._parents[x] = self.find(self._parents[x])
        return self._parents[x]

    def is_same(self, x: int, y: int) -> bool:
        """Return whether two vertices x and y are in the same group or not."""
        return self.find(x) == self.find(y)

    def unite(self, x: int, y: int) -> None:
        """Unite two groups of vertices x and y."""
        x, y = self.find(x), 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: int) -> int:
        """Get the size of the group vertex x belongs"""
        return -self._parents[self.find(x)]


def main():
    N, M, K, *ABCD = map(int, open(0).read().split())
    AB, CD = ABCD[:2 * M], ABCD[2 * M:]
    relationships = UnionFind(N, 1)
    non_candidates = [1] * (N + 1)  
    for a, b in zip(*[iter(AB)] * 2):
        relationships.unite(a, b)
        non_candidates[a] += 1
        non_candidates[b] += 1
    for c, d in zip(*[iter(CD)] * 2):
        if relationships.is_same(c, d):
            non_candidates[c] += 1
            non_candidates[d] += 1
    ans = [relationships.get_size(i) - non_candidates[i] for i in range(1, N + 1)]
    print(" ".join(map(str, ans)))


if __name__ == "__main__":
    main()

Solution (Python):

class UnionFind:
    __slots__ = ["_size", "_first_idx", "_parents"]

    def __init__(self, size: int, first_index: int = 0) -> None:
        self._size = size
        self._first_idx = first_index
        self._parents = [-1] * (size + first_index)

    def find(self, x: int) -> int:
        """Find the group (root) of vertex x"""
        if self._parents[x] < 0:
            return x
        self._parents[x] = self.find(self._parents[x])
        return self._parents[x]

    def is_same(self, x: int, y: int) -> bool:
        """Return whether two vertices x and y are in the same group or not."""
        return self.find(x) == self.find(y)

    def unite(self, x: int, y: int) -> None:
        """Unite two groups of vertices x and y."""
        x, y = self.find(x), 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: int) -> int:
        """Get the size of the group vertex x belongs"""
        return -self._parents[self.find(x)]


def main():
    N, M, K, *ABCD = map(int, open(0).read().split())
    AB, CD = ABCD[:2 * M], ABCD[2 * M:]
    relationships = UnionFind(N, 1)
    friends, blocked = [0] * (N + 1), [0] * (N + 1)
    for a, b in zip(*[iter(AB)] * 2):
        relationships.unite(a, b)
        friends[a] += 1
        friends[b] += 1
    for c, d in zip(*[iter(CD)] * 2):
        if relationships.is_same(c, d):
            blocked[c] += 1
            blocked[d] += 1
    ans = [relationships.get_size(i) - friends[i] - blocked[i] - 1 for i in range(1, N + 1)]
    print(" ".join(map(str, ans)))


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())
not_ans = [1 for i in range(n)]
ans = [0 for i in range(n)]
unions = UnionFind(n)
for i in range(m):
    a,b = map(int, input().split())
    not_ans[a-1] += 1
    not_ans[b-1] += 1
    unions.union(a-1, b-1)
for i in range(k):
    a,b = map(int, input().split())
    if unions.same(a-1, b-1):
        not_ans[a-1] += 1
        not_ans[b-1] += 1
for i in range(n):
    ans[i] = unions.size(i) - not_ans[i]
print(*ans)

Solution (Python):
def root(x):
  while par[x]>=0:x=par[x]
  return x
def unite(x,y):
  x,y=root(x),root(y)
  if x!=y:
    if x>y:x,y=y,x
    par[x]+=par[y]
    par[y]=x
def same(x,y):
  return root(x)==root(y)
def size(x):
  return-par[root(x)]
n,m,k,*t=map(int,open(0).read().split())
par=[-1]*n
f=[set()for _ in range(n)]
for a,b in zip(*[iter(t[:m*2])]*2):
  a-=1
  b-=1
  unite(a,b)
  f[a].add(b)
  f[b].add(a)
a=[size(i)-len(f[i])-1for i in range(n)]
for c,d in zip(*[iter(t[m*2:])]*2):
  c-=1
  d-=1
  if same(c,d):
    a[c]-=1
    a[d]-=1
print(*a)

Solution (Python):
def root(x):
  while par[x]>=0:x=par[x]
  return x
def unite(x,y):
  x,y=root(x),root(y)
  if x!=y:
    if x>y:x,y=y,x
    par[x]+=par[y]
    par[y]=x
def same(x,y):
  return root(x)==root(y)
def size(x):
  return-par[root(x)]
n,m,k,*t=map(int,open(0).read().split())
par=[-1]*n
f=[set()for _ in range(n)]
for a,b in zip(*[iter(t[:m*2])]*2):
  a-=1
  b-=1
  unite(a,b)
  f[a].add(b)
  f[b].add(a)
a=[size(i)-len(f[i])-1for i in range(n)]
for c,d in zip(*[iter(t[m*2:])]*2):
  c-=1
  d-=1
  if same(c,d):
    a[c]-=1
    a[d]-=1
print(*a)

Solution (Python):






import sys

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

ipti = sys.stdin.readline
MOD = 10 ** 9 + 7
INF = float('INF')
sys.setrecursionlimit(10 ** 5)

def main():
    n, m, k = list(map(int,ipti().split()))
    r = UnionFind(n)
    rr = [0] * n
    fr = [[0] * 2 for _ in range(m)]
    bl = [[0] * 2 for _ in range(k)]

    for i in range(m):
        a, b = list(map(int,ipti().split()))
        fr[i][0] = a - 1
        fr[i][1] = b - 1
        r.union(fr[i][0], fr[i][1])

    for i in range(k):
        a, b = list(map(int,ipti().split()))
        bl[i][0] = a - 1
        bl[i][1] = b - 1

    for i in range(m):
        a, b = fr[i][0], fr[i][1]
        if r.same(a, b):
            rr[a] += 1
            rr[b] += 1

    for i in range(k):
        a, b = bl[i][0], bl[i][1]
        if r.same(a, b):
            rr[a] += 1
            rr[b] += 1

    ans = [0] * n

    for i in range(n):
        ans[i] = r.size(i) - rr[i] - 1

    print(*ans)

if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.readline
n, m, k = map(int,input().split())
A = [list(map(int,input().split())) for i in range(m)]
B = [list(map(int,input().split())) for i in range(k)]


for i in range(m):
    for j in range(2):
        A[i][j] -= 1
for i in range(k):
    for j in range(2):
        B[i][j] -= 1


 
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
 
    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]
 
    def size(self, x):
        return -self.parents[self.find(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 n_cc(self):  
        A = [i for i in self.parents if i < 0]
        return len(A)
 
U = UnionFind(n)
for i in range(m):
    a = A[i][0]
    b = A[i][1]
    U.union(a, b)
C = [0] * n
 
for i in range(m):
    a = A[i][0]
    b = A[i][1]
    C[a] -= 1
    C[b] -= 1
for i in range(k):
    a = B[i][0]
    b = B[i][1]
    if U.find(a) == U.find(b):
        C[a] -= 1
        C[b] -= 1

ANS = []
for i in range(n):
    ANS.append(U.size(i) + C[i] - 1)
print(" ".join([str(i) for i in ANS]))

Solution (Python):
import sys
input = sys.stdin.readline
n, m, k = map(int,input().split())
A = [list(map(int,input().split())) for i in range(m)]
B = [list(map(int,input().split())) for i in range(k)]


for i in range(m):
    for j in range(2):
        A[i][j] -= 1
for i in range(k):
    for j in range(2):
        B[i][j] -= 1


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

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

    def size(self, x):
        
        if self.parents[x] < 0:
            return -self.parents[x]  
        
        
        
        
        
        else:
            self.parents[x] = -self.size(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 n_cc(self):  
        A = [i for i in self.parents if i < 0]
        return len(A)
 
U = UnionFind(n)
for i in range(m):
    a = A[i][0]
    b = A[i][1]
    U.union(a, b)
C = [0] * n
 
for i in range(m):
    a = A[i][0]
    b = A[i][1]
    C[a] -= 1
    C[b] -= 1
for i in range(k):
    a = B[i][0]
    b = B[i][1]
    if U.find(a) == U.find(b):
        C[a] -= 1
        C[b] -= 1

ANS = []
for i in range(n):
    ANS.append(U.size(i) + C[i] - 1)
print(" ".join([str(i) for i in ANS]))

Solution (Python):
import sys
input = sys.stdin.readline
 
n,m,k = map(int,input().split())
ab = [set() for _ in range(n)]
cd = [[] * n for _ in range(n)]

 

 

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

for _ in range(m):
    a, b = [int(x) for x in input().split()]
    unite(a - 1, b - 1)
    ab[a - 1].add(b - 1)
    ab[b - 1].add(a - 1)

for i in range(k):
    c, d = [int(x) for x in input().split()]
    if same(c - 1, d - 1):
        cd[c - 1].append(d - 1)
        cd[d - 1].append(c - 1)

ans = [0] * n

for i in range(n):
    ans[i] = size(i) - 1 - len(cd[i]) - len(ab[i])

print(*ans)

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)]
con = [1 for _ in range(n+1)]
uni = [-1 for i in range(n+1)]
rank = [0 for _ in range(n+1)]

def root(num, pea):
    if pea[num] < 0:
        return num
    else:
        pea[num] = root(pea[num], pea)
        return pea[num]

for i in range(m):
    a, b = ab[i]
    con[a] += 1
    con[b] += 1
    root_a = root(a, uni)
    root_b = root(b, uni)
    if root_a!=root_b:
        if rank[root_a] < rank[root_b]:
            uni[root_b] += uni[root_a]
            uni[root_a] = root_b
        else:
            uni[root_a] += uni[root_b]
            uni[root_b] = root_a
            if rank[root_a] == rank[root_b]:
                rank[root_a] += 1


for i in range(k):
    c, d = cd[i]
    if root(c, uni) == root(d, uni):
        con[c] += 1
        con[d] += 1

result = []
for i in range(1, n+1):
    root_i = root(i, uni)
    result.append(-uni[root_i]-con[i])
print(*result)

Solution (Python):
import sys
input = sys.stdin.readline
 
n,m,k = map(int,input().split())
ab = [set() for _ in range(n)]
cd = [[] * n for _ in range(n)]

 

 

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

for _ in range(m):
    a, b = [int(x) for x in input().split()]
    unite(a - 1, b - 1)
    ab[a - 1].add(b - 1)
    ab[b - 1].add(a - 1)

for i in range(k):
    c, d = [int(x) for x in input().split()]
    if same(c - 1, d - 1):
        cd[c - 1].append(d - 1)
        cd[d - 1].append(c - 1)

ans = [0] * n

for i in range(n):
    ans[i] = size(i) - 1 - len(cd[i]) - len(ab[i])

print(*ans)

Solution (Python):
class UnionFind:
    def __init__(self, nodes):
        self.sets = [None] * len(nodes)
        self.sizes = [1] * len(nodes)

    def find(self, a):
        curr = a
        path = []
        while self.sets[curr] is not None:
            path.append(curr)
            curr = self.sets[curr]

        for node in path:
            self.sets[node] = curr
        return curr

    def connected(self, a, b):
        return self.find(a) == self.find(b)

    def union(self, a, b):
        rootA = self.find(a)
        rootB = self.find(b)

        if rootA != rootB:
            self.sets[rootB] = rootA
            self.sizes[rootA] += self.sizes[rootB]

    def size(self, a):
        root = self.find(a)
        return self.sizes[root]


if __name__ == '__main__':
    n, m, k = tuple([int(s) for s in input().split()])
    users = [None] * n
    uf = UnionFind(users)

    friendships = [0 for i in range(n)]
    blockships = [0 for i in range(n)]

    for i in range(m):
        a, b = tuple([int(s) for s in input().split()])
        a -= 1
        b -= 1
        friendships[a] += 1
        friendships[b] += 1
        uf.union(a, b)
        uf.find(a)
        uf.find(b)
    for i in range(k):
        a, b = tuple([int(s) for s in input().split()])
        a -= 1
        b -= 1
        if uf.connected(a, b):
            blockships[a] += 1
            blockships[b] += 1

    res = [0] * n
    for i in range(n):
        all_connections = uf.size(i)
        existing = friendships[i]
        blocked = blockships[i]
        res[i] = all_connections - 1 - existing - blocked

    print(" ".join([str(u) for u in res]))

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


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)]
con = [1 for _ in range(n+1)]
uni = UnionFind(n+1)


for i in range(m):
    a, b = ab[i]
    con[a] += 1
    con[b] += 1
    uni.Unite(a, b)

for i in range(k):
    c, d = cd[i]
    if uni.isSameGroup(c,d):
        con[c] += 1
        con[d] += 1

result = []
for i in range(1, n+1):
    result.append(uni.Count(i)-con[i])
print(*result)

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

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

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

        if abs(x) < abs(y): 
            x, y = y, x 
        self.rank[x] += self.rank[y]
        self.rank[y] = x

    def same(self, x, y):
        return self.find(x) == self.find(y)
    
    def size(self, x):
        return -self.rank[self.find(x)]

n,m,k=map(int, input().split())
uf=UnionFind(n)
friend = [0]*n
for i in range(m):
    a,b=map(int, input().split())
    friend[a-1] +=1
    friend[b-1] +=1
    uf.union(a-1,b-1)

block = [[] for _ in range(n)]
for i in range(k):
    x,y=map(int, input().split())
    block[x-1].append(y-1)
    block[y-1].append(x-1)

ans = [0]*n
for i in range(n):
    ans[i] = uf.size(i)-1-friend[i]
    for j in block[i]:
        if uf.same(i,j):
            ans[i] -= 1
    ans[i] = str(ans[i])
    
print(" ".join(ans))