AtCoder Beginner Contest 272 D(2)

https://atcoder.jp/contests/abc272/tasks/abc272_d

素因数分解さえできれば、移動できるステップを高速に求められます。そのために、GaussIntという構造体を作りました。
デバッグのためにfmtというメソッドを作って複素数を出力できるようにしましたが、その中で

            write!(f, "{}", self.re)?;

などとしていますが、?はwrite!でエラーが出たときはそのエラーをそのまま返せるようにする記号です。
この規模だと速くはなりませんね。

// Root M Leaper
#![allow(non_snake_case)]

use std::ops::{Add, Mul};
use std::collections::VecDeque;
use std::fmt;

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

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

fn div_pow(n: i32, d: i32) -> (i32, i32) {
    if n % d == 0 {
        let (e, m) = div_pow(n / d, d);
        (e + 1, m)
    }
    else {
        (0, n)
    }
}


//////////////////// Factors ////////////////////

type Factors = Vec<(i32, i32)>;

fn factorize(n: i32, p0: i32) -> Factors {
    if n == 1 {
        return vec![]
    }
    
    for p in p0.. {
        if p * p > n {
            break
        }
        if n % p == 0 {
            let (e, m) = div_pow(n, p);
            let factors = factorize(m, p + 1);
            let mut new_factors = vec![(p, e)];
            new_factors.extend(&factors);
            return new_factors
        }
    }
    vec![(n, 1)]
}

fn pow_mod(n: i32, e: i32, d: i32) -> i32 {
    if e == 1 {
        n
    }
    else if e % 2 == 0 {
        let m = pow_mod(n, e / 2, d);
        ((m as i64) * (m as i64) % (d as i64)) as i32
    }
    else {
        let m = pow_mod(n, e - 1, d);
        ((m as i64) * (n as i64) % (d as i64)) as i32
    }
}


//////////////////// Point ////////////////////

#[derive(Clone, Copy)]
#[derive(Debug)]
#[derive(Eq, Hash, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Output = Self;
    
    fn add(self, other: Self) -> Self {
        Self { x: self.x + other.x, y: self.y + other.y }
    }
}

// rotate 90 degrees
fn rotate(dir: &Point) ->  Point {
    Point { x: -dir.y, y: dir.x }
}

// reflect on x + y = 0
fn reflect(dir: &Point) -> Point {
    Point { x: dir.y, y: dir.x }
}

fn expand_dirs(dir: Point) -> Vec<Point> {
    let mut dirs = Vec::<Point>::new();
    dirs.push(dir);
    for i in 0..3 {
        dirs.push(rotate(&dirs[i]))
    }
    if dir.x != dir.y && dir.x != 0 && dir.y != 0 {
        for i in 0..4 {
            dirs.push(reflect(&dirs[i]))
        }
    }
    dirs
}


//////////////////// GaussInt ////////////////////

#[derive(Clone, Copy)]
struct GaussInt {
    re: i32,
    im: i32
}

impl Mul for GaussInt {
    type Output = Self;
    
    fn mul(self, other: Self) -> Self {
        let re = self.re * other.re - self.im * other.im;
        let im = self.re * other.im + self.im * other.re;
        Self { re, im }
    }
}

impl fmt::Display for GaussInt {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.re != 0 {
            write!(f, "{}", self.re)?;
            if self.im > 0 {
                write!(f, "+")?;
            }
        }
        else if self.im == 0 {
            write!(f, "0")?
        }
        if self.im == 1 {
            write!(f, "i")?
        }
        else if self.im == -1 {
            write!(f, "-i")?
        }
        else if self.im == 0 {
            return Ok(())
        }
        else {
            write!(f, "{}i", self.im)?
        };
        return Ok(())
    }
}

impl GaussInt {
    fn conjugate(&self) -> GaussInt {
        GaussInt { re: self.re, im: -self.im }
    }
    
    fn rotate90(&self) -> GaussInt {
        GaussInt { re: -self.im, im: self.re }
    }
    
    fn is_normal(&self) -> bool {
        self.re > 0 && self.re > self.im.abs()
    }
    
    // i^eを掛けて、re > 0, |re| > |im|にする
    fn normalize(&self) -> GaussInt {
        let mut c = *self;
        for _ in 0..4 {
            if c.is_normal() {
                return c
            }
            c = c.rotate90()
        }
        c   // ここには来ないはず
    }
    
    // k^2 + 1 ≡ 0(mod p)となるkを見つける
    fn find_i(p: i32) -> i32 {
        let e = p - 1;
        for a in 2..p {
            let k = pow_mod(a, e / 2, p);
            if k == p - 1 {
                return pow_mod(a, e / 4, p)
            }
        }
        1   // ここには来ないはず
    }
    
    fn gcd(z1: &GaussInt, z2: &GaussInt) -> GaussInt {
        if z2.im == 0 {
            return *z1
        }
        else {
            let z3 = z2.normalize();
            let q = z1.re / z3.re;
            let r = z1.re % z3.re;
            let z4 = GaussInt { re: r, im: z1.im - q * z3.im };
            GaussInt::gcd(&z3, &z4)
        }
    }
    
    fn pow(&self, e: i32) -> GaussInt {
        if e == 0 {
            GaussInt { re: 1, im: 0 }
        }
        else if e == 1 {
            *self
        }
        else if e % 2 == 0 {
            let z = self.pow(e / 2);
            z * z
        }
        else {
            *self * self.pow(e - 1)
        }
    }
    
    // 4n+1型素数をガウス整数に分解する
    fn divide_prime(p: i32) -> GaussInt {
        let k = GaussInt::find_i(p);
        let z1 = GaussInt { re: p, im: 0 };
        let z2 = GaussInt { re: k, im: 1 };
        let z = GaussInt::gcd(&z1, &z2);
        GaussInt { re: z.re, im: z.im.abs() }
    }
}

fn powers(z: GaussInt, e: i32, num_e: i32) -> Vec<GaussInt> {
    let zc = z.conjugate();
    (0..num_e).map(|i| z.pow(e-i) * zc.pow(i)).collect()
}

fn expand_zs(zs0: Vec<GaussInt>, (p, e): (i32, i32),
                            head: bool) -> (Vec<GaussInt>, bool) {
    let (ne, new_head) = if p == 2 { (1, head) }
                            else if head { (e/2 + 1, false) }
                            else { (e+1, false) };
    let zs = if p == 2 { vec![(GaussInt { re: 1, im: 1 }).pow(e)] }
                else if p % 4 == 1 { powers(GaussInt::divide_prime(p), e, ne) }
                else { vec![GaussInt { re: p.pow((e/2) as u32), im: 0 }] };
    (zs0.iter().map(|&z0| zs.iter().map(|&z| z0*z).collect::<Vec<GaussInt>>()).
                                                flatten().collect(), new_head)
}

fn find_normal_dirs(factors: &Factors, first: bool) -> Vec<GaussInt> {
    let zs0 = vec![GaussInt { re: 1, im: 0 }];
    let p = factors.iter().fold((zs0, first),
                                |(zs, head), &fs| expand_zs(zs, fs, head));
    p.0
}

fn find_movable_dirs(M: i32) -> Vec<Point> {
    let factors = factorize(M, 2);
    if factors.iter().any(|&(p, e)| p % 4 == 3 && e % 2 == 1) {
        return vec![]
    }
    
    let zs = find_normal_dirs(&factors, true);
    zs.into_iter().map(|z| expand_dirs(Point { x: z.re, y: z.im })).
                                        flatten().collect::<Vec<Point>>()
}

fn make_table(N: i32, M: i32) -> Vec<Vec<i32>> {
    let mut table: Vec<Vec<i32>>
                = (0..N).map(|_| (0..N).map(|_| -1).collect()).collect();
    table[0][0] = 0;
    let dirs = find_movable_dirs(M);
    let mut queue = VecDeque::<Point>::new();
    queue.push_back(Point { x: 0, y: 0 });
    while queue.len() > 0 {
        let pt0 = queue.pop_front().unwrap();
        let x0 = pt0.x as usize;
        let y0 = pt0.y as usize;
        for dir in dirs.iter() {
            let pt = pt0 + *dir;
            let x = pt.x as usize;
            let y = pt.y as usize;
            if 0 <= pt.x && pt.x < N && 0 <= pt.y && pt.y < N &&
                                                    table[x][y] == -1 {
                table[x][y] = table[x0][y0] + 1;
                queue.push_back(pt)
            }
        }
    }
    table
}

fn print_table(table: Vec<Vec<i32>>) {
    for v in table.into_iter() {
        println!("{}", v.iter().map(|n| n.to_string()).
                            collect::<Vec<String>>().join(" "))
    }
}

fn f(N: i32, M: i32) {
    let table = make_table(N, M);
    print_table(table)
}

fn main() {
    let v = read_input();
    f(v.0, v.1)
}