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)
  }
}


Measured memory_bytes: 12092