Problem: 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?

Submission attempts (in order):
    class union_find():
        def __init__(self, n):
            self.par = [i for i in range(n + 1)]
            self.rank = [1 for i in range(n + 1)]
            self.size = [1 for i in range(n + 1)]
     
        def find(self, c):
            if self.par[c] == c:
                return c
     
            ret = self.find(self.par[c])
            self.par[c] = ret
            return ret
     
        def union(self, x, y):
     
            xr = self.find(x)
            yr = self.find(y)
            if xr == yr:
                return
     
            if self.rank[yr] > self.rank[xr]:
                self.par[xr] = yr
            else:
                self.par[yr] = xr
                self.size[xr] += self.size[yr]
                if self.rank[xr] == self.rank[yr]:
                    self.rank[xr] += 1
     
        def mass_size(self):
            return [i == v for i, v in enumerate(self.par)].count(True) - 1
        
        def size_belong(self, i):
        	return self.size[self.find(i)]
     
        def show(self):
            print('parent', self.par[1:])
            print('rank', self.rank[1:])
     
    def main():
        from collections import defaultdict
     
        dicf = defaultdict(lambda :[])
        dicb = defaultdict(lambda :[])
     
        N, M, K = map(int, input().split())
     
        uf = union_find(N)
        for i in range(M):
            a, b = map(int, input().split())
            dicf[a].append(b)
            dicf[b].append(a)
            if a > b:
                a, b = b, a
            uf.union(a, b)
     
        for i in range(K):
            c, d = map(int, input().split())
            dicb[c].append(d)
            dicb[d].append(c)
     
        ans = []
        for i in range(1, N + 1):
            x = uf.size_belong(i) - len(dicf[i]) - 1
            m = 0
            for b in dicb[i]:
                if uf.find(b) == uf.find(i):
                    m += 1
     
            ans.append(x - m)
     
     
        print(' '.join(map(str, ans)))
     
     
     
     
    if __name__ == '__main__':
        main()

class union_find():
    __slots__ = ["par", "rank", "size"]
    def __init__(self, n):
        self.par = [i for i in range(n + 1)]
        self.rank = [1 for i in range(n + 1)]
        self.size = [1 for i in range(n + 1)]

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

        ret = self.find(self.par[c])
        self.par[c] = ret
        return ret

    def union(self, x, y):

        xr = self.find(x)
        yr = self.find(y)
        if xr == yr:
            return

        if self.rank[yr] > self.rank[xr]:
            self.par[xr] = yr
            self.size[yr] += self.size[xr]
        else:
            self.par[yr] = xr
            self.size[xr] += self.size[yr]
            if self.rank[xr] == self.rank[yr]:
                self.rank[xr] += 1

    def size_belong(self, i):
        return self.size[self.find(i)]

    def mass_size(self):
        return [i == v for i, v in enumerate(self.par)].count(True) - 1

    def show(self):
        print('parent', self.par[1:])
        print('rank', self.rank[1:])

def main():
    from collections import defaultdict

    dicf = defaultdict(lambda :[])
    dicb = defaultdict(lambda :[])

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

    uf = union_find(N)
    for i in range(M):
        a, b = map(int, input().split())
        dicf[a].append(b)
        dicf[b].append(a)
        if a > b:
            a, b = b, a
        uf.union(a, b)

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

    ans = []
    for i in range(1, N + 1):
        x = uf.size_belong(i) - len(dicf[i]) - 1
        m = 0
        for b in dicb[i]:
            if uf.find(b) == uf.find(i):
                m += 1

        ans.append(x - m)


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




if __name__ == '__main__':
    main()

Verdicts: Runtime Error

Accepted