Buggy python submission (verdict: Time Limit Exceeded):
from collections import deque

class Graph:
    # n is the number of N
    # E is a set of edges where each edge is a two tuple (u, v)
    def __init__(self, n, E):
        self.N = n # number of vertices
        self.V = list(range(0, n)) # V = [0, 1, ..., n-1]
        self.AL = [set() for i in range(n)] # adjacency list
        for e in E:
            self.add_edge(e[0], e[1])

    def add_edge(self, u, v): # u is head, v is tail
        self.AL[u].add(v)
        self.AL[v].add(u)

# 入力
N, M, K = [int(x) for x in input().split()]
Ef = [-1] * M
Eb = [-1] * K

for i in range(M):
    Ef[i] = [int(x) - 1 for x in input().split()]

for i in range(K):
    Eb[i] = [int(x) - 1 for x in input().split()]

Gf = Graph(N, Ef)   # 友達
Gb = Graph(N, Eb)   # ブロック
ans = [0] * N
visited = [False] * N

for root in range(N):
    if visited[root]: continue
    que = deque()
    que.append(root)
    tree_nodes = set()

    while len(que) > 0:
        u = que.pop()
        visited[u] = True
        tree_nodes.add(u)
        
        for v in Gf.AL[u]:
            if visited[v] or v in que:
                continue
            que.append(v)

    for v in tree_nodes:
        ans[v] = max(0, len(tree_nodes) - 1 - len(Gb.AL[v] & tree_nodes)- len(Gf.AL[v]))

print(" ".join([str(f) for f in ans]))


Fixed submission:
# Union-Find木（サイズ付き）
class UnionFind():
    # 初めは全ての頂点が別々の木の根
    def __init__(self, n):  # n要素で初期化
        self.parent = [None] * n # 親
        self.rank = [None] * n   # 木の深さ
        self._size = [1] * n # 要素が属する集合の大きさ（根の要素のみ参照すること）
        for i in range(n):
            self.parent[i] = i
            self.rank[i] = 0

    # 木の根を求める
    def root_of(self, x):
        children = [x]
        while self.parent[x] != x:
            x = self.parent[x]
            children.append(x)

        for ch in children:
            self.parent[ch] = x

        return x

    # xとyの属する集合を併合
    def unite(self, x, y):
        rx = self.root_of(x)
        ry = self.root_of(y)
        if rx == ry:
            return
        if self.rank[rx] < self.rank[ry]: # ランクの小さい木から大きい木の根に辺を張る
            self.parent[rx] = ry  # rxをryの子とする
            self._size[ry] += self._size[rx]
        else:
            self.parent[ry] = rx
            self._size[rx] += self._size[ry]
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    # 同じ集合に属するかどうか
    def is_same(self, x, y):
        return self.root_of(x) == self.root_of(y)

    # 頂点xが属する集合のサイズ
    def size(self, x):
        return self._size[self.root_of(x)]


# 入力
N, M, K = [int(x) for x in input().split()]

Ef = [[int(x) - 1 for x in input().split()] for _ in range(M)]
Eb = [[int(x) - 1 for x in input().split()] for _ in range(K)]

ans = [0] * N
uf = UnionFind(N)
for i in range(M):
    uf.unite(Ef[i][0], Ef[i][1])
    ans[Ef[i][0]] -= 1  # すでに友達なら友達候補ではない
    ans[Ef[i][1]] -= 1

for i in range(K):
    if uf.is_same(Eb[i][0], Eb[i][1]):
        ans[Eb[i][0]] -= 1  # ブロックしているなら友達候補ではない
        ans[Eb[i][1]] -= 1

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

print(" ".join([str(i) for i in ans]))

Buggy python submission (verdict: Time Limit Exceeded):
from collections import deque

class Graph:
    # n is the number of N
    # E is a set of edges where each edge is a two tuple (u, v)
    def __init__(self, n, E):
        self.N = n # number of vertices
        self.V = list(range(0, n)) # V = [0, 1, ..., n-1]
        self.AL = [set() for i in range(n)] # adjacency list
        for e in E:
            self.add_edge(e[0], e[1])

    def add_edge(self, u, v): # u is head, v is tail
        self.AL[u].add(v)
        self.AL[v].add(u)

# 入力
N, M, K = [int(x) for x in input().split()]
Ef = [-1] * M
Eb = [-1] * K

for i in range(M):
    Ef[i] = [int(x) - 1 for x in input().split()]

for i in range(K):
    Eb[i] = [int(x) - 1 for x in input().split()]

Gf = Graph(N, Ef)   # 友達
Gb = Graph(N, Eb)   # ブロック
ans = [0] * N
visited = [False] * N

for root in range(N):
    if visited[root]: continue
    que = deque()
    que.append(root)
    tree_nodes = set()

    while len(que) > 0:
        u = que.pop()
        visited[u] = True
        tree_nodes.add(u)
        
        for v in Gf.AL[u]:
            if visited[v] or v in que:
                continue
            que.append(v)

    for v in tree_nodes:
        ans[v] = max(0, len(tree_nodes) - 1 - len(Gb.AL[v] & tree_nodes)- len(Gf.AL[v]))

print(" ".join([str(f) for f in ans]))


Fixed submission:
# Union-Find木（サイズ付き）
class UnionFind():
    # 初めは全ての頂点が別々の木の根
    def __init__(self, n):  # n要素で初期化
        self.parent = [None] * n # 親
        self.rank = [None] * n   # 木の深さ
        self._size = [1] * n # 要素が属する集合の大きさ（根の要素のみ参照すること）
        for i in range(n):
            self.parent[i] = i
            self.rank[i] = 0

    # 木の根を求める
    def root_of(self, x):
        children = [x]
        while self.parent[x] != x:
            x = self.parent[x]
            children.append(x)

        for ch in children:
            self.parent[ch] = x

        return x

    # xとyの属する集合を併合
    def unite(self, x, y):
        rx = self.root_of(x)
        ry = self.root_of(y)
        if rx == ry:
            return
        if self.rank[rx] < self.rank[ry]: # ランクの小さい木から大きい木の根に辺を張る
            self.parent[rx] = ry  # rxをryの子とする
            self._size[ry] += self._size[rx]
        else:
            self.parent[ry] = rx
            self._size[rx] += self._size[ry]
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    # 同じ集合に属するかどうか
    def is_same(self, x, y):
        return self.root_of(x) == self.root_of(y)

    # 頂点xが属する集合のサイズ
    def size(self, x):
        return self._size[self.root_of(x)]


# 入力
N, M, K = [int(x) for x in input().split()]

Ef = [[int(x) - 1 for x in input().split()] for _ in range(M)]
Eb = [[int(x) - 1 for x in input().split()] for _ in range(K)]

ans = [0] * N
uf = UnionFind(N)
for i in range(M):
    uf.unite(Ef[i][0], Ef[i][1])
    ans[Ef[i][0]] -= 1  # すでに友達なら友達候補ではない
    ans[Ef[i][1]] -= 1

for i in range(K):
    if uf.is_same(Eb[i][0], Eb[i][1]):
        ans[Eb[i][0]] -= 1  # ブロックしているなら友達候補ではない
        ans[Eb[i][1]] -= 1

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

print(" ".join([str(i) for i in ans]))