Problem:
一は零，零は一
あなたは "二進の錬金術師" の名を与えられた著名な錬金術師である．その二つ名が表す通り，求めに応じて '0' と '1' からなる二進文字列を意のままに錬成するのがあなたの得意分野だ．ただし，錬金術の基本は等価交換．無から有を生み出すことはできない．そのためあなたは以下の手順に従って二進文字列を錬成する．
予め錬成素材となるいくつかの二進文字列を文字列集合
S
としてストックしておく．
空文字列から始め，
S
から任意の文字列を 1 つ選んで語尾に連結していくことを任意の回数繰り返す．ここで，同じ文字列を何度も選んでも構わない．
連結された文字列に対し，任意の隣り合った 2 文字の交換を任意の回数繰り返す．
あなたは与えられた二進文字列
t
と二進文字列集合
S
に対し，
S
を素材となる文字列集合とし，上記の手順に従って
t
を錬成したい．このとき，
t
を錬成する手順が複数通り考えられる場合，手順 3. における交換回数が少ないほど錬成に必要なエネルギーを抑えられるため，好ましい．それでもまだ複数通りの手順が考えられる場合，手順 2. の終了時点での二進文字列のうち辞書順で最小のものを採用することで錬成陣を簡潔化できるため，より望ましい．
あなたはできる限り瞬時に術を発動できるようにするため，補助装置として手順 2. の終了時点での最適な文字列を自動で求めるプログラムを開発することにした．ここで，どのような手順を踏んでも手持ちの
S
からは
t
を錬成できない場合も考えられる．その場合は "IMPOSSIBLE" と出力することとする．
Input
入力は複数のデータセットからなる．
各データセットは 1 つの整数
n
を含む 1 行から始まる．これは文字列集合
S
に含まれる文字列が
n
個であることを表し，
1 ≤ n ≤ 100
を満たす．
続く
n
行の
i
行目は，
S
に含まれる
i
番目の二進文字列
S
i
を表す．
S
i
は '0' もしくは '1' のみからなり，その長さ
|S
i
|
は
1 ≤ |S
i
| ≤ 100
を満たす．すべての
1 ≤ i < j ≤ n
について，
S
i
≠ S
j
を満たすことが保証される．
続く 1 行は錬成したい文字列
t
を表す．
t
は '0' もしくは '1' のみからなり，その長さ
|t|
は
1 ≤ |t| ≤ 100
を満たす．
入力の終わりは 1 つのゼロからなる行で表される． 全データセットの総数は
100
を超えない．
Output
t
を錬成する手順の過程として手順 2. の終了時点で作られうる文字列を 1 行に出力せよ．ただし，そのような文字列が複数考えられる場合，手順 3. における隣り合った 2 文字の交換回数が最小となる文字列を出力せよ．それでも複数考えられる場合，辞書順で最小のものを出力せよ．そのような文字列が存在しない場合，"IMPOSSIBLE" と出力せよ．
Sample Input
2
00
1
010
3
110
011
0
010010
3
110
010
11
0110010
0
Output for the Sample Input
001
000110
IMPOSSIBLE

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int inf = 1 << 29;

void solve(int n) {
    vector<string> s(n);
    vector<vector<int>> sone(n);
    for (auto &i: s) cin >> i;
    vector<int> cnt1(n);
    for (int i = 0; i < n; i++) {
        int ct = 0;
        for (int j = 0; j < (int)s[i].size(); j++) {
            if (s[i][j] == '1') {
                ct++;
                sone[i].push_back(j);
            }
        }
        cnt1[i] = ct;
    }
    string t;
    cin >> t;
    int cntt = 0;
    vector<int> ones;
    for (int i = 0; i < (int)t.size(); i++) {
        if (t[i] == '1') {
            cntt++;
            ones.push_back(i);
        }
    }
    vector dp(t.size() + 1, vector<pair<int, string>>(cntt + 1, make_pair(inf, "")));
    dp[0][0].first = 0;
    for (int i = 0; i < (int)t.size(); i++) {
        for (int j = 0; j < cntt + 1; j++) {
            if (dp[i][j].first == inf) continue;
            for (int k = 0; k < n; k++) {
                if (i + s[k].size() > t.size()) continue;
                if (j + cnt1[k] > cntt) continue;
                int score = 0;
                for (int idx = 0; idx < cnt1[k]; idx++) {
                    score += abs(sone[k][idx] + i - ones[j + idx]);
                }
                int kscore = dp[i][j].first + score;
                string ks = dp[i][j].second + s[k];
                if (kscore < dp[i + s[k].size()][j + cnt1[k]].first) {
                    dp[i + s[k].size()][j + cnt1[k]].first = kscore;
                    dp[i + s[k].size()][j + cnt1[k]].second = dp[i][j].second + s[k];
                }
                else if (dp[i][j].first + score == dp[i + s[k].size()][j + cnt1[k]].first && ks < dp[i + s[k].size()][j + cnt1[k]].second) {
                    dp[i + s[k].size()][j + cnt1[k]].second = ks;
                }
            }
        }
    }
    if (dp.back().back().first == inf) cout << "IMPOSSIBLE\n";
    else cout << dp.back().back().second << "\n";
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    while (true) {
        int n;
        cin >> n;
        if (n == 0) break;
        solve(n);
    }
}
accuracy: 1
time_ms: 350
memory_kb: 4476
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rrep(i, n) for (int i = (int)(n) - 1; 0 <= i; --i)
template <typename T> bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
void solve();
int n;
string s[100],t;
signed main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  cout << fixed << setprecision(20);
  int TESTCASES = 1<<30;
  //cin >> TESTCASES;
  while (TESTCASES--) {
    cin>>n;
    if(n==0)break;
    rep(i,n)cin>>s[i];
    cin>>t;
    solve();
  }
}
void solve() {
  using i128=__int128_t;
  vector<i128>val(n);
  rep(i,n){
    rep(j,s[i].size()){
      val[i]=2*val[i]+(s[i][j]-'0');
    }
  }
  int m=t.size();
  vector<vector<int>>indices(n+1);
  rep(i,n)rep(j,s[i].size())if(s[i][j]=='1')indices[i].emplace_back(j);
  rep(i,m)if(t[i]=='1')indices[n].emplace_back(i);
  int t1=indices[n].size();
  vector<int>cnt1(n);
  rep(i,n)rep(j,s[i].size())if(s[i][j]=='1')++cnt1[i];
  constexpr int inf=1<<30;
  vector dp(m+1,vector<pair<int,i128>>(t1+1,{inf,0}));
  dp[0][0]={0,0};
  rep(i,m)rep(j,t1+1){
    if(dp[i][j].first==inf)continue;
    rep(k,n){
      if(!(i+(int)s[k].size()<=m&&j+cnt1[k]<=t1))continue;
      int cost=0;
      rep(l,cnt1[k]){
        cost+=abs(indices[n][j+l]-(i+indices[k][l]));
      }
      i128 nval=dp[i][j].second<<s[k].size();
      nval+=val[k];
      chmin(dp[i+(int)s[k].size()][j+cnt1[k]],make_pair(cost+dp[i][j].first,nval));
    }
  }
  if(dp[m][t1].first==inf){
    cout<<"IMPOSSIBLE"<<'\n';
  }else{
    string ans;
    rep(i,m){
      ans+='0'+dp[m][t1].second%2;
      dp[m][t1].second/=2;
    }
    reverse(all(ans));
    cout<<ans<<'\n';
  }
}
accuracy: 1
time_ms: 40
memory_kb: 3840
final_rank: 3

code_snippet: //#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for (ll i=0;i<(ll)n;i++)
#define rrep(i,n) for (ll i=n-1;i>=(ll)0;i--)
#define loop(i,m,n) for(ll i=m;i<=(ll)n;i++)
#define rloop(i,m,n) for(ll i=m;i>=(ll)n;i--)
#define vl vector<long long>
#define vvl vector<vector<long long>>
#define vdbg(a) rep(ii,a.size()){cout<<a[ii]<<" ";}cout<<endl;
#define vvdbg(a) rep(ii,a.size()){rep(jj,a[ii].size()){cout<<a[ii][jj]<<" ";}cout<<endl;}
#define setdbg(a) for(const auto & ii:a){cout<<ii<<" ";}cout<<endl;
#define inf 4000000000000000000LL
#define mod 998244353LL
#define eps 0.000000001
//#define mod 1000000007LL
random_device rnd;// 非決定的な乱数生成器
mt19937 mt(rnd());// メルセンヌ・ツイスタの32ビット版、引数は初期シード

//#include<boost/multiprecision/cpp_int.hpp>
//#define bbi boost::multiprecision::cpp_int

//#include<atcoder/lazysegtree>

//√の値が整数かを調べる
bool isSqrt(ll n) {
	if (n < 0) return false;
	ll sqrtN = static_cast<ll>(sqrt(n));
	return sqrtN * sqrtN == n;
}

//整数同士の累乗の計算をする。
ll power(ll A, ll B) {
	ll result = 1;
	for (ll i=0;i<B;i++){
		result *= A;
	}
	return result;
}

//素因数分解
vector<ll> makePrime(ll n){
	vector<ll> factors;
	while (n % 2 == 0) {
		factors.push_back(2);
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors.push_back(i);
			n /= i;
		}
	}
	if (n > 2) {
		factors.push_back(n);
	}
	return factors;
}

//map形式で、nを素因数分解した値を返す
map<ll,ll> makeMapPrime(ll n){
	map<ll,ll> factors;
	while (n % 2 == 0) {
		factors[2]++;
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors[i]++;
			n /= i;
		}
	}
	if (n > 2) {
		factors[n]++;
	}
	return factors;
}

// nのk乗をmodで割った余りを計算
ll power_mod(ll n, ll k){
	long long result = 1;
	while (k > 0){
		if ((k&1) ==1)result=(result*n)%mod;
		n=n*n%mod;
		k >>= 1;
	}
	return result;
}

//mod mにおけるaの逆元を計算
ll modinv(ll a, ll m) {
	ll b = m, u = 1, v = 0;
	while (b) {
		ll t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= m; 
	if (u < 0) u += m;
	return u;
}

//場合の数 nCr を求める
ll ncr(ll n,ll r) {
	if(n<r)return 0;
	vvl dp(n+1,vl(r+1));
	rep (i,n+1)dp[i][0] = 1;
	rep (i,r+1)dp[i][i] = 1;
	loop (i,1,n){
		loop (j,1,min((ll)i-1,r)) {
			//nCr= n-1Cr-1 + n-1Cr
			dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
		}
	}
	return dp[n][r];
}

//受け取った文字列を、第2引数が0なら全て小文字に、1なら大文字に変換する関数
string cnvString(const string &str, int mode) {
	string result = str;
	if (mode == 0) {
		// 小文字に変換
		for (char &c : result) {
			c = tolower(c);
		}
	} else if (mode == 1) {
		// 大文字に変換
		for (char &c : result) {
			c = toupper(c);
		}
	}
	return result;
}

//第一引数で受け取った数を、第二引数で受け取った数の進数と見做して、第三引数の進数へ変換する。
string cnvBase(const string &str, ll from_base, ll to_base) {
	ll num = 0;
	//小文字があったら大文字に変換
	string num_str=cnvString(str,1);
	// 数値を10進数に変換
	for (char digit : num_str) {
		num = num * from_base + (isdigit(digit) ? digit - '0' : digit - 'A' + 10);
	}
	string result;
	// 数値を目的の基数に変換
	while (num > 0) {
		ll remainder = num % to_base;
		result.push_back(remainder < 10 ? remainder + '0' : remainder - 10 + 'A');
		num /= to_base;
	}
	// 結果を逆順にして返す
	reverse(result.begin(), result.end());
	return result.empty() ? "0" : result;
}

//底がaの対数xを計算。ただし小数点は繰り上げ。
ll logax(ll a, ll x){
	if(x<=1)return 0;
	ll result = 1;
	ll power = 1;
	while (power < (x+a-1) / a){
		power *= a;
		result++;
	}
	return result;
}

//第一引数を第二引数で割った余りを計算、割る数はint範囲
ll bigmd(const string &num, int md) {
	ll ans = 0;
	ll SIZ = 9; //9桁のチャンク
	ll base = 1000000000;//SIZ個の0
	rep(i,(num.size()-1)/SIZ+1){
		ll chunk = 0;
		ll l = i*SIZ;
		ll r = min((ll)num.size(),l+SIZ);
		if(r!=num.size()){
			ans = (ans*base+stoll(num.substr(l,r-l)))%md;
		}else{
			rep(i,r-l)ans*=10;
			ans=(ans+stoll(num.substr(l,r-l)))%md;
		}
	}
	return ans;
}

//受け取った2次元文字の外側に、文字pをコーティングする。
vector<string> pad(vector<string> &s,char p){
	ll h=s.size();
	ll w=s[0].size();
	vector<string> res(h+2,string(w+2,p));
	rep(i,h)rep(j,w)res[i+1][j+1]=s[i][j];
	return res;
}

//ax+by=cの整数解を得る ただし、cはgcd(a,b)の倍数でない場合、0,0になる
pair<ll,ll> ex_euclid(ll a,ll b,ll c){
	if(a<0||b<0||c<0){
		pair<ll,ll>ans=ex_euclid(abs(a),abs(b),abs(c));
		if(a<0)ans.first*=-1;
		if(b<0)ans.second*=-1;
		if(c<0)ans.first*=-1,ans.second*=-1;
		return ans;
	}
	if(c!=1){
		ll d=gcd(a,b);
		if(c%d!=0)return make_pair(0,0);
		pair<ll,ll>ans = ex_euclid(a/d,b/d,1);
		ans.first*=c/d;
		ans.second*=c/d;
		return ans;
	}
	if(a<b){
		pair<ll,ll>ans=ex_euclid(b,a,c);
		swap(ans.first,ans.second);
		return ans;
	}
	if(a==1&&b==0)return make_pair(1,0);
	else if(b==0) return make_pair(0,0);
	ll x,y;
	tie(x,y)=ex_euclid(b,a%b,c);
	pair<ll,ll> ans=make_pair(y,x-(a/b)*y);
	return ans;
}

//オイラーのトーシェント関数。N以下のNと互いに素な物の数を返す。
ll euler(ll n){
	unordered_map<ll,ll> factors;
	ll tmp=n;
	while (tmp % 2 == 0) {
		factors[2]++;
		tmp /= 2;
	}
	for (ll i=3; i*i<=tmp;i+=2) {
		while (tmp%i == 0) {
			factors[i]++;
			tmp/= i;
		}
	}
	if (tmp > 2)factors[tmp]++;
	ll ans=1;
	for(const auto & val:factors){
		ans*=power(val.first,val.second-1)*(val.first-1);
	}
	return ans;
}

// Union-Find
struct UnionFind {
	vector<int> par, siz;
	UnionFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return par[x] = root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	// x を含むグループと y を含むグループとを併合する
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if (x == y) return false; 
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	// x を含むグループのサイズ
	int size(int x) {
		return siz[root(x)];
	}
};

//重み付きUF
struct PotentialUnionFind {
	ll n;
	vl par, siz, pot;
	PotentialUnionFind(ll N) : par(N,-1) , siz(N,1) , pot(N,0){n=N;}
	// 根を求める
	ll root(ll x) {
		if (par[x] == -1) return x;
		ll tmp = root(par[x]);
		pot[x] += pot[par[x]];
		par[x] = tmp;
		return par[x];
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(ll x, ll y) {
		return root(x) == root(y);
	}
	//x よりいくつ大きい所に y があるか。根が一致しない場合は"0"
	ll potential(ll x,ll y){
		if(root(x) != root(y)) return 0;
		else return pot[y]-pot[x];
	}
	//x より w だけ大きい状態として y を併合。
	bool unite(ll x, ll y, ll w) {
		ll rx = root(x),ry = root(y);
		if (rx == ry) return false;
		w += pot[x]-pot[y];
		if (siz[rx] < siz[ry]) swap(rx, ry),w*=-1;
		par[ry] = rx;
		siz[rx] += siz[ry];
		siz[ry] = 0;
		pot[ry] = w;
		return true;
	}
	// x を含むグループのサイズ
	ll size(ll x) {
		return siz[root(x)];
	}
	//小さい順にUnionFindグラフを調整、O(n log n)
	void regulation(){
		vvl r(n);
		rep(i,n)r[root(i)].push_back(i);
		rep(i,n){
			if(r[i].size()==0)continue;
			ll mn = i;
			rep(j,r[i].size())if(pot[mn]>pot[r[i][j]])mn=r[i][j];
			siz[mn]=siz[i];
			siz[i]=0;
			ll tmp = pot[mn];
			rep(j,r[i].size()){
				pot[r[i][j]]-=tmp;
				par[r[i][j]] = mn;
			}
			par[mn]=-1;
		}
	}
	void debug(){
		rep(i,n)cout<<setw(4)<<left<<par[i]<<" ";
		cout<<endl;
		rep(i,n)cout<<setw(4)<<left<<pot[i]<<" ";
		cout<<endl;
	}
};

//分離可能UnionFind、経路圧縮をしない。
struct CuttingFind{
	vector<int> par, siz;
	CuttingFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	//根x と 根y のグループを併合する(お互い根ではない時、falseで何もしない)
	bool unite(int x, int y) {
		if (issame(x,y) || par[x] != -1 || par[y] != -1) {
			cout<<"error"<<endl;
			return false;
		}
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	//根の側から、その直系の子供を分離する。片方が根でもう片方が直系の子でなければならない。
	bool separate(int x,int y){
		if(par[y]==-1)swap(x,y);
		if(par[y]!=x||par[x]!=-1){
			cout<<"error2"<<endl;
			return false;
		}
		siz[x] -= siz[y];
		par[y]=-1;
		return true;
	}
	// x を含むグループのサイズを求める
	int size(int x) {
		return siz[root(x)];
	}
};
//セグ木,乗せる値の型が必要
template<typename T>
struct SegTree{
	ll size;
	ll tall;
	vector<T> data;
	function<T(T,T)> p;
	//セグ木に乗せる値の初期値をa配列にし、putの関数をセグ木に乗せる、dをデフォルト値に。
	SegTree(vector<T> a,function<T(T,T)> put,T d) : data(power(2,logax(2,a.size())+1)) {
		size = data.size()/2;
		tall=logax(2,size)+1;
		p=put;
		ll tmp=size;
		data = vector<T>(size*2,d);
		while(tmp!=0){
			if(tmp==size)rep(i,a.size())data[tmp+i]=a[i];
			else rep(i,tmp) data[tmp+i]=p(data[2*(tmp+i)],data[2*(tmp+i)+1]);
			tmp/=2;
		}
	}
	//更新、t番目の値をxにする。
	void update(ll t,T x){
		t+=size;
		while(t!=0){
			if(t>=size)data[t]=x;
			else data[t]=p(data[2*t],data[2*t+1]);
			t/=2;
		}
	}
	//取得、l~r区間内の評価値を取得する。
	T get(ll l,ll r){
		//lとrが範囲外なら範囲内に正す
		l=max(0LL,l);
		r=min(r,size-1);
		r++;
		T ans=data[0];
		ll pos=l+size;
		ll wid=1;
		//出来る限り上に上げきる。
		while(l+(wid*2)<=r){
			while(l%(wid*2)==0&&l+(wid*2)<=r)pos/=2,wid*=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		//上げ終わったので今度は下げる
		while(l!=r){
			while(l+wid>r)pos*=2,wid/=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		return ans;
	}
	//セグ木デバッグ用、丸ごと出力
	void print(){
		rep(i,size)cout<<setw(7)<<left<<i;
		cout<<endl;
		ll pos=size;
		rep(i,tall){
			rep(j,size){
				if(j%power(2,i)==0)cout<<setw(7)<<left<<data[pos],pos++;
				else cout<<"       ";
			}
			pos/=4;
			cout<<endl;
		}
	}
};

//グリッド問題等用
vl dx={1,0,-1,0};
vl dy={0,1,0,-1};


ll solve(){
	ll n;
	cin>>n;
	if(n==0){return 1;}
	
	vector<string> s(n);
	rep(i,n)cin>>s[i];

	vl cntone(n,0);
	rep(i,n){
		rep(j,s[i].size()){
			if(s[i][j]=='1')cntone[i]++;
		}
	}

	string t;
	cin>>t;
	vl basyo;
	rep(i,t.size()){
		if(t[i]=='1')basyo.push_back(i);
	}

	vector<vector<pair<ll,string>>> dp(200,vector<pair<ll,string>>(200,{inf,""}));
	dp[0][0]={0,""};

	
	rep(i,t.size()){
		loop(j,0,i){
			rep(k,n){
				//i文字,j個の1を見終えてる
				bool f=false;
				ll index=0;
				ll cost=0;
				rep(l,cntone[k]){
					while(s[k][index]=='0')index++;
					if(l+j==basyo.size()){
						f=true;
						break;
					}
					cost+=abs(basyo[l+j]-(index+i));
					index++;
				}
				if(f)continue;
				pair<ll,string> tmp={dp[i][j].first+cost,dp[i][j].second+s[k]};
				dp[i+s[k].size()][j+cntone[k]]=min(dp[i+s[k].size()][j+cntone[k]],tmp);
			}
		}
	}

	if(dp[t.size()][basyo.size()].first!=inf)cout<<dp[t.size()][basyo.size()].second<<endl;
	else cout<<"IMPOSSIBLE"<<endl;
	return 0;
}

//メイン
int main(){
	while(solve()==0);
	return 0;
}
accuracy: 1
time_ms: 1430
memory_kb: 5320
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

using u128 = __uint128_t;
int n;

u128 str2u(string& s) {
    u128 res = 0;
    for (auto c : s) {
        res <<= 1;
        res += c - '0';
    }
    return res;
}

void solve() {
    string s[n];
    rep(i, n) cin >> s[i];
    u128 s_bit[n];
    vector<vector<int>> pos1;
    pos1.reserve(n);
    rep(i, n) {
        s_bit[i] = str2u(s[i]);
        vector<int> ad{};
        rep(j, s[i].size()) {
            if (s[i][j] == '1') ad.push_back(j);
        }
        pos1.emplace_back(ad);
    }

    string t;
    cin >> t;
    int m = t.size();
    vector<int> pos1_t{};
    rep(i, m) if (t[i] == '1') pos1_t.push_back(i);
    int t1 = pos1_t.size();
    int inf = 1 << 20;

    pair<int, u128> dp[m + 1][t1 + 1];
    rep(i, m + 1) rep(j, t1 + 1) dp[i][j] = {inf, 0};
    dp[0][0] = {0, 0};
    rep(i, m) {
        rep(j, t1 + 1) {
            auto [cost, str] = dp[i][j];
            if (cost == inf) continue;
            rep(k, n) {
                int len_s = s[k].size();
                int ones = pos1[k].size();
                if (i + len_s > m) continue;
                if (j + ones > t1) continue;
                int add_cost = 0;
                rep(l, ones) add_cost += abs(i + pos1[k][l] - pos1_t[j + l]);
                dp[i + len_s][j + ones] =
                    min(dp[i + len_s][j + ones],
                        {cost + add_cost, (str << len_s) | s_bit[k]});
            }
        }
    }

    if (dp[m][t1].first == inf) {
        cout << "IMPOSSIBLE" << endl;
    } else {
        string ans = "";
        u128 b = dp[m][t1].second;
        rep(_, m) {
            ans += '0' + (b & 1);
            b >>= 1;
        }
        reverse(all(ans));
        cout << ans << endl;
    }
}

int main() {
    while (true) {
        cin >> n;
        if (n == 0) break;
        solve();
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3968
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n); i >= 0; i--)
#define range(i, l, r) for (int i = (int)(l); i < (int)(r); i++)
using ll = long long;

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "[";
    for (int i = 0; i < v.size(); i++) {
        os << v[i] << (i == (v.size() - 1) ? "" : ", ");
    }
    os << "]";
    return os;
}

template <typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2> p) {
    os << "{" << p.first << ", " << p.second << "}";
    return os;
}

using u128 = __uint128_t;
int n;

u128 str2u(string& s) {
    u128 res = 0;
    for (auto c : s) {
        res <<= 1;
        res += c - '0';
    }
    return res;
}

void solve() {
    string s[n];
    rep(i, n) cin >> s[i];
    u128 s_bit[n];
    vector<vector<int>> pos1;
    pos1.reserve(n);
    rep(i, n) {
        s_bit[i] = str2u(s[i]);
        vector<int> ad{};
        rep(j, s[i].size()) {
            if (s[i][j] == '1') ad.push_back(j);
        }
        pos1.emplace_back(ad);
    }

    string t;
    cin >> t;
    int m = t.size();
    vector<int> pos1_t{};
    rep(i, m) if (t[i] == '1') pos1_t.push_back(i);
    int t1 = pos1_t.size();
    int inf = 1 << 20;

    pair<int, u128> dp[m + 1][t1 + 1];
    rep(i, m + 1) rep(j, t1 + 1) dp[i][j] = {inf, 0};
    dp[0][0] = {0, 0};
    rep(i, m) {
        rep(j, t1 + 1) {
            auto [cost, str] = dp[i][j];
            if (cost == inf) continue;
            rep(k, n) {
                int len_s = s[k].size();
                int ones = pos1[k].size();
                if (i + len_s > m) continue;
                if (j + ones > t1) continue;
                int add_cost = 0;
                rep(l, ones) add_cost += abs(i + pos1[k][l] - pos1_t[j + l]);
                dp[i + len_s][j + ones] =
                    min(dp[i + len_s][j + ones],
                        {cost + add_cost, (str << len_s) | s_bit[k]});
            }
        }
    }

    if (dp[m][t1].first == inf) {
        cout << "IMPOSSIBLE" << endl;
    } else {
        string ans = "";
        u128 b = dp[m][t1].second;
        rep(_, m) {
            ans += '0' + (b & 1);
            b >>= 1;
        }
        reverse(all(ans));
        cout << ans << endl;
    }
}

int main() {
    while (true) {
        cin >> n;
        if (n == 0) break;
        solve();
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3968
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ull=unsigned long long;
using u128=__uint128_t;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define loop(n) for (int tjh = 0; tjh < (int)(n); tjh++)
constexpr int maxN=100;
constexpr int ma=1'000'000;
const string NO="IMPOSSIBLE";
array<u128,maxN>S;u128 T;string u;
array<int,maxN>Ssz;int Tsz;
array<array<int,maxN>,maxN>S1;array<int,maxN>T1;
array<int,maxN>S1sz;int T1sz;
array<array<pair<int,u128>,maxN+1>,maxN+1>dp;
pair<int,u128>val;u128 res;
signed main() {
  cin.tie(0)->sync_with_stdio(0);//NOLINT
  cout<<fixed<<setprecision(16);
  for (int N;cin>>N,N;) {
    fill_n(S1sz.begin(),N,0);T1sz=0;
    rep(i,N) {
      cin>>u;Ssz[i]=(int)u.size();
      S[i]=(u128)0;
      rep(j,Ssz[i]) {
        S[i]*=2;
        if (u[j]=='1')++S[i];
      }
      rep(j,Ssz[i]) {
        if (u[j]=='1') {
          S1[i][S1sz[i]++]=j;
        }
      }
    }
    cin>>u;Tsz=(int)u.size();
    T=(u128)0;
    rep(i,Tsz) {
      T*=2;
      if (u[i]=='1')++T;
    }
    rep(i,Tsz) {
      if (u[i]=='1') {
        T1[T1sz++]=i;
      }
    }
    rep(i,Tsz+1)rep(j,T1sz+1)dp[i][j].first=ma;
    dp[0][0]={0,(u128)0};
    rep(i,Tsz)rep(j,T1sz+1) {
      if (dp[i][j].first==ma)continue;
      rep(k,N) {
        if (i+Ssz[k]>Tsz)continue;
        if (j+S1sz[k]>T1sz)continue;
        val=dp[i][j];
        val.second=(val.second<<Ssz[k])+S[k];
        rep(l,S1sz[k]) {
          val.first+=abs(S1[k][l]+i-T1[l+j]);
        }
        if (dp[i+Ssz[k]][j+S1sz[k]]>val)dp[i+Ssz[k]][j+S1sz[k]]=val;
      }
    }
    if (dp[Tsz][T1sz].first==ma){cout<<NO<<'\n';}
    else {
      u.resize(0);res=dp[Tsz][T1sz].second;
      rep(i,Tsz){u+=(char)('0'+res%(u128)2);res>>=1;}
      ranges::reverse(u);cout<<u<<'\n';
    }
  }
}
accuracy: 1
time_ms: 30
memory_kb: 3968
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#include <unordered_map>
#include <stdlib.h>
using namespace std;
#define rep(i, a, n) for(ll i = a; i < n; i++)
#define rrep(i, a, n) for(ll i = a; i >= n; i--)
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(x) (x).begin(), (x).end()
//constexpr ll MOD = 1000000007;
constexpr ll MOD = 998244353;
constexpr int IINF = 1001001001;
constexpr ll INF = 1LL<<60;
template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

ll gcd(ll a, ll b){
    if(a%b == 0){
      return b;
    }else{
      return gcd(b, a%b);
    }
}

ll lcm(ll a, ll b){
    return a*b / gcd(a, b);
}

ll powMod(ll x, ll n) {
    if (n == 0) return 1 % MOD;
    ll val = powMod(x, n / 2);
    val *= val;
    val %= MOD;
    if (n % 2 == 1) val *= x;
    return val % MOD;
}

int main() {
    while(true){
        ll n; cin >> n;
        if(n == 0) break;
        vector<string> s(n);
        vector<vector<ll>> s0(n);
        rep(i,0,n) cin >> s[i];
        string t; cin >> t;
        ll m = t.size();
        // {
        //     vector<vector<ll>> vec(n);
        //     rep(i,0,n){
        //         rrep(j,s[i].size()-1,0)if(s[i][j] == '1') vec[i].push_back(s[i].size()-1-j);
        //         vec[i].push_back(INF);
        //         vec[i].push_back(i);
        //     }
        //     sort(all(vec));
        //     reverse(all(vec));
        //     vector<string> ns(n);
        //     rep(i,0,n) ns[i] = s[vec[i].back()];
        //     swap(s,ns);
        // }
        // rep(i,0,n){
        //     cout << s[i] << endl;
        // }
        ll cnt0 = 0, cnt1 = 0;
        for(auto x: t){
            if(x == '1') cnt1++;
            else cnt0++;
        }
        vector<ll> id0(cnt0);
        {
            ll cc = 0;
            rep(i,0,m){
                if(t[i] == '0') id0[cc] = i,cc++;
            }
        }
        rep(i,0,n){
            rep(j,0,s[i].size())if(s[i][j] == '0') s0[i].push_back(j);
        }
        vector<vector<vector<ll>>> num(n,vector<vector<ll>>(cnt0+1, vector<ll>(cnt1+1)));
        rep(i,0,n){
            rep(j,0,cnt0+1){
                if(j+s0[i].size() > cnt0) continue;
                vector<ll> cntminus(m+1, 0);
                ll mi = 0, pl = 0;
                ll now = 0;
                rep(k,0,s0[i].size()){
                    if(id0[j+k] <= j+s0[i][k]) pl++;
                    else{
                        mi++;
                        cntminus[id0[j+k]-(j+s0[i][k])]++;
                    }
                    now += abs(id0[j+k]-(j+s0[i][k]));
                }
                num[i][j][0] = now;
                rep(k,1,cnt1+1){
                    now += (pl-mi);
                    num[i][j][k] = now; 
                    mi -= cntminus[k];
                    pl += cntminus[k];
                }
            }
        }
        vector<vector<ll>> dp(cnt0+1, vector<ll>(cnt1+1,INF));
        vector<vector<string>> ansstr(cnt0+1, vector<string>(cnt1+1,""));
        dp[0][0] = 0;
        rep(sum,0,m+1){
            rep(i,0,cnt0+1){
                ll j = sum-i;
                if(j < 0 || j > cnt1 || dp[i][j] == INF) continue;
                rep(id,0,n){
                    if(i+s0[id].size() > cnt0 || j+s[id].size()-s0[id].size() > cnt1) continue;
                    if(dp[i+s0[id].size()][j+s[id].size()-s0[id].size()] > dp[i][j]+num[id][i][j]){
                        chmin(dp[i+s0[id].size()][j+s[id].size()-s0[id].size()],dp[i][j]+num[id][i][j]);
                        ansstr[i+s0[id].size()][j+s[id].size()-s0[id].size()] = ansstr[i][j]+s[id];
                    }
                    else if(dp[i+s0[id].size()][j+s[id].size()-s0[id].size()] == dp[i][j]+num[id][i][j]){
                        chmin(ansstr[i+s0[id].size()][j+s[id].size()-s0[id].size()],ansstr[i][j]+s[id]);
                    }
                }
            }
        }
        if(dp[cnt0][cnt1] == INF) cout << "IMPOSSIBLE" << endl;
        else{
            // ll n0 = cnt0, n1 = cnt1;
            // vector<ll> vec;
            // while(n0 > 0 || n1 > 0){
            //     vec.push_back(pre[n0][n1]);
            //     ll nn0 = n0-s0[pre[n0][n1]].size();
            //     ll nn1 = n1-(s[pre[n0][n1]].size()-s0[pre[n0][n1]].size());
            //     n0 = nn0;
            //     n1 = nn1;
            // }
            // reverse(all(vec));
            // string ans = "";
            // for(auto x: vec) ans += s[x];
            // cout << ans << endl;
            cout << ansstr[cnt0][cnt1] << endl;
            // cout << dp[2][0] << endl;
            // cout << dp[2][1] << endl;
        }
        // cout << num[1][2][0] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 5928
final_rank: 18

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T, typename S = T> S SUM(const vector<T> &a) {
    return accumulate(ALL(a), S(0));
}
template <typename S, typename T = S> S POW(S a, T b) {
    S ret = 1, base = a;
    for (;;) {
        if (b & 1)
            ret *= base;
        b >>= 1;
        if (b == 0)
            break;
        base *= base;
    }
    return ret;
}
template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define debug 1
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define debug 0
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 2 "library/Utility/random.hpp"

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]
    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]
    return get(R - L) + L;
}
double uniform() {
    return double(get(1000000000)) / 1000000000;
}
string str(int n) {
    string ret;
    rep(i, 0, n) ret += get('a', 'z');
    return ret;
}
template <typename Iter> void shuffle(Iter first, Iter last) {
    if (first == last)
        return;
    int len = 1;
    for (auto it = first + 1; it != last; it++) {
        len++;
        int j = get(0, len - 1);
        if (j != len - 1)
            iter_swap(it, first + j);
    }
}
template <typename T> vector<T> select(int n, T L, T R) { // [L,R]
    if (n * 2 >= R - L + 1) {
        vector<T> ret(R - L + 1);
        iota(ALL(ret), L);
        shuffle(ALL(ret));
        ret.resize(n);
        return ret;
    } else {
        unordered_set<T> used;
        vector<T> ret;
        while (SZ(used) < n) {
            T x = get(L, R);
            if (!used.count(x)) {
                used.insert(x);
                ret.push_back(x);
            }
        }
        return ret;
    }
}

void relabel(int n, vector<pair<int, int>> &es) {
    shuffle(ALL(es));
    vector<int> ord(n);
    iota(ALL(ord), 0);
    shuffle(ALL(ord));
    for (auto &[u, v] : es)
        u = ord[u], v = ord[v];
}
template <bool directed, bool multi, bool self>
vector<pair<int, int>> genGraph(int n, int m) {
    vector<pair<int, int>> cand, es;
    rep(u, 0, n) rep(v, 0, n) {
        if (!self and u == v)
            continue;
        if (!directed and u > v)
            continue;
        cand.push_back({u, v});
    }
    if (m == -1)
        m = get(SZ(cand));
    // chmin(m, SZ(cand));
    vector<int> ord;
    if (multi)
        rep(_, 0, m) ord.push_back(get(SZ(cand) - 1));
    else {
        ord = select(m, 0, SZ(cand) - 1);
    }
    for (auto &i : ord)
        es.push_back(cand[i]);
    relabel(n, es);
    return es;
}
vector<pair<int, int>> genTree(int n) {
    vector<pair<int, int>> es;
    rep(i, 1, n) es.push_back({get(i - 1), i});
    relabel(n, es);
    return es;
}
}; // namespace Random

/**
 * @brief Random
 */
#line 4 "sol.cpp"

int main() {
    for (;;) {
        int n;
        read(n);
        if (n == 0)
            break;
        vector<string> S(n);
        string T;
        read(S, T);

        int zero = 0, one = 0;
        vector<int> pos;
        rep(i, 0, SZ(T)) {
            char c = T[i];
            if (c == '0') {
                zero++;
                pos.push_back(i);
            } else {
                one++;
            }
        }
        using P = pair<ll, string>;
        vector dp(zero + 1, vector<P>(one + 1, P{INF, ""}));
        dp[0][0] = {0, ""};
        rep(z, 0, zero + 1) {
            rep(o, 0, one + 1) if (dp[z][o].first != INF) {
                rep(x, 0, n) {
                    int nz = z, no = o;
                    for (auto &c : S[x]) {
                        if (c == '0')
                            nz++;
                        else
                            no++;
                    }
                    if (nz > zero or no > one)
                        continue;
                    string nxt = dp[z][o].second + S[x];
                    vector<int> np;
                    rep(p, 0, SZ(nxt)) {
                        if (nxt[p] == '0')
                            np.push_back(p);
                    }
                    assert(SZ(np) == nz);
                    ll cost = 0;
                    rep(p, 0, nz) {
                        cost += abs(pos[p] - np[p]);
                    }
                    chmin(dp[nz][no], P{cost, nxt});
                }
            }
        }
        auto [cost, ret] = dp[zero][one];
        if (cost == INF)
            ret = "IMPOSSIBLE";
        print(ret);
    }
    return 0;
}
accuracy: 1
time_ms: 1060
memory_kb: 4096
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using i128 = __int128_t;
using P = pair<int, i128>;

const int inf = 1 << 30;
const i128 inf128 = i128(1) << 120;

bool solve() {
  int N;
  cin >> N;
  if (N == 0) return false;
  vector<string> S(N);
  for (int i = 0; i < N; i++) cin >> S[i];
  string T;
  cin >> T;
  array<vector<int>, 2> cnt;
  cnt[0] = cnt[1] = vector<int>(500, 0);
  int C0 = 0, C1 = 0;
  for (char c : T) {
    if (c == '0') {
      cnt[1][++C0] = C1;
    } else {
      cnt[0][++C1] = C0;
    }
  }
  vector<vector<P>> DP(C0 + 1, vector<P>(C1 + 1, {inf, inf128}));
  DP[0][0] = {0, 0};
  for (int n = 0; n <= C0; n++) {
    for (int m = 0; m <= C1; m++) {
      if (DP[n][m] == P{inf, inf128}) continue;
      auto [inv, val] = DP[n][m];
      for (int i = 0; i < N; i++) {
        int c0 = n, c1 = m;
        int ninv = inv;
        i128 nval = val;
        for (auto c : S[i]) {
          if (c == '0') {
            c0++;
            ninv += max(0, c1 - cnt[1][c0]);
            nval = 2 * nval;
          } else {
            c1++;
            ninv += max(0, c0 - cnt[0][c1]);
            nval = 2 * nval + 1;
          }
        }
        if (c0 <= C0 && c1 <= C1) {
          DP[c0][c1] = min(DP[c0][c1], P{ninv, nval});
        }
      }
    }
  }
  string ans = "";
  auto val = get<1>(DP[C0][C1]);
  if (val == inf128) {
    cout << "IMPOSSIBLE" << '\n';
    return true;
  }
  for (int i = 0; i < C0 + C1; i++) {
    ans = "01"[val >> i & 1] + ans;
  }
  cout << ans << '\n';
  return true;
}

int main() {
  while (solve()) {}
}
accuracy: 1
time_ms: 50
memory_kb: 3584
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
struct state {
    bool ok = false;
    int cost = 0;
    string str;
};
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    while (cin >> n, n) {
        vector<string> s(n);
        for (int i = 0; i < n; i++) cin >> s[i];
        string t;
        cin >> t;
        int m = t.size();
        vector<int> pos1;
        for (int i = 0; i < m; i++)
            if (t[i] == '1') pos1.push_back(i);
        int k = pos1.size();
        vector<int> len(n), cnt1(n);
        for (int i = 0; i < n; i++) {
            len[i] = s[i].size();
            cnt1[i] = count(s[i].begin(), s[i].end(), '1');
        }
        vector<vector<state>> dp(m + 1, vector<state>(k + 1));
        dp[0][0] = {true, 0, ""};
        for (int l = 0; l <= m; l++) {
            for (int c = 0; c <= k; c++) {
                if (!dp[l][c].ok) continue;
                for (int idx = 0; idx < n; idx++) {
                    int L = len[idx], ones = cnt1[idx];
                    if (l + L > m || c + ones > k) continue;
                    int add = 0, rank = 0;
                    for (int j = 0; j < L; j++)
                        if (s[idx][j] == '1') {
                            int cur = l + j;
                            add += abs(cur - pos1[c + rank]);
                            rank++;
                        }
                    int nl = l + L, nc = c + ones, ncost = dp[l][c].cost + add;
                    string nstr = dp[l][c].str + s[idx];
                    auto &st = dp[nl][nc];
                    if (!st.ok || ncost < st.cost ||
                        (ncost == st.cost && nstr < st.str)) {
                        st.ok = true;
                        st.cost = ncost;
                        st.str = move(nstr);
                    }
                }
            }
        }
        if (dp[m][k].ok)
            cout << dp[m][k].str << "\n";
        else
            cout << "IMPOSSIBLE\n";
    }
    return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 4568
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep2(i, n) for (ll i = 0; i < (n); i++)
#define rep3(i, a, b) for (ll i = (a); i < (b); i++)
#define overload(a, b, c, d, ...) d
#define rep(...) overload(__VA_ARGS__, rep3, rep2)(__VA_ARGS__)
#define all(a) begin(a), end(a)
bool chmin(auto& a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto& a, auto b) { return a < b ? a = b, 1 : 0; }

int solve() {
    int n;
    cin >> n;
    if (n == 0) return 1;
    vector<string> ss(n);
    rep(i, n) cin >> ss[i];
    string t;
    cin >> t;
    int one = count(all(t), '1');
    int zero = count(all(t), '0');
    auto cnt = [&](string s) {
        return pair<int, int>{count(all(s), '1'), count(all(s), '0')};
    };
    vector<int> ones, zeros;
    rep(i, ssize(t)) (t[i] == '1' ? ones : zeros).push_back(i);
    const int inf = 1e9;
    vector swp(one + 1, vector<int>(zero + 1, inf));
    vector dp(one + 1, vector<string>(zero + 1));

    auto cost = [&](string s) {
        int i = 0;
        int diff = 0;
        rep(j, ssize(s)) {
            if (s[j] == '1') {
                diff += abs(ones[i] - j);
                i++;
            }
        }
        return diff;
    };

    rep(i, one + 1) rep(j, zero + 1) {
        if (dp[i][j].empty() && !(i == 0 && j == 0)) continue;
        for (auto s: ss) {
            auto [di, dj] = cnt(s);
            auto cur = dp[i][j] + s;
            if (i + di <= one && j + dj <= zero) {
                auto c = cost(cur);
                if (dp[i + di][j + dj].empty()) {
                    dp[i + di][j + dj] = cur;
                    swp[i + di][j + dj] = c;
                } else if (chmin(swp[i + di][j + dj], c)) {
                    dp[i + di][j + dj] = cur;
                } else if (swp[i + di][j + dj] == c) {
                    chmin(dp[i + di][j + dj], cur);
                }
            }
        }
    }
    cout << (dp[one][zero].empty() ? "IMPOSSIBLE" : dp[one][zero]) << endl;
    return 0;
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    while (!solve());
}
accuracy: 1
time_ms: 540
memory_kb: 3968
final_rank: 13

code_snippet: // AOJ #3251 One is Zero, Zero is One
// 2025.3.6

#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int N;
    while(true) {
        cin >> N;
        if (N == 0) break;
        vector<string> pat(N);
        vector<vector<int>> one(N);
        for(int i = 0; i < N; i++){
            cin >> pat[i];
            one[i].clear();
            for(int j = 0; j < pat[i].size(); j++)
                if(pat[i][j] == '1') one[i].push_back(j);
        }

        string tt;
        cin >> tt;
        vector<int> t1;
        for(int j = 0; j < tt.size(); j++) if(tt[j] == '1') t1.push_back(j);

        int Tn = tt.size();
        int tot = t1.size();
        vector<vector<pair<int, string>>> dp(Tn + 1, vector<pair<int, string>>(tot + 1, {INF, ""}));
        dp[0][0] = {0, ""};

        for(int i = 0; i < Tn; i++){
            for(int j = 0; j <= tot; j++){
                if(dp[i][j].first < INF){
                    for(int k = 0; k < N; k++){
                        int pSize = pat[k].size();
                        int inp = one[k].size();
                        if(i + pSize <= Tn && j + inp <= tot){
                            pair<int, string> can;
                            can.second = dp[i][j].second + pat[k];
                            can.first = dp[i][j].first;
                            for(int t = 0; t < inp; t++)
                                can.first += abs((i + one[k][t]) - t1[j + t]);
                            int nx = i + pSize, k = j + inp;
                            if(dp[nx][k] > can) dp[nx][k] = can;
                        }
                    }
                }
            }
        }
        pair<int, string> ans = dp[Tn][tot];
        if(ans.first == INF) cout << "IMPOSSIBLE" << endl;
        else cout << ans.second << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 4056
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) a.begin(),a.end()
#define reps(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, a, n) for (int i = (a); i > (int)(n); i--)
const long long mod = 1000000007;
const long long INF = 1e18;
ll myceil(ll a, ll b) {return (a+b-1)/b;}


int n;

void solve() {
	vector<string> s(n);
	rep(i,n) {
		cin >> s[i];
	}

	vector<int> sc(n);
	vector<vector<int>> sone(n);
	rep(i,n) {
		int temp = 0;
		rep(j,s[i].length()) {
			if (s[i][j] == '1') {
				sone[i].push_back(j);
				temp++;
			}
		}
		sc[i] = temp;
	}

	// rep(i,n) {
	// 	cout << sc[i] << endl;
	// 	rep(j,sc[i]) {
	// 		cout << sone[i][j] << ' ';
	// 	}
	// 	cout << endl;
	// }


	string t;
	cin >> t;
	int tn = t.length();

	vector<int> tone(0);
	rep(i,tn) {
		if (t[i] == '1') {
			tone.push_back(i);
		}
	}
	int tc = tone.size();

	vector<vector<int>> dp(tn+1,vector<int> (tn+1,1000000));
	vector<vector<string>> dps(tn+1,vector<string> (tn+1,""));
	dp[0][0] = 0;
	rep(i,tn+1) {
		rep(j,i+1) {
			rep(k,n) {
				if (i + s[k].length() <= tn && j + sc[k] <= tc) {
					int temp = 0;
					rep(q,sc[k]) {
						temp += abs((sone[k][q]+i)-tone[q+j]);
					}
					if (dp[i+s[k].length()][j+sc[k]] > dp[i][j]+temp || (dp[i+s[k].length()][j+sc[k]] == dp[i][j]+temp && dps[i+s[k].length()][j+sc[k]] > dps[i][j]+s[k])) {
						dp[i+s[k].length()][j+sc[k]] = dp[i][j]+temp;
						dps[i+s[k].length()][j+sc[k]] = dps[i][j]+s[k];

						// cout << i << j << k << endl;
					}
				}
			}
		}
	}

	if (dps[tn][tc] != "") {
		cout << dps[tn][tc] << endl;
	}
	else {
		cout << "IMPOSSIBLE" << endl;
	}
	return;
}


int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
	while (cin >> n && n != 0) {
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 4448
final_rank: 10

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

void solve(int N){
    vc<string> S(N);rep(i, N) cin >> S[i];
    string T; cin >> T;
    int M = len(T);
    vi zero, one;
    int cnt0 = 0, cnt1 = 0;
    rep(i, M){
        if (T[i] == '0'){
            zero.push_back(cnt1);
            cnt0++;
        }else{
            one.push_back(cnt0);
            cnt1++;
        }
    }
    vv<pair<ll, __int128_t>> dp(M + 1, vc<pair<ll, __int128_t>>(M + 1, {INF, 0}));
    dp[0][0] = {0, 0};
    rep(i, M) rep(c0, i + 1){
        int c1 = i - c0;
        if (c0 > len(zero) || c1 > len(one)) continue;
        auto [r, cmb] = dp[i][c0];
        if (r == INF) continue;
        for (auto s : S){
            int nc0 = c0, nc1 = c1;
            ll nr = r;
            __int128_t nxt = cmb;
            bool flag = true;
            for (auto x : s){
                if (x == '0'){
                    if (nc0 >= len(zero)){
                        flag = false;
                        break;
                    }
                    nr += max(0, nc1 - zero[nc0]);
                    nc0++;
                    nxt <<= 1;
                }else{
                    if (nc1 >= len(one)){
                        flag = false;
                        break;
                    }
                    nr += max(0, nc0 - one[nc1]);
                    nc1++;
                    nxt <<= 1;
                    nxt++;
                }
            }
            if (flag) dp[nc0 + nc1][nc0] = min(dp[nc0 + nc1][nc0], {nr, nxt});
        }
    }
    auto [r, cmb] = dp[M][len(zero)];
    if (r == INF) cout << "IMPOSSIBLE" << endl;
    else{
        for (int i = M - 1; i >= 0; i--) cout << (cmb >> i & 1 ? 1 : 0);
        cout << endl;
    }
}
int main(){
    while (true){
        int N; cin >> N;
        if (N == 0) break;
        solve(N);
    }
}
accuracy: 1
time_ms: 110
memory_kb: 3472
final_rank: 1

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    using P=pair<ll,ll>;
    using tp=tuple<ll,ll,ll>;
    const int INF=1001001001;
    const ll INFL=1e18;
    const int mod=998244353;


    bool solve(){
		int n;
		cin>>n;
		if(n==0)return false;

		vector<string>s(n);
		rep(i,n)cin>>s[i];
		string t;
		cin>>t;

		vector<vector<int>>ps(n);
		rep(i,n){
			rep(j,s[i].size()){
				if(s[i][j]=='1')ps[i].push_back(j);
			}
		}
		int T=t.size();
		vector<int>pt;
		rep(i,t.size()){
			if(t[i]=='1')pt.push_back(i);
		}
		auto cost=[&](int i,int sz,int ones){
			ll sum=0;
			rep(k,ps[i].size()){
				sum+=abs(sz+ps[i][k]-pt[ones+k]);
			}
			return sum;
		};

		vector<vector<ll>>dp(T+5,vector<ll>(T+5,INFL));
		vector<vector<string>>dp2(T+5,vector<string>(T+5));
		dp[0][0]=0;
		rep(i,T){
			rep(j,T+1){
				rep(k,n){
					if(i+s[k].size()>T){continue;}
					if(j+ps[k].size()>pt.size()){continue;}
					if(dp[i+s[k].size()][j+ps[k].size()]>dp[i][j]+cost(k,i,j)){
						dp[i+s[k].size()][j+ps[k].size()]=dp[i][j]+cost(k,i,j);
						dp2[i+s[k].size()][j+ps[k].size()]=dp2[i][j]+s[k];
					}else if(dp[i+s[k].size()][j+ps[k].size()]==dp[i][j]+cost(k,i,j)){
						chmin(dp2[i+s[k].size()][j+ps[k].size()],dp2[i][j]+s[k]);
					}
				}
			}
		}

		if(dp[T][pt.size()]==INFL)cout<<"IMPOSSIBLE"<<endl;
		else cout<<dp2[T][pt.size()]<<endl;
		return true;
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);

		while(1){
			if(!solve())return false;
		}
		
        return 0;
    }
accuracy: 1
time_ms: 130
memory_kb: 4856
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<string> SS(N);
    vector<int> L(N);
    vector<vector<int>> V(N);
    rep(i,0,N) {
        string S;
        cin >> S;
        SS[i] = S;
        L[i] = S.size();
        rep(j,0,L[i]) {
            if (S[j] == '1') V[i].push_back(j);
        }
    }
    string T;
    cin >> T;
    int M = T.size();
    vector<int> X;
    rep(i,0,M) if (T[i] == '1') X.push_back(i);
    int C = X.size();
    vector<vector<int>> DP(M+1, vector<int>(C+1, inf));
    vector<vector<string>> DPS(M+1, vector<string>(C+1, ""));
    DP[0][0] = 0;
    rep(i,0,M+1) {
        rep(j,0,C+1) {
            if (DP[i][j]==inf) continue;
            rep(k,0,N) {
                if (i + L[k] > M || j + (int)V[k].size() > C) continue;
                int Next = DP[i][j];
                rep(l,0,V[k].size()) {
                    Next += abs(X[j+l]-(i+V[k][l]));
                }
                if (DP[i+L[k]][j+V[k].size()] > Next) {
                    DP[i+L[k]][j+V[k].size()] = Next;
                    DPS[i+L[k]][j+V[k].size()] = DPS[i][j] + SS[k];
                }
                else if (DP[i+L[k]][j+V[k].size()] == Next && DPS[i+L[k]][j+V[k].size()] > (DPS[i][j] + SS[k])) {
                    DPS[i+L[k]][j+V[k].size()] = DPS[i][j] + SS[k];
                }
            }
        }
    }
    if (DP[M][C] == inf) cout << "IMPOSSIBLE" << endl;
    else cout << DPS[M][C] << endl;
}
}
accuracy: 1
time_ms: 100
memory_kb: 4624
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<vvvb> vvvvb;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
#define sz(A) (ll)(A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (ll)(lower_bound(ALL(A),x)-A.begin())
#define UB(A,x) (ll)(upper_bound(ALL(A),x)-A.begin())
#define COU(A,x) (UB(A,x)-LB(A,x))
#define F first
#define S second
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.F<<" "<<p.S;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.F>>p.S;return is;}
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){REP(i,sz(v))os<<v[i]<<(i+1!=sz(v)?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<class T>bool chmax(T&a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T&a,T b){if(b<a){a=b;return 1;}return 0;}
const ll mod=998244353;
template<const long long int mod=998244353>
struct modint{
  using mint=modint<mod>;
  long long int x;
  modint(long long int _x=0):x(_x%mod){if(x<0)x+=mod;}
  long long int val(){return x;}
  mint&operator=(const mint&a){x=a.x;return *this;}
  mint&operator+=(const mint&a){x+=a.x;if(x>=mod)x-=mod;return *this;}
  mint&operator-=(const mint&a){x-=a.x;if(x<0)x+=mod;return *this;}
  mint&operator*=(const mint&a){x*=a.x;x%=mod;return *this;}
  friend mint operator+(const mint&a,const mint&b){return mint(a)+=b;}
  friend mint operator-(const mint&a,const mint&b){return mint(a)-=b;}
  friend mint operator*(const mint&a,const mint&b){return mint(a)*=b;}
  mint operator-()const{return mint(0)-*this;}
  mint pow(long long int n){
    if(!n)return 1;
    mint a=1;
    mint _x=x;
    while(n){
      if(n&1)a*=_x;
      _x=_x*_x;n>>=1;
    }
    return a;
  }
  mint inv(){return pow(mod-2);}
  mint&operator/=(mint&a){return *this*=a.inv();}
  friend mint operator/(const mint&a,mint b){return mint(a)/=b;}
};
using mint=modint<998244353>;
int main(){
    while(1){
        int N;cin>>N;
        if(!N)return 0;
        vector<string>S(N);cin>>S;
        vvi E(N);
        REP(i,N)REP(j,sz(S[i]))if(S[i][j]=='1')E[i].emplace_back(j);
        string T;cin>>T;
        vi F;
        REP(i,sz(T))if(T[i]=='1')F.emplace_back(i);
        vvi DP(sz(T)+1,vi(sz(F)+1,1e18));
        DP[0][0]=0;
        REP(i,sz(T))REP(j,sz(F)+1){
            REP(k,N){
                if(i+sz(S[k])<=sz(T)&&j+sz(E[k])<=sz(F)){
                    ll s=0;
                    REP(l,sz(E[k]))s+=abs(F[j+l]-E[k][l]-i);
                    chmin(DP[i+sz(S[k])][j+sz(E[k])],DP[i][j]+s);
                }
            }
        }
        if(DP[sz(T)][sz(F)]>1e17){cout<<"IMPOSSIBLE"<<endl;continue;}
        vector<vector<string>>EP(sz(T)+1,vector<string>(sz(F)+1,"2"));
        EP[0][0]="";
        REP(i,sz(T))REP(j,sz(F)+1){
            REP(k,N){
                if(i+sz(S[k])<=sz(T)&&j+sz(E[k])<=sz(F)){
                    ll s=0;
                    REP(l,sz(E[k]))s+=abs(F[j+l]-E[k][l]-i);
                    if(DP[i+sz(S[k])][j+sz(E[k])]==DP[i][j]+s)chmin(EP[i+sz(S[k])][j+sz(E[k])],EP[i][j]+S[k]);
                }
            }
        }
        cout<<EP[sz(T)][sz(F)]<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 4064
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long

signed main() {
    while (true) {
        int n;
        cin >> n;
        if (!n) {
            return 0;
        }
        vector<string> s(n);
        string t;

        for (int i = 0; i < n; i++) {
            cin >> s[i];
            reverse(s[i].begin(), s[i].end());
        }

        cin >> t;
        reverse(t.begin(), t.end());

        int64_t dp[101][202], geta = 100;

        vector<pair<int, int>> from[101][202];
        vector<int> used[101][202];

        for (int i = 0; i < 101; i++) {
            for (int j = 0; j < 202; j++) {
                dp[i][j] = INT_MAX;
            }
        }

        dp[0][geta] = 0;

        for (int i = 0; i < t.size(); i++) {
            for (int j = 0; j < 202; j++) {
                for (int k = 0; k < n; k++) {
                    if (i + s[k].size() > t.size()) {
                        continue;
                    }
                    if (dp[i][j] == INT_MAX) {
                        continue;
                    }

                    // cerr << i << " " << j - geta << " " << k << endl;

                    int jj = j, cost = dp[i][j];
                    for (int l = 0; l < s[k].size(); l++) {
                        cost += llabs(jj - geta);
                        if (s[k][l] == '1') {
                            jj++;
                        }
                        if (t[i + l] == '1') {
                            jj--;
                        }
                    }

                    if (0 > jj || jj >= 202) {
                        continue;
                    }

                    // cerr << s[k].size() << endl;

                    // cerr << i + s[k].size() << " " << jj << endl;
                    // cerr << cost << " " << dp[i + s[k].size()][jj] << endl;

                    if (cost < dp[i + s[k].size()][jj]) {
                        dp[i + s[k].size()][jj] = cost;
                        from[i + s[k].size()][jj] = {{i, j}};
                        used[i + s[k].size()][jj] = {k};
                    } else if (cost == dp[i + s[k].size()][jj]) {
                        from[i + s[k].size()][jj].push_back({i, j});
                        used[i + s[k].size()][jj].push_back(k);
                    }
                }
            }
        }

        if (dp[t.size()][geta] == INT_MAX) {
            cout << "IMPOSSIBLE" << endl;
            continue;
        }

        string dpp[101][202];
        for (int i = 0; i < 101; i++) {
            for (int j = 0; j < 202; j++) {
                dpp[i][j] = string(1, 'z');
            }
        }
        dpp[t.size()][geta] = "";

        for (int i = 0; i < n; i++) {
            reverse(s[i].begin(), s[i].end());
        }

        for (int i = t.size(); i > 0; i--) {
            for (int j = 0; j < 202; j++) {
                if (dpp[i][j] == "z") {
                    continue;
                }
                if (from[i][j].size()) {
                    // cerr << i << " " << j - geta << " " << from[i][j].size()
                    //<< endl;
                    for (int k = 0; k < from[i][j].size(); k++) {
                        // cerr << dpp[i][j] + s[used[i][j][k]] << endl;
                        int fi, fj;
                        tie(fi, fj) = from[i][j][k];
                        dpp[fi][fj] = min(
                            dpp[fi][fj], dpp[i][j] + s[used[i][j][k]]
                        );
                    }
                }
            }
        }
        cout << dpp[0][geta] << endl;
    }
}
accuracy: 1
time_ms: 250
memory_kb: 5928
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;

// ★★★★★ いわゆるQCFium、おまじない的につけとくと速い
#ifndef LOCAL_TEST
#pragma GCC target ("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif // LOCAL_TEST


// ★★★★★ 型名を短くする、ちょっと嬉しい
using ll = long long;
using pii = pair<int, int>; using pll = pair<ll, ll>;
using vi = vector<int>;  using vvi = vector<vi>; using vvvi = vector<vvi>;
using vl = vector<ll>;  using vvl = vector<vl>; using vvvl = vector<vvl>;
using vb = vector<bool>; using vvb = vector<vb>; using vvvb = vector<vvb>;
using vc = vector<char>; using vvc = vector<vc>; using vvvc = vector<vvc>;
using vd = vector<double>; using vvd = vector<vd>; using vvvd = vector<vvd>;
using vs = vector<string>; using vvs = vector<vector<string>>; using vvvs = vector<vector<vector<string>>>;

// ★★★ 多次元vector初期化用の関数、ちょっと癖があるけど短く書ける
// テンプレなし：vector dp(n+1, vector(m+1, vector<ll>(k+1, 0)));
// テンプレあり：auto dp = vvv<ll>(n+1, m+1, k+1, 0);
template<typename T> vector<vector<T>> vv(int h, int w, T val = T()) { return vector(h, vector<T>(w, val)); }
template<typename T> vector<vector<vector<T>>> vvv(int h1, int h2, int h3, T val = T()) { return vector(h1, vector(h2, vector<T>(h3, val))); }
template<typename T> vector<vector<vector<vector<T>>>> vvvv(int h1, int h2, int h3, int h4, T val = T()) { return vector(h1, vector(h2, vector(h3, vector<T>(h4, val)))); }

// ★★ いわゆるheapq、C++のデフォルトpriority_queueは大きい順（Python、Nimとは逆）に注意
template <class T> using priority_queue_min = priority_queue<T, vector<T>, greater<T>>;

// ★ 定数系、お好みで
constexpr double PI = 3.14159265358979323;
constexpr ll INFL = 3300300300300300491LL;
double EPSL = 1e-10;


// ★★★★ 入出力高速化、おまじない
struct Nyan { Nyan() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } nyan;

// マクロ類
// わりと全部使う
// all: sort(all(a)) とか lower_bount(all(a), x) とか
// rep: オーバーロードしているので、引数の個数で挙動が変わる、基本Pythonのrangeに近い感覚で使えるようにしてるはず
//      rep(5) -> 5回ループ（新たにループ変数は作らない）
//      rep(i, 5) -> i=0,1,...,4
//      rep(i, 5) -> i=0,1,...,4
//      rep(i, 1, 6) -> i=1,...,4
//      rep(i, 1, 6, 2) -> i=1,3,5
//      rep(i, 10, -1, -1) -> i=10,9,.., 0
// smod, sdiv: python-like mod, div
// uniq: 重複削除、ソートされるのに注意
// vl a = {1, 3, 2, 5, 2, 3}; uniq(a); // a = {1, 2, 3, 5}
#define all(a) (a).begin(), (a).end()
#define len(x) ((ll)(x).size())
#define rep1(n) for(ll dummy_iter = 0LL; dummy_iter < n; ++dummy_iter) // 0,1,...,n-1
#define rep2(i, n) for(ll i = 0LL, i##_counter = 0LL; i##_counter < ll(n); ++(i##_counter), (i) = i##_counter) // i=0,1,...,n-1
#define rep3(i, s, t) for(ll i = ll(s), i##_counter = ll(s); i##_counter < ll(t); ++(i##_counter), (i) = (i##_counter)) // i=s,s+1,...,t-1
#define rep4(i, s, t, step) for(ll i##_counter = step > 0 ? ll(s) : -ll(s), i##_end = step > 0 ? ll(t) : -ll(t), i##_step = abs(step), i = ll(s); i##_counter < i##_end; i##_counter += i##_step, i = step > 0 ? i##_counter : -i##_counter) // i=s,s+step,...,<t
#define overload4(a, b, c, d, e, ...) e
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define repe(a, v) for(auto& a : (v)) // iterate over all elements in v
#define smod(n, m) ((((n) % (m)) + (m)) % (m))
#define sdiv(n, m) (((n) - smod(n, m)) / (m))
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());}

// ★★ Yes, No なくても困らない
int Yes(bool b=true) { cout << (b ? "Yes\n" : "No\n"); return 0; };
int YES(bool b=true) { cout << (b ? "YES\n" : "NO\n"); return 0; };
int No(bool b=true) {return Yes(!b);};
int NO(bool b=true) {return YES(!b);};

// ★★★★ max, min, sum のvector向けオーバーロード、デフォルトがちょっと使いにくいので
template<typename T, size_t N> T max(array<T, N>& a) { return *max_element(all(a)); };
template<typename T, size_t N> T min(array<T, N>& a) { return *min_element(all(a)); };
template<typename T> T max(vector<T>& a) { return *max_element(all(a)); };
template<typename T> T min(vector<T>& a) { return *min_element(all(a)); };
template<typename T> vector<T> vec_slice(const vector<T>& a, int l, int r) { vector<T> rev; rep(i, l, r) rev.push_back(a[i]); return rev; };
template<typename T> T sum(vector<T>& a, T zero = T(0)) { T rev = zero; rep(i, sz(a)) rev += a[i]; return rev; };

// ★★★ vector の各要素を1増やす／減らす、グラフ系の入力受けでちょっと嬉しい
// vector<ll> a = {1, 2, 4}; ++a; // a = {2, 3, 5}
template <class T> inline vector<T>& operator--(vector<T>& v) { repe(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repe(x, v) ++x; return v; }

// ★★★★ 整数pow/sqrt
ll powm(ll a, ll n, ll mod=INFL) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = (res * a) % mod;
        if (n > 1) a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}
ll sqrtll(ll x) {
    assert(x >= 0);
    ll rev = ll(sqrt(x));
    while(rev * rev > x) --rev;
    while((rev+1) * (rev+1)<=x) ++rev;
    return rev;
}

// ★★★★ chmax, chmin
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; }
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; }

// ★★★★★ vector を直接cinできるようにする
// map, set, multiset とかを直接 cout できるようにする
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p);
template <class T> inline istream& operator>>(istream& is, vector<T>& v);
template <class T, class U> inline ostream& operator<<(ostream& os, const pair<T, U>& p);
template <class T> inline ostream& operator<<(ostream& os, const vector<T>& v);
template <typename T, typename S> ostream &operator<<(ostream &os, const map<T, S> &mp);
template <typename T> ostream &operator<<(ostream &os, const set<T> &st);
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &st);
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &st);
template <typename T> ostream &operator<<(ostream &os, deque<T> q);
template <class T, class Container, class Compare> ostream &operator<<(ostream &os, priority_queue<T, Container, Compare> pq);

// overload operators
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repe(x, v) is >> x; return is; }
template <class T, class U> inline ostream& operator<<(ostream& os, const pair<T, U>& p) { os << p.first << " " << p.second; return os; }
template <class T> inline ostream& operator<<(ostream& os, const vector<T>& v) { rep(i, sz(v)) { os << v.at(i); if (i != sz(v) - 1) os << " "; } return os; }
template <typename T, typename S> ostream &operator<<(ostream &os, const map<T, S> &mp) { for (auto &[key, val] : mp) { os << key << ":" << val << " "; } return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &st) { ll cnt = 0; for (auto &e : st) { os << e << (++cnt != (int)st.size() ? " " : ""); } return os; }
template <typename T> ostream &operator<<(ostream &os, deque<T> q) { while (q.size()) { os << q.front(); q.pop_front(); if (q.size()) os << " "; } return os; }
template <class T, class Container, class Compare> ostream &operator<<(ostream &os, priority_queue<T, Container, Compare> pq) { while (pq.size()) { os << pq.top() << " "; pq.pop(); } return os; }
#define out(x) cout << x << endl
#define dout(x) cout << fixed << setprecision(10) << x << endl
#line 2 "data-structure/rollback-union-find.hpp"

int main(){
    while(1){
        //cerr << endl;
        ll N;
        cin >> N;
        if(N == 0){
            return 0;
        }
        vvl S;
        vl lenS;
        vs PS;
        rep(i,N){
            string s;
            cin >> s;
            vl tmp;
            rep(i,len(s)){
                if(s[i] == '1'){
                    tmp.emplace_back(i);
                }
            }
            lenS.push_back(len(s));
            S.push_back(tmp);
            PS.push_back(s);
        }
        string t;
        cin >> t;
        vl T;
        rep(i,len(t)){
            if (t[i] == '1'){
                T.emplace_back(i);
            }
        }
        auto DP = vv(len(t)+1,len(T)+1,INFL);
        DP[0][0] = 0;
        auto now = vv<string>(len(t)+1,len(T)+1,"");
        rep(i,len(t)){
            rep(j,len(T)+1){
                //cerr << i << " "<< j << " " << now[i][j] <<" "<< DP[i][j] << endl;
                rep(k,len(S)){
                    if(j+len(S[k]) <= len(T) && i+lenS[k] <= len(t)){
                        ll cnt = 0;
                        rep(l,len(S[k])){
                            cnt += abs(i+S[k][l]-T[j+l]);
                        }
                        if(chmin(DP[i+lenS[k]][j+len(S[k])],DP[i][j]+cnt)){
                            now[i+lenS[k]][j+len(S[k])] = now[i][j]+PS[k];
                        }else if(DP[i+lenS[k]][j+len(S[k])] == DP[i][j]+cnt){
                            string tmp = now[i][j]+PS[k];
                            if(now[i+lenS[k]][j+len(S[k])]>tmp){
                                now[i+lenS[k]][j+len(S[k])] = tmp;
                            }
                        }
                    }
                }
            }
        }
        if(DP[len(t)][len(T)] == INFL){
            cout << "IMPOSSIBLE" << endl;
        }else{
            cout << now[len(t)][len(T)] << endl;
        }
    }
}
accuracy: 1
time_ms: 150
memory_kb: 4532
final_rank: 11

code_snippet: // #include "my_template.hpp"
// // #include "string/rolling_hash.hpp"
// // RollingHash<mint261> rh(20000);
// using namespace std;
// 
// void solve(int N) {
//     VEC(string, S, N);
//     STR(T);
//     vector<pair<int, int>> S01cnt(N);
//     REP(i, N) {
//         S01cnt[i] = {0, 0};
//         FORE(c, S[i]) {
//             if (c == '0') {
//                 S01cnt[i].first++;
//             } else {
//                 S01cnt[i].second++;
//             }
//         }
//     }
//     show(S01cnt);
//     const int M = LEN(T);
//     vector<int> oneindex;
//     REP(i, M) if (T[i] == '1') oneindex.push_back(i);
//     const int M1 = LEN(oneindex), M0 = M - M1;
//     // dp[i][j] = 0 が i 個, 1 が j 個であるような文字列でスワップ回数が最小のもの
//     // dps[i][j] = 上記の文字列のうち辞書順最小のもの
//     vector dp(M0 + 1, vector<int>(M1 + 1, INF<int>));
//     vector dps(M0 + 1, vector<string>(M1 + 1));
//     dp[0][0] = 0;
//     REP(i, M0 + 1) {
//         REP(j, M1 + 1) {
//             if (dp[i][j] == INF<int>) continue;
//             REP(k, N) {
//                 auto [c0, c1] = S01cnt[k];
//                 if (i + c0 > M0 or j + c1 > M1) continue;
//                 i64 cost = 0;
//                 int cnt = 0;
//                 REP(l, LEN(S[k])) {
//                     if (S[k][l] == '1') {
//                         cost += abs(l + i + j - oneindex[j + cnt]);
//                         cnt++;
//                     }
//                 }
//                 if (chmin(dp[i + c0][j + c1], dp[i][j] + cost)) {
//                     dps[i + c0][j + c1] = dps[i][j] + S[k];
//                 } else if (dp[i + c0][j + c1] == dp[i][j] + cost) {
//                     chmin(dps[i + c0][j + c1], dps[i][j] + S[k]);
//                 }
//             }
//         }
//     }
//     int ans = dp[M0][M1];
//     if (ans == INF<int>) {
//         IMPOSSIBLE();
//     } else {
//         print(dps[M0][M1]);
//     }
//     return;
// }
// 
// int main() {
//     int N;
//     while (cin >> N, N != 0) solve(N);
//     return 0;
// }
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#ifdef RUTHEN_LOCAL
#include <debug.hpp>
#else
#define show(x) true
#endif

// type definition
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using f32 = float;
using f64 = double;
using f128 = long double;
template <class T> using pque = std::priority_queue<T>;
template <class T> using pqueg = std::priority_queue<T, std::vector<T>, std::greater<T>>;
// overload
#define overload4(_1, _2, _3, _4, name, ...) name
#define overload3(_1, _2, _3, name, ...) name
#define overload2(_1, _2, name, ...) name
// for loop
#define REP1(a) for (long long _ = 0; _ < (a); _++)
#define REP2(i, a) for (long long i = 0; i < (a); i++)
#define REP3(i, a, b) for (long long i = (a); i < (b); i++)
#define REP4(i, a, b, c) for (long long i = (a); i < (b); i += (c))
#define REP(...) overload4(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define RREP1(a) for (long long _ = (a)-1; _ >= 0; _--)
#define RREP2(i, a) for (long long i = (a)-1; i >= 0; i--)
#define RREP3(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define RREP(...) overload3(__VA_ARGS__, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define FORE1(x, a) for (auto&& x : a)
#define FORE2(x, y, a) for (auto&& [x, y] : a)
#define FORE3(x, y, z, a) for (auto&& [x, y, z] : a)
#define FORE(...) overload4(__VA_ARGS__, FORE3, FORE2, FORE1)(__VA_ARGS__)
#define FORSUB(t, s) for (long long t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
// function
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define SORT(a) std::sort((a).begin(), (a).end())
#define RSORT(a) std::sort((a).rbegin(), (a).rend())
#define REV(a) std::reverse((a).begin(), (a).end())
#define UNIQUE(a)                      \
    std::sort((a).begin(), (a).end()); \
    (a).erase(std::unique((a).begin(), (a).end()), (a).end())
#define LEN(a) (int)((a).size())
#define MIN(a) *std::min_element((a).begin(), (a).end())
#define MAX(a) *std::max_element((a).begin(), (a).end())
#define SUM1(a) std::accumulate((a).begin(), (a).end(), 0LL)
#define SUM2(a, x) std::accumulate((a).begin(), (a).end(), (x))
#define SUM(...) overload2(__VA_ARGS__, SUM2, SUM1)(__VA_ARGS__)
#define LB(a, x) std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x)))
#define UB(a, x) std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x)))
template <class T, class U> inline bool chmin(T& a, const U& b) { return (a > T(b) ? a = b, 1 : 0); }
template <class T, class U> inline bool chmax(T& a, const U& b) { return (a < T(b) ? a = b, 1 : 0); }
template <class T, class S> inline T floor(const T x, const S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
template <class T, class S> inline T ceil(const T x, const S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}
template <class T, class S> std::pair<T, T> inline divmod(const T x, const S y) {
    T q = floor(x, y);
    return {q, x - q * y};
}
// 10 ^ n
constexpr long long TEN(int n) { return (n == 0) ? 1 : 10LL * TEN(n - 1); }
// 1 + 2 + ... + n
#define TRI1(n) ((n) * ((n) + 1LL) / 2)
// l + (l + 1) + ... + r
#define TRI2(l, r) (((l) + (r)) * ((r) - (l) + 1LL) / 2)
#define TRI(...) overload2(__VA_ARGS__, TRI2, TRI1)(__VA_ARGS__)
// bit operation
// bit[i] (= 0 or 1)
#define IBIT(bit, i) (((bit) >> (i)) & 1)
// (0, 1, 2, 3, 4) -> (0, 1, 3, 7, 15)
#define MASK(n) ((1LL << (n)) - 1)
#define POW2(n) (1LL << (n))
// (0, 1, 2, 3, 4) -> (0, 1, 1, 2, 1)
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(i64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(i64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
// binary search
template <class T, class F> T bin_search(T ok, T ng, F& f) {
    while ((ok > ng ? ok - ng : ng - ok) > 1) {
        T md = (ng + ok) >> 1;
        (f(md) ? ok : ng) = md;
    }
    return ok;
}
template <class T, class F> T bin_search_real(T ok, T ng, F& f, const int iter = 100) {
    for (int _ = 0; _ < iter; _++) {
        T md = (ng + ok) / 2;
        (f(md) ? ok : ng) = md;
    }
    return ok;
}
// rotate matrix counterclockwise by pi / 2
template <class T> void rot(std::vector<std::vector<T>>& a) {
    if ((int)(a.size()) == 0) return;
    if ((int)(a[0].size()) == 0) return;
    int n = (int)(a.size()), m = (int)(a[0].size());
    std::vector res(m, std::vector<T>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            res[m - 1 - j][i] = a[i][j];
        }
    }
    a.swap(res);
}
// const value
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
// infinity
template <class T> constexpr T INF = 0;
template <> constexpr int INF<int> = 1'000'000'000;                 // 1e9
template <> constexpr i64 INF<i64> = i64(INF<int>) * INF<int> * 2;  // 2e18
template <> constexpr u32 INF<u32> = INF<int>;                      // 1e9
template <> constexpr u64 INF<u64> = INF<i64>;                      // 2e18
template <> constexpr f32 INF<f32> = INF<i64>;                      // 2e18
template <> constexpr f64 INF<f64> = INF<i64>;                      // 2e18
template <> constexpr f128 INF<f128> = INF<i64>;                    // 2e18
// I/O
// input
template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (auto&& i : v) is >> i;
    return is;
}
template <class... T> void in(T&... a) { (std::cin >> ... >> a); }
void scan() {}
template <class Head, class... Tail> void scan(Head& head, Tail&... tail) {
    in(head);
    scan(tail...);
}
// input macro
#define INT(...)     \
    int __VA_ARGS__; \
    scan(__VA_ARGS__)
#define I64(...)     \
    i64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define U32(...)     \
    u32 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define U64(...)     \
    u64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F32(...)     \
    f32 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F64(...)     \
    f64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F128(...)     \
    f128 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define STR(...)             \
    std::string __VA_ARGS__; \
    scan(__VA_ARGS__)
#define CHR(...)      \
    char __VA_ARGS__; \
    scan(__VA_ARGS__)
#define VEC(type, name, size)     \
    std::vector<type> name(size); \
    scan(name)
#define VEC2(type, name1, name2, size)          \
    std::vector<type> name1(size), name2(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i])
#define VEC3(type, name1, name2, name3, size)                \
    std::vector<type> name1(size), name2(size), name3(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i], name3[i])
#define VEC4(type, name1, name2, name3, name4, size)                      \
    std::vector<type> name1(size), name2(size), name3(size), name4(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i], name3[i], name4[i])
#define VV(type, name, h, w)                       \
    std::vector name((h), std::vector<type>((w))); \
    scan(name)
// output
template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    auto n = v.size();
    for (size_t i = 0; i < n; i++) {
        if (i) os << ' ';
        os << v[i];
    }
    return os;
}
template <class... T> void out(const T&... a) { (std::cout << ... << a); }
void print() { out('\n'); }
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {
    out(head);
    if (sizeof...(Tail)) out(' ');
    print(tail...);
}
// for interactive problems
void printi() { std::cout << std::endl; }
template <class Head, class... Tail> void printi(Head&& head, Tail&&... tail) {
    out(head);
    if (sizeof...(Tail)) out(' ');
    printi(tail...);
}
// bool output
void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void NO(bool t = 1) { YES(!t); }
void No(bool t = 1) { Yes(!t); }
void no(bool t = 1) { yes(!t); }
void POSSIBLE(bool t = 1) { print(t ? "POSSIBLE" : "IMPOSSIBLE"); }
void Possible(bool t = 1) { print(t ? "Possible" : "Impossible"); }
void possible(bool t = 1) { print(t ? "possible" : "impossible"); }
void IMPOSSIBLE(bool t = 1) { POSSIBLE(!t); }
void Impossible(bool t = 1) { Possible(!t); }
void impossible(bool t = 1) { possible(!t); }
void FIRST(bool t = 1) { print(t ? "FIRST" : "SECOND"); }
void First(bool t = 1) { print(t ? "First" : "Second"); }
void first(bool t = 1) { print(t ? "first" : "second"); }
void SECOND(bool t = 1) { FIRST(!t); }
void Second(bool t = 1) { First(!t); }
void second(bool t = 1) { first(!t); }
// I/O speed up
struct SetUpIO {
    SetUpIO() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout << std::fixed << std::setprecision(15);
    }
} set_up_io;
// #include "string/rolling_hash.hpp"
// RollingHash<mint261> rh(20000);
using namespace std;

void solve(int N) {
    VEC(string, S, N);
    STR(T);
    vector<pair<int, int>> S01cnt(N);
    REP(i, N) {
        S01cnt[i] = {0, 0};
        FORE(c, S[i]) {
            if (c == '0') {
                S01cnt[i].first++;
            } else {
                S01cnt[i].second++;
            }
        }
    }
    show(S01cnt);
    const int M = LEN(T);
    vector<int> oneindex;
    REP(i, M) if (T[i] == '1') oneindex.push_back(i);
    const int M1 = LEN(oneindex), M0 = M - M1;
    // dp[i][j] = 0 が i 個, 1 が j 個であるような文字列でスワップ回数が最小のもの
    // dps[i][j] = 上記の文字列のうち辞書順最小のもの
    vector dp(M0 + 1, vector<int>(M1 + 1, INF<int>));
    vector dps(M0 + 1, vector<string>(M1 + 1));
    dp[0][0] = 0;
    REP(i, M0 + 1) {
        REP(j, M1 + 1) {
            if (dp[i][j] == INF<int>) continue;
            REP(k, N) {
                auto [c0, c1] = S01cnt[k];
                if (i + c0 > M0 or j + c1 > M1) continue;
                i64 cost = 0;
                int cnt = 0;
                REP(l, LEN(S[k])) {
                    if (S[k][l] == '1') {
                        cost += abs(l + i + j - oneindex[j + cnt]);
                        cnt++;
                    }
                }
                if (chmin(dp[i + c0][j + c1], dp[i][j] + cost)) {
                    dps[i + c0][j + c1] = dps[i][j] + S[k];
                } else if (dp[i + c0][j + c1] == dp[i][j] + cost) {
                    chmin(dps[i + c0][j + c1], dps[i][j] + S[k]);
                }
            }
        }
    }
    int ans = dp[M0][M1];
    if (ans == INF<int>) {
        IMPOSSIBLE();
    } else {
        print(dps[M0][M1]);
    }
    return;
}

int main() {
    int N;
    while (cin >> N, N != 0) solve(N);
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3796
final_rank: 4