AtCoder Beginner Contest 302 E

https://atcoder.jp/contests/abc302/tasks/abc302_e

Queryをenumにして、matchで分けるときれいに書けますね。
HashMapでborrowするとややこしいことになりますね。

// Isolation
#![allow(non_snake_case)]

use std::collections::{HashMap, HashSet};


//////////////////// library ////////////////////

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

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

//////////////////// process ////////////////////

fn read_input() -> (usize, usize) {
    let v = read_vec();
    let N = v[0];
    let Q = v[1];
    (N, Q)
}

type Node = usize;
type Graph = HashMap<Node, HashSet<Node>>;

enum Query {
    Add(usize, Node, Node),
    Remove(usize, Node)
}

fn read_query() -> Query {
    let v = read_vec();
    if v[0] == 1 {
        Query::Add(v[0], v[1], v[2])
    }
    else {
        Query::Remove(v[0], v[1])
    }
}

fn add_edge(v: Node, w: Node, graph: &mut Graph) -> usize {
    let e1 = graph.entry(v).or_insert(HashSet::new());
    e1.insert(w);
    let num1 = if e1.len() == 1 { 1 } else { 0 };
    let e2 = graph.entry(w).or_insert(HashSet::new());
    e2.insert(v);
    let num2 = if e2.len() == 1 { 1 } else { 0 };
    num1 + num2
}

fn remove_node(v: Node, graph: &mut Graph) -> usize {
    let op = graph.get(&v);
    if op.is_none() {
        return 0
    }
    
    let s = op.unwrap();
    if s.is_empty() {
        return 0
    }
    
    let num = s.iter().filter(|w| graph.get(w).unwrap().len() == 1).count();
    let neighbors: Vec<Node> = s.iter().map(|&w| w).collect();
    for w in neighbors.iter() {
        graph.get_mut(w).unwrap().remove(&v);
    }
    let s1 = graph.get_mut(&v).unwrap();
    s1.clear();
    num + 1
}

fn f(N: usize, Q: usize) {
    let mut graph: Graph = Graph::new();
    let mut num_isolated = N;
    for _ in 0..Q {
        match read_query() {
            Query::Add(_, v, w) => {
                num_isolated -= add_edge(v, w, &mut graph)
            },
            Query::Remove(_, v) => {
                num_isolated += remove_node(v, &mut graph)
            }
        }
        println!("{}", num_isolated)
    }
}

//////////////////// main ////////////////////

fn main() {
    let (N, Q) = read_input();
    f(N, Q)
}