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 Lua (LuaJIT 2.1.0) (judge verdict: Accepted)

local bls, brs = bit.lshift, bit.rshift
local bxor = bit.bxor
local mce, mfl, msq, mmi, mma, mab = math.ceil, math.floor, math.sqrt, math.min, math.max, math.abs

local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
long long atoll(const char*);
]]

local function lltonumber(str)
  return C.atoll(str)
end

local n = io.read()
if n == "1" then print(1) os.exit() end
n = lltonumber(n)
n = 2LL * n
local lim = 31622777
local function getprimes(x)
  local primes = {}
  local allnums = {}
  for i = 1, x do allnums[i] = true end
  for i = 2, x do
    if allnums[i] then
      table.insert(primes, i)
      local lim = mfl(x / i)
      for j = 2, lim do
        allnums[j * i] = false
      end
    end
  end
  return primes
end
-- print(os.clock())
local primes = getprimes(lim)
-- print(os.clock())
local function getdivisorparts(x, primes, lim)
  local prime_num = #primes
  local tmp = {}
  local raw = {}
  local primepos = 1
  local dv = primes[primepos]
  while primepos <= prime_num and dv <= lim do
    if x % dv == 0LL then
      local p = dv
      x = x / dv
      while x % dv == 0 do
        x = x / dv
        p = p * dv
      end
      table.insert(tmp, p)
      table.insert(raw, dv)
      -- lim = mce(msq(x))
    end
    if primepos == prime_num then break end
    primepos = primepos + 1
    dv = primes[primepos]
  end
  if x ~= 1LL then
    table.insert(tmp, x)
    table.insert(raw, x)
  end
  return tmp, raw
end
-- for i = 1, #dvs do
--   print(dvs[i])-- maybe LL
-- end

local function grayCode(x)
  return bxor(x, brs(x, 1))
end

-- add_func(idx), rm_func(idx), work_func()
local function grayWalk(size, add_func, rm_func, work_func)
  local prv = 0
  local total = bls(1, size) - 1
  local bpos = {}
  for i = 1, size do
    bpos[bls(1, i - 1)] = i
  end
  -- if need first work then use below
  -- work_func()
  for i = 1, total do
    local v = grayCode(i)
    if prv < v then
      prv, v = v, v - prv
      add_func(bpos[v])
    else
      prv, v = v, prv - v
      rm_func(bpos[v])
    end
    work_func()
  end
end

local dvs, raw = getdivisorparts(n, primes, lim)
local tot = bls(1, #dvs)
local left_use = {}
local minfact = n
local kcand = 1
local left = 1LL

local function solve(a, b, x, y)
  if b == 0LL then
    x[1] = 1LL
    y[1] = 0LL
    return a
  end
  local d = solve(b, a % b, y, x)
  y[1] = y[1] - (a / b) * x[1]
  return d
end

local function add_func(idx)
  left_use[tostring(raw[idx])] = true
  left = left * dvs[idx]
end
local function rm_func(idx)
  left_use[tostring(raw[idx])] = false
  left = left / dvs[idx]
end
local x, y = {0}, {0}
local function work_func()
  local right = n / left
  solve(left, right, x, y)
  x[1] = -x[1]
  while x[1] < 0LL do
    x[1] = x[1] + right
  end
  local z = x[1] * left
  if 0LL < z and z < minfact then
  -- if x[1] * left < minfact then
    minfact = left * x[1]
    -- print(x[1], left, minfact)
  end
end
grayWalk(#dvs, add_func, rm_func, work_func)
local ans = minfact
ans = tostring(ans):gsub("LL", "")
print(ans)