Problem:
Score : 400 points

Problem Statement

Find the largest integer that can be formed with exactly N matchsticks, under the following conditions:

Every digit in the integer must be one of the digits A_1, A_2, ..., A_M (1 \leq A_i \leq 9).

The number of matchsticks used to form digits 1, 2, 3, 4, 5, 6, 7, 8, 9 should be 2, 5, 5, 4, 5, 6, 3, 7, 6, respectively.

Constraints

All values in input are integers.

2 \leq N \leq 10^4

1 \leq M \leq 9

1 \leq A_i \leq 9

A_i are all different.

There exists an integer that can be formed by exactly N matchsticks under the conditions.

Input

Input is given from Standard Input in the following format:

N M
A_1 A_2 ... A_M

Output

Print the largest integer that can be formed with exactly N matchsticks under the conditions in the problem statement.

Sample Input 1

20 4
3 7 8 4

Sample Output 1

777773

The integer 777773 can be formed with 3 + 3 + 3 + 3 + 3 + 5 = 20 matchsticks, and this is the largest integer that can be formed by 20 matchsticks under the conditions.

Sample Input 2

101 9
9 8 7 6 5 4 3 2 1

Sample Output 2

71111111111111111111111111111111111111111111111111

The output may not fit into a 64-bit integer type.

Sample Input 3

15 3
5 4 6

Sample Output 3

654

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

#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

#[derive(Clone)]
struct BigInt {
    int: Vec<usize>,
    made: bool,
}

impl BigInt {
    fn add_new_digit_to_msb(&mut self, num: usize) {
        self.int.push(num);
    }

    fn to_string(self) -> String {
        let mut digits = self.int.clone();
        digits.reverse();
        digits
            .iter()
            .map(|&x| x.to_string())
            .collect::<Vec<_>>()
            .join("")
    }
}

impl Ord for BigInt {
    fn cmp(&self, other: &BigInt) -> Ordering {
        if self.int.len() > other.int.len() {
            return Ordering::Greater;
        } else if self.int.len() < other.int.len() {
            return Ordering::Less;
        }
        for i in (0..self.int.len()).rev() {
            if self.int[i] > other.int[i] {
                return Ordering::Greater;
            } else if self.int[i] < other.int[i] {
                return Ordering::Less;
            }
        }
        Ordering::Equal
    }
}

impl PartialOrd for BigInt {
    fn partial_cmp(&self, other: &BigInt) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialEq for BigInt {
    fn eq(&self, other: &BigInt) -> bool {
        self.int == other.int
    }
}
impl Eq for BigInt {}

fn main() {
    let v: Vec<usize> = read_vec();
    let n = v[0];
    let mut a = read_vec::<usize>();
    a.sort();

    let mut convert_dict = HashMap::new();

    for num in a {
        if num == 1 {
            convert_dict.insert(2usize, 1);
        } else if num == 2 {
            convert_dict.insert(5, 2);
        } else if num == 3 {
            *convert_dict.entry(5).or_insert(3) = 3;
        } else if num == 4 {
            convert_dict.insert(4, 4);
        } else if num == 5 {
            *convert_dict.entry(5).or_insert(5) = 5;
        } else if num == 6 {
            *convert_dict.entry(6).or_insert(6) = 6;
        } else if num == 7 {
            *convert_dict.entry(3).or_insert(7) = 7;
        } else if num == 8 {
            *convert_dict.entry(7).or_insert(8) = 8;
        } else if num == 9 {
            *convert_dict.entry(6).or_insert(9) = 9;
        }
    }

    let mut dp = vec![
        BigInt {
            int: vec![],
            made: false,
        };
        n + 1
    ];
    dp[0] = BigInt {
        int: vec![],
        made: true,
    };

    for i in 2..n + 1 {
        for &cost in convert_dict.keys() {
            if i >= cost && dp[i - cost].made {
                let mut new_int = dp[i - cost].clone();
                new_int.add_new_digit_to_msb(convert_dict[&cost]);
                // println!("try {0} {1}", i, new_int.clone().to_string());
                dp[i] = max(new_int, dp[i].clone());
                dp[i].made = true;
                // println!("{0} {1}", i, dp[i].clone().to_string());
            }
        }
    }
    println!("{}", dp[n].clone().to_string());
}