Problem:
Score : 600 points

Problem Statement

Given is an integer N.
Find the minimum possible positive integer k such that (1+2+\cdots+k) is a multiple of N.
It can be proved that such a positive integer k always exists.

Constraints

1 \leq N \leq 10^{15}

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N

Output

Print the answer in a line.

Sample Input 1

11

Sample Output 1

10

1+2+\cdots+10=55 holds and 55 is indeed a multple of N=11.
There are no positive integers k \leq 9 that satisfy the condition, so the answer is k = 10.

Sample Input 2

20200920

Sample Output 2

1100144

Solution in Rust (1.42.0) (judge verdict: Accepted)

// template {{{
#![allow(clippy::many_single_char_names)]

#[allow(dead_code)]
mod ngtio {
    use ::std::collections::VecDeque;

    pub struct Buffer {
        buf: VecDeque<String>,
    }

    impl Buffer {
        pub fn new() -> Self {
            Self {
                buf: VecDeque::new(),
            }
        }

        fn load(&mut self) {
            while self.buf.is_empty() {
                let mut s = String::new();
                let length = ::std::io::stdin().read_line(&mut s).unwrap();
                if length == 0 {
                    break;
                }
                self.buf.extend(s.split_whitespace().map(|s| s.to_owned()));
            }
        }

        pub fn string(&mut self) -> String {
            self.load();
            self.buf
                .pop_front()
                .unwrap_or_else(|| panic!("入力が終了したのですが。"))
        }

        pub fn string_char_vec(&mut self) -> Vec<char> {
            let s = self.string();
            s.chars().collect::<Vec<_>>()
        }

        pub fn string_char_vec_trusted_len(&mut self, len: usize) -> Vec<char> {
            let s = self.string();
            let s = s.chars().collect::<Vec<_>>();
            assert_eq!(s.len(), len, "あら、思ったのと長さ違いますね……");
            s
        }

        pub fn char(&mut self) -> char {
            let string = self.string();
            let mut chars = string.chars();
            let res = chars.next().unwrap();
            assert!(
                chars.next().is_none(),
                "char で受け取りたいのも山々なのですが、さては 2 文字以上ありますね？"
            );
            res
        }

        pub fn read<T: ::std::str::FromStr>(&mut self) -> T
        where
            <T as ::std::str::FromStr>::Err: ::std::fmt::Debug,
        {
            self.string()
                .parse::<T>()
                .expect("Failed to parse the input.")
        }

        pub fn read_vec<T: ::std::str::FromStr>(&mut self, len: usize) -> Vec<T>
        where
            <T as ::std::str::FromStr>::Err: ::std::fmt::Debug,
        {
            (0..len).map(|_| self.read::<T>()).collect()
        }
    }

    macro_rules! define_primitive_reader {
        ($($ty:tt,)*) => {
            impl Buffer {
                $(
#[inline]
                    pub fn $ty(&mut self) -> $ty {
                        self.read::<$ty>()
                    }
                )*
            }
        }
    }

    define_primitive_reader! {
        u8, u16, u32, u128, usize,
        i8, i16, i32, i128, isize,
    }

    impl Default for Buffer {
        fn default() -> Self {
            Self::new()
        }
    }
}

#[allow(unused_imports)]
use std::{collections, iter, mem, ops};
// }}}
// crt {{{
#[allow(dead_code)]
mod crt {
    #![warn(missing_docs)]

    use std::mem;

    #[allow(clippy::many_single_char_names)]
    pub fn crt(xm: &[(u128, u128)]) -> Option<(u128, u128)> {
        xm.iter()
            .try_fold((0, 1), |(x0, m0), &(x1, m1)| {
                let (option_x, m) = crt_impl(x0, m0, x1 as i128, m1 as i128);
                option_x.map(|x| (x, m))
            })
            .map(|(x, m)| (x as u128, m as u128))
    }

    // これの答えです。
    // ans = x0 ( mod m0 )
    // ans = x1 ( mod m1 )
    #[allow(clippy::many_single_char_names)]
    fn crt_impl(x0: i128, m0: i128, x1: i128, m1: i128) -> (Option<i128>, i128) {
        let dx = x1 - x0;
        let (a_inv, g) = mod_inverse_gcd(m0, m1);
        let l = m0 / g * m1;
        let res = if dx % g == 0 {
            let b = dx / g;
            let m = m1 / g;
            let k = b * a_inv % m;
            let k = if k < 0 { k + m } else { k };
            Some(x0 + m0 * k)
        } else {
            None
        };
        (res, l)
    }

    // TODO: 一般の符号あり整数型を受け取れるようにしたいです。
    #[allow(clippy::many_single_char_names)]
    fn mod_inverse_gcd(x: i128, m: i128) -> (i128, i128) {
        let mut x = x;
        let mut y = m;
        let mut u = 1;
        let mut v = 0;
        while x != 0 {
            let q = y / x;
            y -= q * x;
            v -= q * u;
            mem::swap(&mut x, &mut y);
            mem::swap(&mut u, &mut v);
        }
        let res = if v < 0 { v + m } else { v };
        (res, y)
    }
}
// }}}

fn factorize(mut n: u128) -> Vec<u128> {
    let mut fac = Vec::new();
    for i in 2.. {
        if n < i * i {
            break;
        }
        if n % i == 0 {
            let mut count = 0;
            while n % i == 0 {
                count += 1;
                n /= i;
            }
            fac.push(i.pow(count));
        }
    }
    if n != 1 {
        fac.push(n);
    }
    fac
}

fn solve(n: u128) -> u128 {
    let fac = factorize(2 * n);

    let k = (1..1 << fac.len())
        .map(|bs| {
            let xm = fac
                .iter()
                .enumerate()
                .map(|(i, &q)| {
                    let r = if bs >> i & 1 == 1 { q - 1 } else { 0 };
                    (r, q)
                })
                .collect::<Vec<_>>();
            crt::crt(&xm).unwrap().0
        })
        .min()
        .unwrap();
    assert!(k * (k + 1) / 2 % n == 0);
    assert!(k <= 2 * n);
    k
}

fn main() {
    let mut buf = ngtio::Buffer::new();
    let n = buf.u128();
    let k = solve(n);
    println!("{}", k);
}

#[cfg(test)]
#[test]
fn test() {
    for i in 1..10000 {
        solve(i);
    }
    solve(10u128.pow(15));
}