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 Rust (1.15.1) (judge verdict: Time Limit Exceeded)

use std::io::*;
use std::str::FromStr;
use std::cmp::Ordering;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char) 
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

pub trait BinarySearch<T> {
    fn lower_bound(&self, x: &T) -> usize;
    fn upper_bound(&self, x: &T) -> usize;
    fn bsearch(&self, x: &T) -> Option<usize>;
}

impl<T: Ord> BinarySearch<T> for [T] {
    fn lower_bound(&self, x: &T) -> usize {
        let mut low = 0;
        let mut high = self.len();

        while low != high {
            let mid = (low + high) / 2;
            match self[mid].cmp(x) {
                Ordering::Less => {
                    low = mid + 1;
                }
                Ordering::Equal | Ordering::Greater => {
                    high = mid;
                }
            }
        }
        low
    }

    fn upper_bound(&self, x: &T) -> usize {
        let mut low = 0;
        let mut high = self.len();

        while low != high {
            let mid = (low + high) / 2;
            match self[mid].cmp(x) {
                Ordering::Less | Ordering::Equal => {
                    low = mid + 1;
                }
                Ordering::Greater => {
                    high = mid;
                }
            }
        }
        low
    }

    fn bsearch(&self, x: &T) -> Option<usize> {
        let lower_idx = self.lower_bound(x);
        if lower_idx < self.len() && self[lower_idx] == *x {
            return Some(lower_idx);
        }
        return None;
    }
}

fn is_friend_rel(friend_map: Vec<Vec<usize>>, idx: usize, target: usize, searched: Vec<usize>) -> bool {
    let mut searched = searched.clone();

    fn _is_friend_rel(friend_map: Vec<Vec<usize>>, idx: usize, target: usize, searched: &mut Vec<usize>) -> bool {
        // println!("{} {}", idx, target);
        // println!("{:?}", *searched);
        for node in friend_map[idx].iter() {
            if *node == target {
                return true;
            }
    
            let lower = searched.lower_bound(node);
            if lower < searched.len() && searched[lower] == *node {
                continue;
            }
    
            searched.insert(lower, *node);
            if _is_friend_rel(friend_map.clone(), *node, target, searched) {
                return true;
            }
        }
        return false;
    }
    return _is_friend_rel(friend_map, idx, target, &mut searched);
}

fn main() {
    let n: usize = read();
    let m: usize = read();
    let k: usize = read();

    let mut ai: Vec<usize> = Vec::new();
    let mut bi: Vec<usize> = Vec::new();
    for _ in 0..m {
        ai.push(read());
        bi.push(read());
    }

    let mut ci: Vec<usize> = Vec::new();
    let mut di: Vec<usize> = Vec::new();
    for _ in 0..k {
        ci.push(read());
        di.push(read());
    }

    let mut friend_map: Vec<Vec<usize>> = (0..n+1).map(|_| Vec::new()).collect();
    let mut block_map: Vec<Vec<usize>> = (0..n+1).map(|_| Vec::new()).collect();
    for i in 0..m {
        friend_map[ai[i]].push(bi[i]);
        friend_map[bi[i]].push(ai[i]);
    }
    for i in 0..k {
        block_map[ci[i]].push(di[i]);
        block_map[di[i]].push(ci[i]);
    }

    // println!("{:?}", friend_map);
    // println!("{:?}", block_map);
    let mut ans: Vec<usize> = (0..n+1).map(|_| 0).collect();
    for i in 1..n+1 {
        block_map[i].sort();
        friend_map[i].sort();
        for j in i+1..n+1 {
            // println!("{} {}", i, j);
            if block_map[i].bsearch(&j).is_some() {
                // println!("ブロック");
                continue;
            }
            if friend_map[i].bsearch(&j).is_some() {
                // println!("友達");
                continue;
            }
            if is_friend_rel(friend_map.clone(), i, j, Vec::new()) {
                // println!("友達関係");
                ans[i] += 1;
                ans[j] += 1;
            }
        }
    }

    let ans: Vec<String> = ans.into_iter().skip(1).map(|i| i.to_string()).collect();
    println!("{}", ans.join(" "));
}