Problem:
Score : 400 points

Problem Statement

You start with the number 0 and you want to reach the number N.

You can change the number, paying a certain amount of coins, with the following operations:

Multiply the number by 2, paying A coins.

Multiply the number by 3, paying B coins.

Multiply the number by 5, paying C coins.

Increase or decrease the number by 1, paying D coins.

You can perform these operations in arbitrary order and an arbitrary number of times.

What is the minimum number of coins you need to reach N?

You have to solve T testcases.

Constraints

1 \le T \le 10

1 \le N \le 10^{18}

1 \le A, B, C, D \le 10^9

All numbers N, A, B, C, D are integers.

Input

The input is given from Standard Input. The first line of the input is

T

Then, T lines follow describing the T testcases.
Each of the T lines has the format

N A B C D

Output

For each testcase, print the answer on Standard Output followed by a newline.

Sample Input 1

5
11 1 2 4 8
11 1 2 2 8
32 10 8 5 4
29384293847243 454353412 332423423 934923490 1
900000000000000000 332423423 454353412 934923490 987654321

Sample Output 1

20
19
26
3821859835
23441258666

For the first testcase, a sequence of moves that achieves the minimum cost of 20 is:

Initially x = 0.

Pay 8 to increase by 1 (x = 1).

Pay 1 to multiply by 2 (x = 2).

Pay 1 to multiply by 2 (x = 4).

Pay 2 to multiply by 3 (x = 12).

Pay 8 to decrease by 1 (x = 11).

For the second testcase, a sequence of moves that achieves the minimum cost of 19 is:

Initially x = 0.

Pay 8 to increase by 1 (x = 1).

Pay 1 to multiply by 2 (x = 2).

Pay 2 to multiply by 5 (x = 10).

Pay 8 to increase by 1 (x = 11).

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

fn dfs(
    n: usize,
    a: usize,
    b: usize,
    c: usize,
    d: usize,
    x: usize,
    memo: &mut HashMap<usize, usize>,
) -> usize {
    let mut res = std::usize::MAX;
    if n == 0 {
        return min(res, x);
    } else if n == 1 {
        return min(res, x + d);
    }

    for &p in [(2, a), (3, b), (5, c)].iter().rev() {
        if n >= p.0 {
            let flor = n / p.0;
            res = min(
                dfs(flor, a, b, c, d, x + p.1 + (n - flor * p.0) * d, memo),
                res,
            );
            if n % p.0 != 0 {
                let ceil = n / p.0 + 1;
                res = min(
                    dfs(ceil, a, b, c, d, x + p.1 + (ceil * p.0 - n) * d, memo),
                    res,
                );
            }
        }
    }
    match memo.get_mut(&n) {
        Some(v) => {
            *v = min(res, *v);
        }
        None => {
            memo.insert(n, res);
        }
    };
    res
}

fn solve() {
    let t: usize = read();
    'outer: for i in 0..t {
        let n: usize = read();
        let (a, b): (usize, usize) = (read::<usize>(), read::<usize>());
        let (c, d): (usize, usize) = (read::<usize>(), read::<usize>());
        let mut memo: HashMap<usize, usize> = HashMap::new();
        let mut que = BinaryHeap::new();
        que.push((Reverse(0), Reverse(n)));

        while let Some((Reverse(cost), Reverse(n))) = que.pop() {
            if n == 0 {
                memo.insert(0, cost);
                break;
            } else if n == 1 {
                memo.insert(0, cost + d);
                break;
            }
            match memo.get_mut(&n) {
                Some(v) => {
                    if *v <= cost {
                        continue;
                    } else {
                        *v = cost;
                    }
                }
                None => {
                    memo.insert(n, cost);
                }
            };

            que.push((Reverse(cost.wrapping_add(n.wrapping_mul(d))), Reverse(0)));
            for &p in [(2, a), (3, b), (5, c)].iter().rev() {
                if n >= p.0 {
                    let flor = n / p.0;
                    que.push((Reverse(cost + p.1 + (n - flor * p.0) * d), Reverse(flor)));
                    if n % p.0 != 0 {
                        let ceil = n / p.0 + 1;
                        que.push((Reverse(cost + p.1 + (ceil * p.0 - n) * d), Reverse(ceil)));
                    }
                }
            }
        }
        println!("{}", memo.get(&0).expect("error"));
    }
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}

// =========
#[allow(unused_imports)]
use std::cmp::{max, min, Reverse};
#[allow(unused_imports)]
use std::collections::{BinaryHeap, HashMap, HashSet};
#[allow(unused_imports)]
use std::process::exit;

#[allow(dead_code)]
const MOD: usize = 1000000007;

fn read<T: std::str::FromStr>() -> T {
    use std::io::Read;
    let stdin = std::io::stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

// =========