AtCoder Beginner Contest 265 C

https://atcoder.jp/contests/abc265/tasks/abc265_c

こういう問題はOptionを使うとよいようです。1行が少し長くなりますが。
あと、Rustにはloopというキーワードがあるんですね。

// Belt Conveyor
#![allow(non_snake_case)]

use std::collections::HashSet;

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 find_end_point(G: Vec<Vec<char>>) -> Option<(usize, usize)> {
    let H = G.len();
    let W = G[0].len();
    let mut visited = HashSet::<(usize, usize)>::new();
    let mut x = 0usize;
    let mut y = 0usize;
    loop {
        if visited.contains(&(x, y)) {
            return None
        }
        visited.insert((x, y));
        match G[x][y] {
            'U' => { if x == 0     { return Some((x, y)) } else { x -= 1 } },
            'D' => { if x == H - 1 { return Some((x, y)) } else { x += 1 } },
            'L' => { if y == 0     { return Some((x, y)) } else { y -= 1 } },
            'R' => { if y == W - 1 { return Some((x, y)) } else { y += 1 } },
            _         => { return None }
        }
    }
}

fn main() {
    let v = read_vec();
    let H: usize = v[0];
    let G = (0..H).map(|_| read::<String>().chars().collect()).collect();
    match find_end_point(G) {
        Some((x, y)) => { println!("{} {}", x + 1, y + 1) },
        None =>         { println!("{}", -1) }
    }
}