#define _FORTIFY_SOURCE 0
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP(i,b) for(int i=0;i<(int)(b);i++)
#define FORD(i,a,b) for(int i=(a);i>=(int)(b);i--)
#define REPD(i,b) for(int i=(int)(b)-1;i>=0;i--)
typedef long long ll;
typedef long double ldouble;
const int N = 121;
const int BASE = int(1e9);
const int BASE_LG = 9;
struct bignum_t {
int a[N / BASE_LG + 1], n = 0;
inline bignum_t() {}
inline bignum_t(const char *s) { FromStr(string(s)); }
inline int& operator[](int i) { return a[i]; }
inline const int& operator[](int i) const { return a[i]; }
inline void CleanZeros() {
while (n && !a[n - 1]) n--;
}
inline bool IsZero() const { return !n; }
inline int StringToInt(const string &s, int st, int ed) {
int res = 0;
FOR(i, st, ed - 1) res = res * 10 + s[i] - '0';
return res;
}
inline void FromStr(const string &s, int first = 0, int last = -1) {
if (last == -1) last = s.size();
n = 0;
int i = last;
for (; i > first; i -= BASE_LG)
a[n++] = StringToInt(s, max(i - BASE_LG, first), i);
CleanZeros();
}
inline bignum_t& operator=(const string &s) {
FromStr(s);
return *this;
}
inline operator string() const {
stringstream ss;
REPD(i, n) {
if (i != n - 1) ss << setw(BASE_LG) << setfill('0');
ss << a[i];
}
return ss.str();
}
inline operator ldouble() const {
ldouble res = 0;
REPD(i, n) res = res * BASE + a[i];
return res;
}
inline bool operator<(const bignum_t &b) const {
if (n != b.n) return n < b.n;
REPD(i, n) if (a[i] != b[i]) return a[i] < b[i];
return false;
}
inline bool operator<=(const bignum_t &b) const {
if (n != b.n) return n < b.n;
REPD(i, n) if (a[i] != b[i]) return a[i] < b[i];
return true;
}
inline bignum_t operator-(const bignum_t &b) const {
bignum_t c; c.n = n;
int carry = 0;
REP(i, n) {
int B = (i < b.n) ? b[i] : 0;
c[i] = a[i] - B - carry, carry = 0;
if (c[i] < 0) {
c[i] += BASE;
carry = 1;
}
}
c.CleanZeros();
return c;
}
};
const bignum_t EPS{ "5000" };
string str_S, str_X;
bignum_t range_val[N][N];
ldouble range_ld[N][N];
int ranges_idx[N][N];
struct range_t {
int u, v;
inline range_t() : u(0), v(0) {}
inline range_t(int u, int v) : u(u), v(v) {}
inline const bignum_t& GetVal() const { return range_val[u][v]; }
inline operator ldouble() const { return range_ld[u][v]; }
inline void SetStatus(bool active) const;
inline bool HasLeadingZero() const { return str_S[u] != '0'; }
inline int Len() const { return v - u; }
inline int SIdx() const { return ranges_idx[u][v]; }
};
bignum_t S, X;
int n, m;
int Plus[N] = {};
uint64_t rangeset_mask[N][N][2];
const int MBITS = 64;
struct rangeset_t {
uint64_t a[2] = {};
inline bool Conflict(const range_t &r) {
uint64_t(&m)[2] = rangeset_mask[r.u][r.v];
return (m[0] & a[0]) || (m[1] & a[1]);
}
inline void Set(const range_t &r) {
uint64_t(&m)[2] = rangeset_mask[r.u][r.v];
a[0] |= m[0], a[1] |= m[1];
}
inline void Clear(const range_t &r) {
uint64_t(&m)[2] = rangeset_mask[r.u][r.v];
a[0] &= ~m[0], a[1] &= ~m[1];
}
inline int Find(int from, bool val) {
uint64_t x[2] = { a[0], a[1] };
if (from < MBITS) {
x[0] >>= from;
for (; from < MBITS && from < n; x[0] >>= 1, from++)
if ((x[0] & 1) == val) return from;
}
x[1] >>= from - MBITS;
for (; from < n; x[1] >>= 1, from++)
if ((x[1] & 1) == val) return from;
return from;
}
inline bool operator[](int i) {
uint64_t &x = (i < MBITS) ? (a[0]) : (i -= MBITS, a[1]);
return (x >> i) & 1;
}
inline void GetZeros(vector<int> &v, int &t) {
int cnt = 0, k = 0; t = 0;
uint64_t x[2] = { a[0], a[1] };
REP(q, 2) {
REP(i, MBITS) {
if (k++ >= n) goto end;
if ((x[q] & 1) == 0) cnt++;
else if (cnt) {
v.push_back(cnt), t += cnt;
cnt = 0;
}
x[q] >>= 1;
}
}
end:
if (cnt) v.push_back(cnt), t += cnt;
}
inline void Reset() {
a[0] = a[1] = 0;
}
};
rangeset_t mark;
inline void range_t::SetStatus(bool active) const {
active ? mark.Set(*this) : mark.Clear(*this);
active ? (Plus[u]++, Plus[v]++) : (Plus[u]--, Plus[v]--);
}
inline void SetBitRange(uint64_t &a, int u, int v) {
a = (~((~0ull) << (v - u))) << u;
}
inline void InitRangeSet(int u, int v) {
uint64_t(&m)[2] = rangeset_mask[u][v];
if (u < MBITS) SetBitRange(m[0], u, min(MBITS, v));
if (v > MBITS) SetBitRange(m[1], max(u - MBITS, 0), v - MBITS);
}
std::istream& operator >>(std::istream &is, bignum_t &n)
{
string s; is >> s; n = s;
return is;
}
std::ostream& operator <<(std::ostream &os, const bignum_t &n)
{
os << (string)n;
return os;
}
vector<range_t> ranges;
typedef vector<range_t>::iterator rit;
ldouble nines[N];
void Init() {
REP(i, n) {
ldouble q = str_S[i] - '0';
FOR(j, i + 1, n) {
range_val[i][j].FromStr(str_S, i, j);
range_ld[i][j] = q;
q = q * 10 + str_S[j] - '0';
if (str_S[i] != '0' && range_val[i][j] <= X) {
ranges.emplace_back(i, j);
InitRangeSet(i, j);
}
}
}
struct sortr_cmp {
inline bool operator()(const range_t &a, const range_t &b) const {
return b.GetVal() < a.GetVal();
}
};
sort(ranges.begin(), ranges.end(), sortr_cmp());
memset(ranges_idx, -1, sizeof ranges_idx);
REP(i, ranges.size())
ranges_idx[ranges[i].u][ranges[i].v] = i;
FOR(i, 0, n) nines[i] = pow<ldouble>(10, i) - 1;
}
inline int FindRangeAtMost(const bignum_t &lim) {
struct findr_cmp {
inline bool operator()(const range_t &r, const bignum_t &b) {
return b < r.GetVal();
}
};
return lower_bound(ranges.begin(), ranges.end(), lim, findr_cmp())
- ranges.begin();
}
const ldouble ONE = 1.000001;
inline bool CheckMaxFast(const bignum_t &R, int from) {
if (R.IsZero()) return true;
while (from < (int)ranges.size() &&
mark.Conflict(ranges[from])) from++;
if (from >= (int)ranges.size()) return false;
static vector<int> its; its.clear();
int unset_len = 0;
mark.GetZeros(its, unset_len);
ldouble ldR = R, E = ranges[from];
int len = max(ranges[from].Len() - 1, 1);
ldouble Q = E * (unset_len / len) + nines[unset_len%len];
if (Q*ONE < ldR) return false;
ldouble S = 0;
REP(i, its.size()) {
const int &k = its[i];
S += E * (k / len) + nines[k%len];
if (S > ldR) return true;
}
return S*ONE > ldR;
}
vector<bool> visi[N];
bool DFS(int p, int R) {
if (visi[p][R]) return false;
else visi[p][R] = true;
if (p == n) return R == 0;
if (mark[p]) return DFS(mark.Find(p, 0), R);
int ed = mark.Find(p, 1);
int rlen = 1, rr = R;
for (rr /= 10; rr; rr /= 10, rlen++);
FOR(i, p + 1, min(ed, p + rlen)) {
int R2 = R - range_val[p][i][0];
if (R2 < 0) break;
if (DFS(i, R2)) {
Plus[i] = true;
return true;
}
}
return false;
}
inline bool InitDFS(int R) {
REP(i, n + 1) visi[i].assign(R + 1, false);
return DFS(0, R);
}
bool Try(const bignum_t &R, int from) {
if (R < EPS) return InitDFS(R[0]);
for (int i = max(FindRangeAtMost(R), from);
i < (int)ranges.size(); i++) {
if (mark.Conflict(ranges[i])) continue;
if (!CheckMaxFast(R, i)) break;
ranges[i].SetStatus(true);
if (Try(R - ranges[i].GetVal(), i + 1)) return true;
ranges[i].SetStatus(false);
}
return false;
}
inline void Input() {
cin >> str_S >> str_X;
S = str_S, X = str_X;
n = str_S.size(), m = str_X.size();
}
inline void Output() {
REP(i, n) {
if (i && Plus[i]) cout << '+';
cout << str_S[i];
}
cout << '\n';
}
inline void Reset() {
FOR(i,0,n) Plus[i] = false;
mark.Reset();
ranges.clear();
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T; cin >> T;
REP(i,T) {
Input();
Reset();
Init();
Try(X, 0);
Output();
}
return 0;
}