Buggy python submission (verdict: Time Limit Exceeded):
from collections import deque
def bfs(G, start):
    label[start] = start
    queue = deque()
    visited = [False] * (len(G))
    queue.append(start)
    while queue:
        target = queue.popleft()
        label[target] = start
        for j in G[target]:
            if visited[j] == False:
                visited[j] = True
                queue.append(j)
    # visited = [k for k, x in enumerate(visited) if x ]
    # return set(visited)

N, M, K = map(int, input().split())
F_G = [[] for _ in range(N)]
B_G = [[] for _ in range(N)]
label = [-1] * N
link = [0] * N
# 無向グラフの作成
for _ in range(M):
    a, b = map(int, input().split())
    link[a-1] += 1
    link[b-1] += 1
    F_G[a-1].append(b-1)
    F_G[b-1].append(a-1)

sub = list(range(N))
# bfsでラベル付けすることで連結成分を作成
for i in sub:
    if label[i] == -1:
        bfs(F_G, i)

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

for i in range(len(link)):
    link[i] -= len(F_G[i])
    num = len([x for x in label if x == label[i]])
    link[i] += (num-len(F_G[i]))-1
print(*link)

Fixed submission:
N,M,K = map(int,input().split())
AB = [tuple(map(int, input().split())) for _ in range(M)]
CD = [tuple(map(int, input().split())) for _ in range(K)]

"""
Union-Find木実装のキモ(計算量削減)
1. Unionの工夫
   マージテク：大きい方を動かさずに小さい方をくっつける
2. Findの工夫
   経路圧縮 : 集合の要素を根に直接つなぎ変える.木をフラットにする.
"""

# Union-Findを用いて連結成分を考える(Union-Find木の実装)
class UnionFind:
    # まずは最初の状態を作る
    def __init__(self, N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * N
        self.count = 0

    # そのノードの根を返す過程で,集合の要素を根に直接つなぎかえる
    def root(self, a):
        if self.parent[a] == a:
            return a
        else:
            self.parent[a] = self.root(self.parent[a])
            return self.parent[a]

    # aとbの根が同じ,つまり同じ連結成分内かどうかを返す
    def is_same(self, a, b):
        return self.root(a) == self.root(b)

    # 連結成分同士を効率的に(rankが大きい方を動かさずにrankが小さい方をくっつける)
    def unite(self, a, b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
        else:
            self.parent[rb] = ra
            if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
        self.count += 1

blocks = [[] for _ in range(N)]
for c, d in CD:
    c, d = c-1, d-1
    blocks[c].append(d)
    blocks[d].append(c)

# friendsは友達の数を保持する
friends = [0] * N
uf = UnionFind(N)
for a,b in AB:
    a, b = a-1, b-1
    friends[a] += 1
    friends[b] += 1
    # aとbが同連結成分内であれば何もする必要がない
    if uf.is_same(a, b): continue
    # 異なれば結合
    uf.unite(a, b)

for i in range(N):
    uf.root(i)

from collections import Counter
ctr = Counter()
for i in range(N):
    r = uf.root(i)
    ctr[r] += 1

ans = []
for i in range(N):
    tmp = ctr[uf.root(i)] - friends[i] -1
    for b in blocks[i]:
        if uf.is_same(i, b):
            tmp -= 1
    ans.append(tmp)
print(*ans)

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

def bfs(G, start):
    label[start] = start
    queue = deque()
    visited = [False] * (len(G))
    queue.append(start)
    while queue:
        target = queue.popleft()
        label[target] = start
        for j in G[target]:
            if visited[j] == False:
                visited[j] = True
                queue.append(j)
    visited = [k for k, x in enumerate(visited) if x ]
    return set(visited)

N, M, K = map(int, input().split())
F_G = [[] for _ in range(N)]
B_G = [[] for _ in range(N)]
label = [-1] * N
# 無向グラフの作成
for _ in range(M):
    a, b = map(int, input().split())
    F_G[a-1].append(b-1)
    F_G[b-1].append(a-1)
for _ in range(K):
    c, d = map(int, input().split())
    B_G[c-1].append(d-1)
    B_G[d-1].append(c-1)

sub = list(range(N))
# bfsでラベル付けすることで連結成分を作成
for i in sub:
    if label[i] == -1:
        bfs(F_G, i)
for i in sub:
    linked_node = [j for j, x in enumerate(label) if x == label[i]]
    linked_num = len(linked_node)
    next_to_num = len(F_G[i])
    block_num = len([k for k in linked_node if k in B_G[i]])
    if i != N-1:
        print(linked_num - next_to_num - block_num - 1, end=" ")
    else:
        print(linked_num - next_to_num - block_num - 1)

Fixed submission:
N,M,K = map(int,input().split())
AB = [tuple(map(int, input().split())) for _ in range(M)]
CD = [tuple(map(int, input().split())) for _ in range(K)]

"""
Union-Find木実装のキモ(計算量削減)
1. Unionの工夫
   マージテク：大きい方を動かさずに小さい方をくっつける
2. Findの工夫
   経路圧縮 : 集合の要素を根に直接つなぎ変える.木をフラットにする.
"""

# Union-Findを用いて連結成分を考える(Union-Find木の実装)
class UnionFind:
    # まずは最初の状態を作る
    def __init__(self, N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * N
        self.count = 0

    # そのノードの根を返す過程で,集合の要素を根に直接つなぎかえる
    def root(self, a):
        if self.parent[a] == a:
            return a
        else:
            self.parent[a] = self.root(self.parent[a])
            return self.parent[a]

    # aとbの根が同じ,つまり同じ連結成分内かどうかを返す
    def is_same(self, a, b):
        return self.root(a) == self.root(b)

    # 連結成分同士を効率的に(rankが大きい方を動かさずにrankが小さい方をくっつける)
    def unite(self, a, b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
        else:
            self.parent[rb] = ra
            if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
        self.count += 1

blocks = [[] for _ in range(N)]
for c, d in CD:
    c, d = c-1, d-1
    blocks[c].append(d)
    blocks[d].append(c)

# friendsは友達の数を保持する
friends = [0] * N
uf = UnionFind(N)
for a,b in AB:
    a, b = a-1, b-1
    friends[a] += 1
    friends[b] += 1
    # aとbが同連結成分内であれば何もする必要がない
    if uf.is_same(a, b): continue
    # 異なれば結合
    uf.unite(a, b)

for i in range(N):
    uf.root(i)

from collections import Counter
ctr = Counter()
for i in range(N):
    r = uf.root(i)
    ctr[r] += 1

ans = []
for i in range(N):
    tmp = ctr[uf.root(i)] - friends[i] -1
    for b in blocks[i]:
        if uf.is_same(i, b):
            tmp -= 1
    ans.append(tmp)
print(*ans)

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

def bfs(G, start):
    label[start] = start
    queue = deque()
    visited = [False] * (len(G))
    queue.append(start)
    while queue:
        target = queue.popleft()
        label[target] = start
        for j in G[target]:
            if visited[j] == False:
                visited[j] = True
                queue.append(j)
    visited = [k for k, x in enumerate(visited) if x ]
    return set(visited)

N, M, K = map(int, input().split())
F_G = [[] for _ in range(N)]
B_G = [[] for _ in range(N)]
label = [-1] * N
# 無向グラフの作成
for _ in range(M):
    a, b = map(int, input().split())
    F_G[a-1].append(b-1)
    F_G[b-1].append(a-1)
for _ in range(K):
    c, d = map(int, input().split())
    B_G[c-1].append(d-1)
    B_G[d-1].append(c-1)

sub = list(range(N))
for i in sub:
    can = list(range(N))
    can.pop(i) # 自分自身を友達候補から削除
    can = set(can)
    can -= set(B_G[i])     # ブロック関係にある人を友達候補から削除
    can -= set(F_G[i])     # 友達関係に既にある人を友達候補から削除
    if label[i] != -1:
        v = [l for l, x in enumerate(label) if x == label[i]]
        v = set(v)
    else:
        v = bfs(F_G, i)    # 友達グラフ上でつながっている友達をsetで取得
    can &= v               # 今の候補と積集合とって完成
    if i != N-1:
        print(len(can), end=" ")
    else:
        print(len(can))

Fixed submission:
N,M,K = map(int,input().split())
AB = [tuple(map(int, input().split())) for _ in range(M)]
CD = [tuple(map(int, input().split())) for _ in range(K)]

"""
Union-Find木実装のキモ(計算量削減)
1. Unionの工夫
   マージテク：大きい方を動かさずに小さい方をくっつける
2. Findの工夫
   経路圧縮 : 集合の要素を根に直接つなぎ変える.木をフラットにする.
"""

# Union-Findを用いて連結成分を考える(Union-Find木の実装)
class UnionFind:
    # まずは最初の状態を作る
    def __init__(self, N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * N
        self.count = 0

    # そのノードの根を返す過程で,集合の要素を根に直接つなぎかえる
    def root(self, a):
        if self.parent[a] == a:
            return a
        else:
            self.parent[a] = self.root(self.parent[a])
            return self.parent[a]

    # aとbの根が同じ,つまり同じ連結成分内かどうかを返す
    def is_same(self, a, b):
        return self.root(a) == self.root(b)

    # 連結成分同士を効率的に(rankが大きい方を動かさずにrankが小さい方をくっつける)
    def unite(self, a, b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
        else:
            self.parent[rb] = ra
            if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
        self.count += 1

blocks = [[] for _ in range(N)]
for c, d in CD:
    c, d = c-1, d-1
    blocks[c].append(d)
    blocks[d].append(c)

# friendsは友達の数を保持する
friends = [0] * N
uf = UnionFind(N)
for a,b in AB:
    a, b = a-1, b-1
    friends[a] += 1
    friends[b] += 1
    # aとbが同連結成分内であれば何もする必要がない
    if uf.is_same(a, b): continue
    # 異なれば結合
    uf.unite(a, b)

for i in range(N):
    uf.root(i)

from collections import Counter
ctr = Counter()
for i in range(N):
    r = uf.root(i)
    ctr[r] += 1

ans = []
for i in range(N):
    tmp = ctr[uf.root(i)] - friends[i] -1
    for b in blocks[i]:
        if uf.is_same(i, b):
            tmp -= 1
    ans.append(tmp)
print(*ans)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import deque
def bfs(G, start):
    queue = deque()
    visited = [False] * (len(G))
    queue.append(start)
    while queue:
        target = queue.popleft()
        for j in G[target]:
            if visited[j] == False:
                visited[j] = True
                queue.append(j)
    visited = [k for k, x in enumerate(visited) if x ]
    return set(visited)

def main():
    N, M, K = map(int, input().split())
    F_G = [[] for _ in range(N)]
    B_G = [[] for _ in range(N)]
    for _ in range(M):
        a, b = map(int, input().split())
        F_G[a-1].append(b-1)
        F_G[b-1].append(a-1)
    for _ in range(K):
        c, d = map(int, input().split())
        B_G[c-1].append(d-1)
        B_G[d-1].append(c-1)
    sub = list(range(N))
    for i in sub:
        can = list(range(N))
        can.pop(i)         # 自分自身を友達候補から削除
        can = set(can)
        can -= set(B_G[i]) # ブロック関係にある人を友達候補から削除
        can -= set(F_G[i]) # 友達関係に既にある人を友達候補から削除
        v = bfs(F_G, i)    # 友達グラフ上でつながっている友達をsetで取得
        can &= v           # 今の候補と積集合とって完成
        if i != N-1:
            print(len(can), end=" ")
        else:
            print(len(can))

if __name__ == "__main__":
    main()

Fixed submission:
N,M,K = map(int,input().split())
AB = [tuple(map(int, input().split())) for _ in range(M)]
CD = [tuple(map(int, input().split())) for _ in range(K)]

"""
Union-Find木実装のキモ(計算量削減)
1. Unionの工夫
   マージテク：大きい方を動かさずに小さい方をくっつける
2. Findの工夫
   経路圧縮 : 集合の要素を根に直接つなぎ変える.木をフラットにする.
"""

# Union-Findを用いて連結成分を考える(Union-Find木の実装)
class UnionFind:
    # まずは最初の状態を作る
    def __init__(self, N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * N
        self.count = 0

    # そのノードの根を返す過程で,集合の要素を根に直接つなぎかえる
    def root(self, a):
        if self.parent[a] == a:
            return a
        else:
            self.parent[a] = self.root(self.parent[a])
            return self.parent[a]

    # aとbの根が同じ,つまり同じ連結成分内かどうかを返す
    def is_same(self, a, b):
        return self.root(a) == self.root(b)

    # 連結成分同士を効率的に(rankが大きい方を動かさずにrankが小さい方をくっつける)
    def unite(self, a, b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
        else:
            self.parent[rb] = ra
            if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
        self.count += 1

blocks = [[] for _ in range(N)]
for c, d in CD:
    c, d = c-1, d-1
    blocks[c].append(d)
    blocks[d].append(c)

# friendsは友達の数を保持する
friends = [0] * N
uf = UnionFind(N)
for a,b in AB:
    a, b = a-1, b-1
    friends[a] += 1
    friends[b] += 1
    # aとbが同連結成分内であれば何もする必要がない
    if uf.is_same(a, b): continue
    # 異なれば結合
    uf.unite(a, b)

for i in range(N):
    uf.root(i)

from collections import Counter
ctr = Counter()
for i in range(N):
    r = uf.root(i)
    ctr[r] += 1

ans = []
for i in range(N):
    tmp = ctr[uf.root(i)] - friends[i] -1
    for b in blocks[i]:
        if uf.is_same(i, b):
            tmp -= 1
    ans.append(tmp)
print(*ans)