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 C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace AtCoder {
    public class Program {
        static int[] getKeys() {
            var Keys = Console.ReadLine().Split(' ');
            int N = Keys.Length;
            int[] Ns = new int[N];
            for (int i = 0; i < N; i++) {
                Ns[i] = int.Parse(Keys[i]);
            }
            return Ns;
        }
        static int[] getKeys(char delimiter) {
            var Keys = Console.ReadLine().Split(delimiter);
            int N = Keys.Length;
            int[] Ns = new int[N];
            for (int i = 0; i < N; i++) {
                Ns[i] = int.Parse(Keys[i]);
            }
            return Ns;
        }

        public static void Show<T>(T[,] map) {
            int H = map.GetLength(0);
            int W = map.GetLength(1);
            Console.WriteLine("-------------------------");
            for (int i = 0; i < H; i++) {
                for (int j = 0; j < W; j++) {
                    Console.Write(map[i, j] + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine("-------------------------");
        }
        public static void Show<T>(T[,] map, string delimiter) {
            int H = map.GetLength(0);
            int W = map.GetLength(1);
            Console.WriteLine("-------------------------");
            for (int i = 0; i < H; i++) {
                for (int j = 0; j < W; j++) {
                    Console.Write(map[i, j] + delimiter);
                }
                Console.WriteLine();
            }
            Console.WriteLine("-------------------------");
        }
        public static void Show<T>(IEnumerable<T> ts) {
            foreach (var item in ts) {
                Console.Write(item + " ");
            }
            Console.WriteLine();
        }
        public static void Show<T>(IEnumerable<T> ts, string delimiter) {
            foreach (var item in ts) {
                Console.Write(item + delimiter);
            }
            Console.WriteLine();
        }
        public static void ShowDictionary<T1, T2>(Dictionary<T1, T2> dictionary) {
            foreach (var item in dictionary) {
                Console.WriteLine(item);
            }
        }
        static T[] getUniform<T>(int length, T value) {
            T[] Ts = new T[length];
            for (int i = 0; i < length; i++) {
                Ts[i] = value;
            }
            return Ts;
        }
        static void setUniform<T>(T[] ts, T value) {
            int length = ts.Length;
            for (int i = 0; i < length; i++) {
                ts[i] = value;
            }
        }
        static T[,] getUniform<T>(int row, int col, T value) {
            T[,] Ts = new T[row, col];
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    Ts[j, i] = value;
                }
            }
            return Ts;
        }
        static void setUniform<T>(T[,] ts, T value) {
            int N = ts.GetLength(0);
            int M = ts.GetLength(1);
            for (int i = 0; i < M; i++) {
                for (int j = 0; j < N; j++) {
                    ts[j, i] = value;
                }
            }
        }

        static int N, M;
        static List<int> HPs;
        static int[] Matches = new int[] { 2, 5, 5, 4, 5, 6, 3, 7, 6 };
        static List<int> available = new List<int>();
        static void Main() {
            var Keys = getKeys();
            N = Keys[0];
            M = Keys[1];
            Keys = getKeys();
            //桁数と大小のトレードオフ
            for (int i = 0; i < M; i++) {
                available.Add(Keys[i]);
            }
            available.Sort((x, y) => y - x);
            //ある本数から作られる最大のナンバーを。
            Dictionary<int, int> MatchToNumber = new Dictionary<int, int>();
            for (int i = 0; i < M; i++) {
                if (!MatchToNumber.ContainsKey(Matches[available[i] - 1])) {
                    MatchToNumber.Add(Matches[available[i] - 1], available[i]);
                }
            }
            ShowDictionary(MatchToNumber);
            int minMatch = MatchToNumber.Keys.Min();
            int MaxDigit = N / minMatch;
            int rest = N % minMatch;
            int a = MatchToNumber[minMatch];
            StringBuilder SB = new StringBuilder();
            for (int i = 0; i < MaxDigit; i++) {
                SB.Append(a.ToString());
            }
            int digit = MaxDigit;
            long answer = long.Parse(SB.ToString());
            MatchToNumber.Remove(minMatch);
            while (rest != 0) {
                rest += minMatch;
                answer /= 10;
                rest = Reduce(rest, MatchToNumber, answer);
            }
            Console.WriteLine(Maximaze(answer.ToString()));
        }

        static int Reduce(int rest, Dictionary<int, int> dic, long ans) {
            int m = dic.Keys.Min();
            rest -= m;
            ans *= 10;
            ans += dic[m];
            return rest;
        }

       static string Maximaze(string n) {
            List<Tuple<long, long>> tuples = new List<Tuple<long, long>>();
            foreach (var item in available) {
                tuples.Add(new Tuple<long, long>(item, n.Where(c => c.ToString() == item.ToString()).Count()));
            }
            StringBuilder builder = new StringBuilder();
            tuples.Sort((x, y) => (int)(y.Item1 - x.Item1));
            foreach (var item in tuples) {
                string s = item.Item1.ToString();
                for (int i = 0; i < item.Item2; i++) {
                    builder.Append(s);
                }
            }
            return builder.ToString();
        }
    }
}