open System

(*
opt    = {} # opt[t] は t円の最適な払い方。これから求めるよ！
opt[0] = [] # 0円 はコイン0枚で最適に(?)払えます
1.upto(T) do |t|
  opt[t] =                       # t円の最適な払い方は
     C.select{|c| opt[t-c]}.
          map{|c| opt[t-c]+[c]}. #   t-c円の最適な払い方 + c円玉
       min_by{|p| p.size}        #   … のうち一番枚数少ないヤツ
end
p opt[T]

bool comp(const vector<int>& lhs, const vector<int>& rhs)
{
	if (lhs.size() < rhs.size())
		return true;
	else if (lhs.size() == rhs.size()) {
		for (int i = 0; i < (int)lhs.size(); i++)
			if (lhs[i] < rhs[i])
				return true;
	}
	return false;
}

int main()
{
	const int cost[] = { 0,2,5,5,4,5,6,3,7,6 };
	int N, M;
	cin >> N >> M;
	set<int> A;
	rep(i, M) {
		int a;
		cin >> a;
		A.insert(a);
	}
	vector<vector<int>> dp(N+1);	//dp[i]: i本マッチで作れる最大の数
	dp[0] = {};
	rep1(i, N) {
		for (auto rit = A.rbegin(); rit != A.rend(); ++rit) {
			const auto& a = *rit;
			int j = i - cost[a];
			if (j == 0 && dp[j].size() == 0 || j > 0 && dp[j].size() != 0) {
				auto x = dp[j];
				x.push_back(a);
				if (comp(dp[i], x)) {
					dp[i] = x;
				}
			}
		}
	}
	for (auto i : dp[N])
		cout << i;
	cout << endl;
	return 0;
}

*)

let comp lhs rhs =
    if List.length lhs < List.length rhs then true
    else if List.length lhs = List.length rhs then List.exists2 (<) lhs rhs
    else false

[<EntryPoint>]
let main argv =
    let cost = [|0;2;5;5;4;5;6;3;7;6|]
    let N, M = Console.ReadLine().Split(" ") |> Array.map int |> (fun xs -> xs.[0], xs.[1])
    let A = Console.ReadLine().Split(" ") |> Array.map int |> Set.ofArray
    let dp : int list array = Array.create (N+1) []
    for i=1 to N do
        for a in A do
            let j = i - cost.[a]
            if j = 0 && List.isEmpty dp.[j] || j > 0 && (not <| List.isEmpty dp.[j]) then
                let x = a :: dp.[j]
                if comp dp.[i] x then
                    dp.[i] <- x
    dp.[N]
    //|> List.rev 
    |> List.map string
    |> String.concat ""
    |> fun ans -> Console.WriteLine(ans)
    0 // return an integer exit code
