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::*;
#[allow(unused_imports)]
use std::io::*;
#[allow(unused_imports)]
use std::iter;
#[allow(unused_imports)]
use std::mem::*;
#[allow(unused_imports)]
use std::str::*;
#[allow(unused_imports)]
use std::usize;

#[allow(unused_macros)]
macro_rules! read_cols {
    ($($t:ty),+) => {{
        let mut line = String::new();
        stdin().read_line(&mut line).unwrap();

        let mut it = line.trim()
            .split_whitespace();

        ($(
            it.next().unwrap().parse::<$t>().ok().unwrap()
        ),+)
    }}
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let mut line = String::new();
    stdin().read_line(&mut line).unwrap();
    line.trim().to_string().parse().ok().unwrap()
}

#[allow(dead_code)]
fn read_vec<T: FromStr>() -> Vec<T> {
    let mut line = String::new();
    stdin().read_line(&mut line).unwrap();

    line.trim()
        .split_whitespace()
        .map(|s| s.parse().ok().unwrap())
        .collect()
}

fn main() {
    let (n, m) = read_cols!(usize, usize);
    let mut a = read_vec::<i64>();

    assert_eq!(a.len(), m);

    a.sort();

    let mut dp = vec![None; 10001];
    dp[0] = Some(String::new());
    let result = a.iter().fold(dp, |dp, &aa| {
        let cost: usize = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6][aa as usize];
        dp.into_iter()
            .fold(Vec::<Option<String>>::new(), |mut dp, row| {
                if dp.len() < cost {
                    dp.push(row);
                    return dp;
                }
                let next = {
                    let prev = &dp[dp.len() - cost];
                    prev.as_ref()
                        .map(|prev| {
                            let candidate = aa.to_string() + prev;
                            match row {
                                None => Some(candidate),
                                Some(ref old) => {
                                    if old.len() < candidate.len() {
                                        Some(candidate)
                                    } else if old.len() > candidate.len() {
                                        Some(old.clone())
                                    } else {
                                        Some(max(old.clone(), candidate))
                                    }
                                }
                            }
                        })
                        .unwrap_or(row.clone())
                };
                dp.push(next);
                dp
            })
    });
    let ans = result[n].as_ref().unwrap();

    println!("{}", ans);
}