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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.util.*;

public class Main {
    private static int[] costs = new int[]{-1, 2, 5, 5, 4, 5, 6, 3, 7, 6};

    private static class RunLenNum implements Comparable<RunLenNum> {
        private int totLen;
        private int[] numCounts;

        public RunLenNum() {
            this.totLen = 0;
            this.numCounts = new int[10];
        }

        public RunLenNum addNum(int num) {
            RunLenNum res = new RunLenNum();
            res.totLen = totLen + 1;
            res.numCounts = Arrays.copyOf(numCounts, numCounts.length);
            res.numCounts[num]++;

            return res;
        }

        @Override
        public int compareTo(RunLenNum o) {
            if (o == null)
                return 1;

            if (totLen != o.totLen)
                return Integer.compare(totLen, o.totLen);

            for (int i = 9; i > 0; i--) {
                if (numCounts[i] != o.numCounts[i])
                    return Integer.compare(numCounts[i], o.numCounts[i]);
            }

            return 0;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();

            for (int i = 9; i > 0; i--) {
                if (numCounts[i] == 0)
                    continue;

                for (int j = 0; j < numCounts[i]; j++) {
                    sb.append(i);
                }
            }

            return sb.toString();
        }
    }

    private static RunLenNum findBest(RunLenNum[] memo, int minDigits, int n, List<Integer> digits) {
        if (n < minDigits)
            return null;

        if (memo[n] != null)
            return memo[n];

        ArrayList<RunLenNum> choices = new ArrayList<>();

        for (int d : digits) {
            if (costs[d] == n)
                choices.add(new RunLenNum().addNum(d));
        }

        for (int d : digits) {
            RunLenNum bestWithoutThis = findBest(memo, minDigits, n - costs[d], digits);

            if (bestWithoutThis != null)
                choices.add(bestWithoutThis.addNum(d));
        }

        if (choices.size() == 0)
            memo[n] = null;
        else
            memo[n] = Collections.max(choices);

        return memo[n];
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt(), m = sc.nextInt();

        ArrayList<Integer> ds = new ArrayList<>(m);

        for (int i = 0; i < m; i++) {
            ds.add(sc.nextInt());
        }

        int minDigits = 10;

        for (int d : ds) {
            minDigits = Math.min(minDigits, costs[d]);
        }

        RunLenNum[] memo = new RunLenNum[Math.max(10, n + 1)];

        System.out.println(findBest(memo, minDigits, n, ds));
    }
}