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 in Java (OpenJDK 11.0.6) (judge verdict: Accepted)

import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.stream.Collectors;

public class Main {

  public static void main(String[] args) {
    resolve(System.in, System.out);
  }

  static void resolve(InputStream is, PrintStream pw) {
    Scanner sc = new Scanner(is);
    int n = Integer.parseInt(sc.next());
    int m = Integer.parseInt(sc.next());
    int k = Integer.parseInt(sc.next());
    UserService userService = new UserService();
    for (int i = 1; i < n + 1; i++) {
      userService.addUser(new User(i));
    }
    for (int i = 0; i < m; i++) {
      userService.makeFriends(Integer.parseInt(sc.next()), Integer.parseInt(sc.next()));
    }
    for (int i = 0; i < k; i++) {
      userService.makeBlocked(Integer.parseInt(sc.next()), Integer.parseInt(sc.next()));
    }
    pw.println(
      userService.countCandidates().stream()
        .map(String::valueOf)
        .collect(Collectors.joining(" "))
    );
  }

  static class User {

    private int id;
    Set<User> friends = new HashSet<>();
    Set<User> blocked = new HashSet<>();

    public User(int id) {
      this.id = id;
    }

    void addFriends(User user) {
      friends.add(user);
    }

    void visitFriendsChain(Set<User> visitor) {
      Deque<User> dfs = new LinkedList<>();
      dfs.add(this);
      while (!dfs.isEmpty()) {

      }
      for (User friend : friends) {
        if (!visitor.contains(friend)) {
          visitor.add(friend);
          friend.visitFriendsChain(visitor);
        }
      }
    }

    Set<User> resolveGroup() {
      Set<User> group = new HashSet<>();
      group.add(this);
      Deque<User> dfs = new LinkedList<>();
      dfs.add(this);
      while (!dfs.isEmpty()) {
        User u = dfs.removeFirst();
        for (User f : u.friends) {
          if (!group.contains(f)) {
            dfs.addFirst(f);
            group.add(f);
          }
        }
      }
      return group;
    }

    Set<User> friendsChain(Set<User> current) {
      Set<User> newFriends = new HashSet<>(friends);
      newFriends.removeAll(current);
      current.addAll(newFriends);
      Set<User> newFriendsChain = newFriends.stream()
        .map(u -> u.friendsChain(current))
        .flatMap(Set::stream)
        .collect(Collectors.toSet());
      newFriendsChain.remove(this);
      current.addAll(newFriendsChain);
      return current;
    }

    boolean isFriend(User u) {
      return friends.contains(u);
    }

    void addBlocked(User user) {
      blocked.add(user);
    }

    boolean isBlocked(User u) {
      return blocked.contains(u);
    }

    @Override
    public boolean equals(Object o) {
      return this == o;
    }

    @Override
    public int hashCode() {
      return id;
    }
  }

  static class UserService {

    LinkedHashMap<Integer, User> users = new LinkedHashMap<>();

    void addUser(User user) {
      users.put(user.id, user);
    }

    void makeFriends(int a, int b) {
      User userA = users.get(a);
      User userB = users.get(b);
      userA.addFriends(userB);
      userB.addFriends(userA);
    }

    void makeBlocked(int a, int b) {
      User userA = users.get(a);
      User userB = users.get(b);
      userA.addBlocked(userB);
      userB.addBlocked(userA);
    }

    List<Integer> countCandidates() {
      Map<User, Set<User>> chainedUserGroupCache = new HashMap<>();
      for (User user : users.values()) {
        if (chainedUserGroupCache.containsKey(user)) {
          continue;
        }
        Set<User> userGroup = user.resolveGroup();
        for (User groupUser : userGroup) {
          chainedUserGroupCache.put(groupUser, userGroup);
        }
      }
      List<Integer> answer = new ArrayList<>();
      for (User user : users.values()) {
        Set<User> candidate = chainedUserGroupCache.get(user);
        int ans = candidate.size();
        ans -= user.friends.size();
        for (User b : user.blocked) {
          if (candidate.contains(b)) {
            ans--;
          }
        }
        answer.add(ans - 1);
      }
      return answer;
    }
  }
}