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++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<cmath>
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
vector<int> arr;
stack<int> st;
queue<int> qu;
queue<pair<int,int> > qu2;
priority_queue<int> pq;
#define rep(i,n) for(int i=0; i<(int)(n); i++)
#define rep2(i,n) for(int i=1; i<=(int)(n); i++)
typedef set<int> set_t;
typedef set<string> set_g;
typedef complex<double> xy_t;
static const int NIL = -1;
static const int INF = 1000000007;
#define mp make_pair

/*int P[10010];
void init(int n){//Union-find
    for(int i=0;i<n;++i)P[i]=i;
}
int root(int a) {
    if(P[a]==a)return a;
    return (P[a]=root(P[a]));
}
bool is_same_set(int a,int b){
    return root(a) == root(b);//代表元を求める
}
void unite(int a,int b){
    P[root(a)]=root(b);
}//対set,グラフ？
//セグメント木？？
*/

//Unionfind ,Disjointset
class UnionFind{
public:
//親の番号を格納する　親の場合-（その集合のサイズ）
    vector<int> Parent;
    //作るときはParentの値を全て-１にする
    UnionFind(int n){
        Parent = vector<int>(n,-1);
    }
    //Aがどのグループに属するか
    int root(int A){
        if(Parent[A] < 0)return A;
        return Parent[A]=root(Parent[A]);
    }
    //自分のグループの頂点数
    int size(int A){
        return -Parent[root(A)];
    }
    //AとBをくっつける
    int connect(int A,int B){
        //AとBを直接ではなくAのrootとBのrootをくっつける
        A = root(A);
        B = root(B);
        if(A==B){
            return false;//すでにくっついている
        }
        if(size(A)<size(B)) swap(A,B);
        //Aのサイズ更新
        Parent[A]+=Parent[B];
        //Bの親をAに変更する
        Parent[B]=A;

        return true;
    }
};

double dot_product(xy_t a, xy_t b) { return (conj(a)*b).real(); }//内積
double cross_product(xy_t a, xy_t b) { return (conj(a)*b).imag(); }//外積
xy_t projection(xy_t p, xy_t b) { return b*dot_product(p,b)/norm(b); }//投影
//対図形

#define mod 1000000007
/*ll f[2001];
//int n,k とかしておく

ll pw(ll x, ll y){//euclidの互除法より
    ll a= 1;
    while(y){
        if(y&1){//奇数なら
            a = a*x%mod;
        }
        x = x*x%mod;
        y /= 2;
    }
    return a;
}

ll modinv(ll x){//逆元を求める
    return pw(x, mod - 2 );
}

ll comb(int n,int r){
    if(n<r){
        return 0;
    }
    return f[n] * modinv(f[r])%mod*modinv(f[n-r])%mod;
}//対combination//ただしfは用意してね
*/

struct BIT{
    vector<int> dat;
    int sz;
    BIT(int n){
        for(sz=1;sz<n;sz *= 2);
        dat.resize(++sz);
    }
    int q(int n){
        int ret = 0;
        for(int i=n;i>0;i-=i&-i)ret +=dat[i];//和の計算　iから最後の１のbit(i&-i 多分＆はビット積)を減算
        for(int i=n;i<sz;i+=i&-i) dat[i]++;//値の加算　iから最後mの１のbitを加算
        return ret;
    }
};
/*
// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
const int mod = 1000000007;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x=0):x((x%mod+mod)%mod){}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;//thisポインター　thisで自分自身のアドレス
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res+=a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res-=a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res*=a;
  }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const {
    return pow(mod-2);
  }
  mint& operator/=(const mint a) {
    return (*this) *= a.inv();
  }
  mint operator/(const mint a) const {
    mint res(*this);
    return res/=a;
  }
};
*/

int cost[9]={2,5,5,4,5,6,3,7,6};

vector<char> ok;

string smax(string s, string t){
    if(s.size()>t.size()) return s;
    else if(s.size()<t.size()) return t;
    return max(s,t);
}


int main(){
    int n,m;
    cin >> n>>m;
    rep(i,m){
        char a;
        cin >>a;
        ok.push_back(a);
    }
    vector<string> dp(10050, "-");
    dp[0]="";
    rep(i,n){
        if(dp[i]=="-") continue;
        rep(j,ok.size()){
            dp[i+cost[ok[j]-'0'-1]]=smax(dp[i+cost[ok[j]-'0'-1]],dp[i]+ok[j]);
        }
    }
    
    cout<<dp[n]<<endl;
}