Files
CodeObject/storage/zeta/rs/completed/11778.rs
2025-11-27 14:08:12 +09:00

70 lines
1.3 KiB
Rust

use std::io::stdin;
const MOD: u64 = 1_000_000_007;
struct sqmat2 {
data: [[u64; 2]; 2],
}
impl sqmat2 {
fn mul(&self, other: &sqmat2) -> sqmat2 {
let mut res = sqmat2 { data: [[0; 2]; 2] };
for i in 0..2 {
for j in 0..2 {
for k in 0..2 {
res.data[i][j] =
(res.data[i][j] + self.data[i][k] * other.data[k][j] % MOD) % MOD;
}
}
}
res
}
}
fn gcd(a: u64, b: u64) -> u64 {
if b == 0 {
return a;
}
gcd(b, a % b)
}
fn fib(mut n: u64) -> u64 {
if n == 0 {
return 0;
}
let mut f = sqmat2 {
data: [[1, 0], [0, 1]],
};
let mut curr = sqmat2 {
data: [[1, 1], [1, 0]],
};
while n > 0 {
if n & 1 == 1 {
f = f.mul(&curr);
}
n >>= 1;
curr = curr.mul(&curr);
}
f.data[0][1] % MOD
}
fn gcd_fib(n: u64, m: u64) -> u64 {
if m == 0 {
return n;
}
fib(gcd(m, n % m))
}
fn main() {
let mut line = String::new();
stdin().read_line(&mut line).unwrap();
let mut iter = line.split(' ').map(|x| x.trim().parse::<u64>().unwrap());
let n = iter.next().unwrap();
let m = iter.next().unwrap();
println!("{}", gcd_fib(n, m));
}