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: Accepted)

use std::vec::Vec;

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace().map(|e| e.parse().ok().unwrap()).collect()
}

fn read_touple<T: std::str::FromStr + Copy>() -> (T, T) {
  let v: Vec<T> = read_vec();
  assert_eq!(v.len(), 2);
  (v[0], v[1])
}

fn read_touple3<T: std::str::FromStr + Copy>() -> (T, T, T) {
  let v: Vec<T> = read_vec();
  assert_eq!(v.len(), 3);
  (v[0], v[1], v[2])
}

fn main() {
    let (n, m, k) = read_touple3::<usize>();
    let mut ab = vec![];
    let mut cd = vec![];
    for _ in 0..m {
      let (a, b) = read_touple::<i64>();
      ab.push((a-1, b-1));
    }

    for _ in 0..k {
      let (c, d) = read_touple::<i64>();
      cd.push((c-1, d-1));
    }

    let mut friend = UnionFind::new(n);
    let mut block = UnionFind::new(n);
    let mut count_frend = vec![0; n];
    // 友達関係をつなげる
    for &(a, b) in &ab {
      friend.connect(a, b);
      count_frend[a as usize] += 1;
      count_frend[b as usize] += 1;
    }

    let mut ans = vec![0; n];

    for i in 0..n {
      ans[i] = friend.size(i as i64) - count_frend[i] - 1;
    }
    
    for &(c, d) in &cd {
      if friend.connected(c, d) {
         ans[c as usize] -= 1;
         ans[d as usize] -= 1;
      }
    }

    for a in ans {
      print!("{} ", a);
    }

    println!("");
}

pub struct UnionFind {
  // 親のノードの番号を書くのする。親だった場合は-(その集合のサイズ)
  pub parent: Vec<i64>,
}

// サポートしているメソッド
// root(a: i64) :: 属している木の値を返す.
// size(a: i64) :: 自分の属してるグループの頂点数を返す
// connect(a: i64, b: i64) :: aとbを接続する
// equal(a: i64, b: i64) :: a と　b　の属してるグループが等しいか返す
// connected(a: i64, b: i64) :: aとbが接続してるか判定する

impl UnionFind {
  // コンストラクター
  pub fn new(n: usize) -> UnionFind {
    return UnionFind {parent: vec![-1; n]};
  }

  // aがどのグループに属しているか調べる
  // 属している木の根を返す
  // 帰り際に要素を直接、根に接続
  pub fn root(&mut self, a: i64) -> i64 {

    if self.parent[a as usize] < 0 {
      return a;
    }
    // aに属してる集合の根にaを直接つなぐ
    let tmp = self.parent[a as usize];
    self.parent[a as usize] = self.root(tmp);

    return self.parent[a as usize];
  }

  // 自分のいるグループの頂点数を調べる
  pub fn size(&mut self, a: i64) -> i64 {
    let tmp = self.root(a) as usize;
    return -self.parent[tmp];
  }

  // aにbをくっつける
  // 接続できたらtrue,　すでに接続済ならfalse 
  pub fn connect(&mut self, a: i64, b: i64) -> bool {
    let mut at = self.root(a);
    let mut bt = self.root(b);

    if at == bt {
      // すでにくっついてるからくっつけない
      return false;
    }

    // 大きい方aに小さい方bをくっつける
    // 大小が逆だったらひっくり返す
    if self.size(at) < self.size(bt) {
      let temp = at;
      at = bt;
      bt = temp;
    }

    // aのサイズを更新する
    self.parent[at as usize] += self.parent[bt as usize];
    // bの親をaに更新する
    self.parent[bt as usize] = at;
    return true
  }

  // UnionFind同士が等しいかどうか判定する
  pub fn equal(&self, that: UnionFind) -> bool {
    let l: usize = that.parent.len();

    if self.parent.len() != l {
      return false;
    }

    for i in 0..l {
      if self.parent[i] != that.parent[i] {
        return false;
      }
    }
    return true;
  }
  
  // aとbが接続しているかどうかを判定する
  pub fn connected(&mut self, a: i64, b: i64 ) -> bool {
    self.root(a) == self.root(b)
  }
}