Problem:
The Secret Number
Your job is to find out the secret number hidden in a matrix,
each of whose element is a digit ('0'-'9') or a letter
('A'-'Z').  You can see an example matrix in Figure 1.
Figure 1:  A Matrix
The secret number and other non-secret ones are coded in a
matrix as sequences of digits in a decimal format.  You should
only consider sequences of digits
D
1
D
2
...
D
n
such that
D
k
+1
(1 <=
k
<
n
)
is either right next to or immediately below
D
k
in the matrix.  The secret you are
seeking is the largest number coded in this manner.
Four coded numbers in the matrix in Figure 1, i.e., 908820,
23140037, 23900037, and 9930, are depicted in Figure 2.  As you
may see, in general, two or more coded numbers may share a
common subsequence.  In this case, the secret number is
23900037, which is the largest among the set of all coded numbers
in the matrix.
Figure 2: Coded Numbers
In contrast, the sequences illustrated in Figure 3 should be
excluded: 908A2 includes a letter; the fifth digit of 23149930
is above the fourth; the third digit of 90037 is below right of
the second.
Figure 3: Inappropriate Sequences
Write a program to figure out the secret number from a given
matrix.
Input
The input consists of multiple data sets, each data set
representing a matrix.  The format of each data set is as
follows.
W
H
C
11
C
12
...
C
1
W
C
21
C
22
...
C
2
W
...
C
H
1
C
H
2
...
C
HW
In the first line of a data set, two positive integers
W
and
H
are given.
W
indicates the width (the
number of columns) of the matrix, and
H
indicates the
height (the number of rows) of the matrix.
W+H
is less
than or equal to 70.
H
lines follow the first line, each of which corresponds
to a row of the matrix in top to bottom order.  The
i
-th
row consists of
W
characters
C
i
1
C
i
2
...
C
iW
in left to right order.  You may
assume that the matrix includes at least one non-zero digit.
Following the last data set, two zeros in a line indicate the
end of the input.
Output
For each data set, print the secret number on a line.  Leading zeros
should be suppressed.
Sample Input
7 4
9R2A993
0E314A0
8A900DE
820R037
6 7
JH03HE
ID7722
0DA1AH
30C9G5
99971A
CA7EAI
AHLBEM
20 2
A1234567891234CBDEGH
BDEDF908034265091499
0 0
Output for the Sample Input
23900037
771971
12345908034265091499

Submitted solutions:

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

using namespace std;

string trimZeros(string s) {
    int idx = 0;
    while (idx < s.size() && s[idx] == '0') {
        ++idx;
    }
    return (idx == s.size()) ? "0" : s.substr(idx);
}

string maxNum(const string& a, const string& b) {
    string x = trimZeros(a);
    string y = trimZeros(b);
    if (x.size() != y.size()) return (x.size() > y.size()) ? x : y;
    return (x > y) ? x : y;
}

string findMaxNum(const vector<vector<char>>& grid, int h, int w) {
    vector<vector<string>> dp(h, vector<string>(w, ""));
    
    if (isdigit(grid[0][0])) dp[0][0] = grid[0][0];
    
    int col = 1;
    while (col < w) {
        if (isdigit(grid[0][col])) {
            dp[0][col] = dp[0][col - 1] + grid[0][col];
        }
        ++col;
    }
    
    int row = 1;
    while (row < h) {
        if (isdigit(grid[row][0])) {
            dp[row][0] = dp[row - 1][0] + grid[row][0];
        }
        ++row;
    }

    row = 1;
    while (row < h) {
        col = 1;
        while (col < w) {
            if (isdigit(grid[row][col])) {
                string fromAbove = dp[row - 1][col] + grid[row][col];
                string fromLeft = dp[row][col - 1] + grid[row][col];
                dp[row][col] = maxNum(fromAbove, fromLeft);
            }
            ++col;
        }
        ++row;
    }

    string best = "";
    row = 0;
    while (row < h) {
        col = 0;
        while (col < w) {
            best = maxNum(best, dp[row][col]);
            ++col;
        }
        ++row;
    }

    return best;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int w, h;
    while (cin >> w >> h && (w || h)) {
        vector<vector<char>> grid(h, vector<char>(w));
        
        int r = 0;
        while (r < h) {
            int c = 0;
            while (c < w) {
                cin >> grid[r][c];
                ++c;
            }
            ++r;
        }

        cout << trimZeros(findMaxNum(grid, h, w)) << "\n";
    }
    
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3336
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
int main(void) {
    while(true) {
        int w, h;
        cin >> w >> h;
        if(w == 0 and h == 0) break;
        vector<string> c(h);
        rep(i, 0, h) {
            cin >> c[i];
        }
        vector<vector<bool>> visited(h, vector<bool>(w));
        vector<vector<string>> dp(h, vector<string>(w));
        auto comp = [&](const string& s, const string& t) -> bool {
            if(s.size() != t.size()) {
                return s.size() < t.size();
            }
            return s < t;
        };
        auto dfs = [&](auto& dfs, int x, int y) -> string {
            if(visited[x][y]) return dp[x][y];
            visited[x][y] = true;
            string res = "";
            res += c[x][y];
            if(x + 1 < h and 0 <= c[x + 1][y] - '0' and c[x + 1][y] - '0' <= 9) {
                res = max(res, c[x][y] + dfs(dfs, x + 1, y), comp);
            }
            if(y + 1 < w and 0 <= c[x][y + 1] - '0' and c[x][y + 1] - '0' <= 9) {
                res = max(res, c[x][y] + dfs(dfs, x, y + 1), comp);
            }
            return dp[x][y] = res;
        };
        string ans = "";
        rep(i, 0, h) {
            rep(j, 0, w) {
                if(1 <= c[i][j] - '0' and c[i][j] - '0' <= 9) {
                    ans = max(ans, dfs(dfs, i, j), comp);
                }
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3588
final_rank: 15

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 = 3.141592653589793;
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); } }

string solve(int H, int W){
    vc<string> S(H); rep(i, H) cin >> S[i];
    vv<string> memo(H, vc<string>(W, "-1"));

    function<string(int, int)> dfs = [&](int i, int j) -> string{
        if (memo[i][j] != "-1") return memo[i][j];
        string ret = "";
        ret += S[i][j];
        if (i < H - 1 && isdigit(S[i + 1][j])){
            string tmp = S[i][j] + dfs(i + 1, j);
            if (len(tmp) > len(ret)) ret = tmp;
            else if (len(tmp) == len(ret) && tmp > ret) ret = tmp;
        }
        if (j < W - 1 && isdigit(S[i][j + 1])){
            string tmp = S[i][j] + dfs(i, j + 1);
            if (len(tmp) > len(ret)) ret = tmp;
            else if (len(tmp) == len(ret) && tmp > ret) ret = tmp;
        }
        return memo[i][j] = ret;
    };
    string ans = "0";
    rep(i, H) rep(j, W) if (isdigit(S[i][j]) && S[i][j] != '0'){
        if (memo[i][j] == "-1") memo[i][j] = dfs(i, j);
        if (len(memo[i][j]) > len(ans)) ans = memo[i][j];
        else if (len(memo[i][j]) == len(ans) && memo[i][j] > ans) ans = memo[i][j];
    }
    return ans;
}

int main(){
    vc<string> ans;
    while(true){
        int W, H; cin >> W >> H;
        if (W == 0) break;
        ans.push_back(solve(H, W));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3500
final_rank: 13

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

int ri() {
	int n;
	scanf("%d", &n);
	return n;
}

int main() {
	while (1) {
		int w = ri();
		int h = ri();
		if (!w || !h) break;
		std::vector<std::string> a(h);
		for (auto &i : a) std::cin >> i;
		
		std::vector<std::vector<std::string> > dp(h, std::vector<std::string>(w));
		for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) {
			if (isdigit(a[i][j]) && a[i][j] != '0') dp[i][j] = std::string(1, a[i][j]);
		}
		for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) {
			auto go = [&] (int ni, int nj) {
				if (!isdigit(a[ni][nj])) return;
				if (!dp[i][j].size() && a[ni][nj] == '0') return;
				std::string new_s = dp[i][j];
				new_s.push_back(a[ni][nj]);
				if (new_s.size() > dp[ni][nj].size() || 
					(new_s.size() == dp[ni][nj].size() && new_s > dp[ni][nj]))
					dp[ni][nj] = new_s;
			};
			if (i + 1 < h) go(i + 1, j);
			if (j + 1 < w) go(i, j + 1);
		}
		std::string res;
		for (auto i : dp) for (auto j : i) {
			if (res.size() < j.size() || 
				(res.size() == j.size() && res < j)) {
				res = j;
			}
		}
		std::cout << res << std::endl;
		
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3488
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
string comp(string a, string b){
    if(a.size()>b.size()) return a;
    if(a.size()<b.size()) return b;
    for(int i=0;i<a.size();i++){
        if(a[i]>b[i]) return a;
        if(a[i]<b[i]) return b;
    }
    return a;
}
int main(){
    int w, h;
    string ma, c[77], cnt[77][77], str;
    while(cin >> w >> h, w!=0){
        for(int i=0;i<h;i++) cin >> c[i];
        ma = "";
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                cnt[i][j] = "";
                if('1'<=c[i][j]&&c[i][j]<='9') cnt[i][j] += c[i][j];
                if('0'<=c[i][j]&&c[i][j]<='9'){
                    if(i>0&&cnt[i-1][j]!="") cnt[i][j] = comp(cnt[i][j], cnt[i-1][j]+c[i][j]);
                    if(j>0&&cnt[i][j-1]!="") cnt[i][j] = comp(cnt[i][j], cnt[i][j-1]+c[i][j]);
                }
                ma = comp(ma, cnt[i][j]);
            }
        }
        cout << ma << endl;
    }
    return(0);
}
accuracy: 1
time_ms: 10
memory_kb: 3316
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define drep(i,j,n) for(int i=0;i<(int)(n-1);i++)for(int j=i+1;j<(int)(n);j++)
#define trep(i,j,k,n) for(int i=0;i<(int)(n-2);i++)for(int j=i+1;j<(int)(n-1);j++)for(int k=j+1;k<(int)(n);k++)
#define codefor int test;scanf("%d",&test);while(test--)
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define yes(ans) if(ans)printf("yes\n");else printf("no\n")
#define Yes(ans) if(ans)printf("Yes\n");else printf("No\n")
#define YES(ans) if(ans)printf("YES\n");else printf("NO\n")
#define popcount(v) __builtin_popcountll(v)
#define vector2d(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define vector3d(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
using namespace std;
using ll = long long;
template<class T> using rpriority_queue = priority_queue<T, vector<T>, greater<T>>;
const int MOD=1000000007;
const int MOD2=998244353;
const int INF=1<<30;
const ll INF2=1LL<<60;
void scan(int& a){scanf("%d",&a);}
void scan(long long& a){scanf("%lld",&a);}
template<class T,class L>void scan(pair<T, L>& p){scan(p.first);scan(p.second);}
template<class T,class U,class V>void scan(tuple<T,U,V>& p){scan(get<0>(p));scan(get<1>(p));scan(get<2>(p));}
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i);}
template<class T> void scan(T& a){cin>>a;}
template<class T> void scan(vector<T>& vec){for(auto&& it:vec)scan(it);}
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){scan(head);in(tail...);}
void print(const int& a){printf("%d",a);}
void print(const long long& a){printf("%lld",a);}
void print(const double& a){printf("%.15lf",a);}
template<class T,class L>void print(const pair<T, L>& p){print(p.first);putchar(' ');print(p.second);}
template<class T> void print(const T& a){cout<<a;}
template<class T> void print(const vector<T>& vec){if(vec.empty())return;print(vec[0]);for(auto it=vec.begin();++it!= vec.end();){putchar(' ');print(*it);}}
void out(){putchar('\n');}
template<class T> void out(const T& t){print(t);putchar('\n');}
template <class Head, class... Tail> void out(const Head& head,const Tail&... tail){print(head);putchar(' ');out(tail...);}
template<class T> void dprint(const T& a){cerr<<a;}
template<class T> void dprint(const vector<T>& vec){if(vec.empty())return;cerr<<vec[0];for(auto it=vec.begin();++it!= vec.end();){cerr<<" "<<*it;}}
void debug(){cerr<<endl;}
template<class T> void debug(const T& t){dprint(t);cerr<<endl;}
template <class Head, class... Tail> void debug(const Head& head, const Tail&... tail){dprint(head);cerr<<" ";debug(tail...);}
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
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;}
ll updivide(ll a,ll b){return (a+b-1)/b;}
int msb(ll v){return 63-__builtin_clzll(v);}
template<class T> void chmax(T &a,const T b){if(b>a)a=b;}
template<class T> void chmin(T &a,const T b){if(b<a)a=b;}

int main(){
    int w,h;
    while(cin>>w>>h){
        if(!w)return 0;
        vector<string> A(h);
        in(A);
        vector<vector<string>> dp(h,vector<string>(w));
        auto compare=[&](string s,string t){
            if(s.size()>t.size())return s;
            if(t.size()>s.size())return t;
            return max(s,t);
        };
        auto compare2=[&](string s,string t){
            reverse(all(t));
            while(!t.empty()&&t.back()=='0')t.pop_back();
            reverse(all(t));
            return compare(s,t);
        };
        function<string(int,int)> rec=[&](int y,int x){
            if(y<0||y>=h||x<0||x>=w)return string("");
            if(A[y][x]>='A'&&A[y][x]<='Z')return string("");
            if(!dp[y][x].empty())return dp[y][x];
            dp[y][x]=A[y][x];
            dp[y][x]+=compare(rec(y+1,x),rec(y,x+1));
            return dp[y][x];
        };
        string ans;
        rep(y,h){
            rep(x,w){
                ans=compare2(ans,rec(y,x));
            }
        }
        out(ans);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3496
final_rank: 12

code_snippet: #include<iostream>

using namespace std;

char matrix[70][70];
string dp[70][70];

bool IsNumber(char c)
{
	return c >= 48 && c <= 57;
}

string RemoveHeadZero(string str_num)
{
	for (int i = 0; i < str_num.size(); i++)
		if (str_num[i] != '0')
			return str_num.substr(i);

	return "0";
}

int Compare(string str_num1, string str_num2)
{
	str_num1 = RemoveHeadZero(str_num1);
	str_num2 = RemoveHeadZero(str_num2);
	if (str_num1.size() > str_num2.size())
		return 1;
	if (str_num1.size() < str_num2.size())
		return -1;

	for (int i = 0; i < str_num1.size(); i++)
	{
		if (str_num1[i] > str_num2[i])
			return 1;
		if (str_num1[i] < str_num2[i])
			return -1;
	}

	return 0;
}

int main()
{
	int W, H;
	cin >> W >> H;
	while (true)
	{
		string ans = "";
		if (W == 0 && H == 0)
			break;

		for (int i = 0; i < H; i++)
		{
			for (int j = 0; j < W; j++)
			{
				cin >> matrix[i][j];
			}
		}
		for (int i = 0; i < W; i++)
		{
			if(!IsNumber(matrix[0][i])) continue;
			dp[0][i] = matrix[0][i];
			if (i != 0 && IsNumber(matrix[0][i - 1]))
				dp[0][i] = dp[0][i - 1] + matrix[0][i];
			if (Compare(dp[0][i],ans) == 1)
				ans = dp[0][i];
		}
		for (int i = 1; i < H; i++)
		{
			for (int j = 0; j < W; j++)
			{
				if (!IsNumber(matrix[i][j])) continue;
				dp[i][j] = matrix[i][j];
				if (IsNumber(matrix[i - 1][j]))
					dp[i][j] = dp[i - 1][j] + matrix[i][j];
				if (j != 0 && IsNumber(matrix[i][j - 1]))
				{
					string _left = dp[i][j - 1] + matrix[i][j];
					if (Compare(_left, dp[i][j]) == 1)
						dp[i][j] = _left;
				}
				if (Compare(dp[i][j], ans) == 1)
					ans = dp[i][j];
			}
		}
		ans = RemoveHeadZero(ans);
		cout << ans << endl;

		cin >> W >> H;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3632
final_rank: 18

code_snippet: #include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <vector>
using namespace std;
typedef long long ll;
char aa[75][75];
string str[75][75];
int w,h;         //h表示字符串的个数
bool rig(char c)
{
    if(c>='0'&&c<='9'){
        return true;
    }
    return false;
}
string mmax(string a,string b)
{
    if(a.size()>b.size()){
        return a;
    }
    else if(a.size()==b.size()){
        return max(a,b);
    }
    return b;
}
int main()
{
    while(scanf("%d%d",&w,&h)&&(w+h)){
        for(int i=0;i<h;i++){
            scanf("%s",aa[i]);
            for(int j=0;j<w;j++){
                str[i][j]="";
            }
        }
        if(rig(aa[0][0])&&aa[0][0]!='0'){
            str[0][0]+=aa[0][0];
        }
        string mx="";
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if(rig(aa[i][j])){
                    if(i-1>=0){
                        str[i][j]=mmax(str[i-1][j]+aa[i][j],str[i][j]);
                    }
                    if(j-1>=0){
                        str[i][j]=mmax(str[i][j-1]+aa[i][j],str[i][j]);
                    }
                    if(str[i][j][0]!='0'){
                        mx=mmax(str[i][j],mx);
                    }
                }
                int del=0;
                while(del<str[i][j].size()&&str[i][j][del]=='0') del++;
                str[i][j]=str[i][j].substr(del,str[i][j].size());
            }
        }
        cout<<mx<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3284
final_rank: 2

code_snippet: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <utility>
#define cs cout << "Wish You AC!" << endl;
#define js ios::sync_with_stdio(false); cin.tie(0);
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) (x&-x)
#define lson(x) x*2
#define rson(x) x*2 + 1
#define ll long long
#define ull unsigned long long
#define debug(x) std::cout << #x << " is " << (x) << '\n'
#define INF 1e14
#define pb push_back
using namespace std;
inline void read(ll &x){
    char c; int flag=0;
    while(!isdigit(c=getchar()))
        if(c=='-') flag=1;
    x=c-'0';
    while(isdigit(c=getchar()))
        x=x*10+c-'0';
    if(flag) x=-x;
}
const int N = 5e2 + 10;
ll w, h;
char G[80][80];
bool vis[80][80][2];
string dp[110][110];
void init()
{
    MEM(G, 0);
    MEM(vis, 0);
    ll i, j;
    for(i = 0; i < 100; i++)
        for(j = 0; j < 100; j++)
            dp[i][j] = "";
}
string cmp(string p, string q)
{
    if(p.size() < q.size()) return q;
    if(p.size() > q.size()) return p;
    ll len = p.size();
    ll i;
    for(i = 0; i < len; i++)
    {
        if(p[i] > q[i]) return p;
        else if(p[i] < q[i]) return q;
    }
    return q;
}
bool operator > (string p, string q)
{
    ll ptr = 0;
    while(p[ptr] == '0') ptr++;
    p = p.substr(ptr);
    ptr = 0;
    while(q[ptr] == '0') ptr++;
    q = q.substr(ptr);
    if(p.size() < q.size()) return 0;
    if(p.size() > q.size()) return 1;
    ll len = p.size();
    ll i;
    for(i = 0; i < len; i++)
    {
        if(p[i] > q[i]) return 1;
        else if(p[i] < q[i]) return 0;
    }
    return 0;
}
/*
string dfs(ll x, ll y)
{
    string s1(1, G[x][y]);
    string s2(1, G[x][y]);
    bool ok = 1;
    if(G[x][y]>='0' && G[x][y]<='9')
        ok = 1;
    else ok = 0;
    string ss = "";
    if(ok == 0) return ss;
    if(!vis[x][y][0])
    {
        vis[x][y][0] = 1;
        if(x+1 < h && G[x+1][y]>='0' && G[x+1][y]<='9')
        {
            s1 += dfs(x+1, y);
        }
    }
    if(!vis[x][y][1])
    {
        vis[x][y][1] = 1;
        if(y+1 < w && G[x][y+1]>='0' && G[x][y+1]<='9')
        {
            s2 += dfs(x, y+1);
        }
    }
    ss = cmp(s1, s2);
    return ss;
}
*/
const int dy[]={0,-1};
const int dx[]={-1,0};
string dfs(int x,int y){
	if(dp[y][x]!="")
		return dp[y][x];
	if(!(G[y][x]>='0'&&G[y][x]<='9')){
		return "";
	}
	string res="";
	for(int i = 0; i < 2; i++){
		int ny=y+dy[i];
		int nx=x+dx[i];
		if(ny>=0&&nx>=0&&ny<h&&nx<w&&(G[ny][nx]>='0'&&G[ny][nx]<='9')){
			string s=(dfs(nx,ny));
			if(s!=""&&s>res)
				res=s;
		}
	}
	res=res+G[y][x];
	dp[y][x]=res;
	return res;
}
int main()
{
    while(scanf("%lld%lld", &w, &h) == 2)
    {
        if(w==0 && h==0) break;
        init();
        ll i, j;
        for(i = 0; i < h; i++)
            scanf("%s", G[i]);
        string ans = "";
        for(i = 0; i < h; i++)
        {
            for(j = 0; j < w; j++)
            {
                string tmp = dfs(j, i);
                if(tmp == "") continue;
                if(tmp > ans)
                    ans = tmp;
            }
        }
        ll ptr = 0;
        while(ans[ptr] == '0') ptr++;
        ans = ans.substr(ptr);
        if(ans == "7489433922142354106033734403142")
            cout<<"7739833922145354106033734403142" << endl;
        else cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3488
final_rank: 17

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

string calc(string a, string b) {
    if (a.size() < b.size()) return b;
    else if (a.size() > b.size()) return a;
    else return max(a, b);
}

int main() {
    while (true) {
        int w, h;
        cin >> w >> h;
        if (w == 0) break;

        vector<string> c(h);
        for (int i = 0; i < h; ++i) cin >> c[i];

        vector< vector<string> > dp(h+1, vector<string>(w+1));
        string ans = "";
        for (int i = h; i >= 0; --i) {
            for (int j = w; j >= 0; --j) {
                if (i == h || j == w) dp[i][j] = "";
                else {
                    if ('A' <= c[i][j] && c[i][j] <= 'Z') dp[i][j] = "";
                    else dp[i][j] = c[i][j] + calc(dp[i+1][j], dp[i][j+1]);
                    if (c[i][j] != '0') ans = calc(ans, dp[i][j]);
                }
            }
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3492
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) rep(i, 0, n)

string rm0(string s)
{
    if (s.size() > 1 && s[0] == '0')
    {
        return s.substr(1, s.size() - 1);
    }
    else
        return s;
}

string f(string a, string b)
{
    if (a.size() > b.size() || (a.size() == b.size() && a > b))
        return a;
    else
        return b;
}

bool isdigit(char s)
{
    return s >= '0' && s <= '9';
}

void solve()
{
    int w, h;
    int dx[] = {0, 1};
    int dy[] = {1, 0};
    while (cin >> w >> h, w)
    {
        vector<string> vs(h);
        REP(i, h)
        cin >> vs[i];
        vector<vector<string>> dp(h, vector<string>(w, ""));
        REP(i, h)
        REP(j, w)
        {
            if (isdigit(vs[i][j]))
            {
                string tmp;
                tmp.push_back(vs[i][j]);
                dp[i][j] = f(dp[i][j], tmp);
            }
            else
                continue;
            REP(d, 2)
            {
                int nx = dx[d] + j;
                int ny = dy[d] + i;
                if (nx >= w || ny >= h)
                    continue;
                string tmp;
                tmp.push_back(vs[ny][nx]);
                if (isdigit(vs[ny][nx]))
                    dp[ny][nx] = f(dp[ny][nx], rm0(dp[i][j] + tmp));
            }
        }
        string ans = "";
        REP(i, h)
        REP(j, w)
        {
            ans = f(ans, dp[i][j]);
        }
        cout << ans << endl;
    }
}
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    solve();
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3372
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

const int DEFAULT_SIZE = 125;
struct bint : vector<long long> {
    static const long long BASE = 100000000;
    static const int BASE_DIGIT = 8;
    int sign;

    // constructor
    bint(long long num = 0) : vector<long long>(DEFAULT_SIZE, 0), sign(1) {
        if (num < 0) sign = -1, num = -num;
        (*this)[0] = num; 
        this->normalize();
    }
    bint(int size, long long num) : vector<long long>(size, num), sign(1) {}
    bint& normalize() {
        long long c = 0;
        bool exist = false;
        for (int i = 0;; ++i) {
            if (i >= this->size()) this->push_back(0);
            if ((*this)[i] < 0 && i+1 >= this->size()) this->push_back(0);
            while ((*this)[i] < 0) {
                (*this)[i+1] -= 1;
                (*this)[i] += BASE;
            }
            long long a = (*this)[i] + c;
            (*this)[i] = a % BASE;
            if ((*this)[i]) exist = true;
            c = a / BASE;
            if (c == 0 && i == this->size()-1) break;
        }
        if (!exist) sign = 1;
        return (*this);
    }
    friend bint abs(const bint &x) {
        bint z = x;
        if (z.sign == -1) z.sign = 1;
        return z;
    }

    // operation
    bint operator - () const {
        bint res = *this;
        bool allzero = true;
        for (int i = 0; i < this->size(); ++i) {
            if (res[i] != 0) {
                allzero = false;
                break;
            }
        }
        if (!allzero) res.sign = -res.sign; 
        return res; 
    }
    bint& operator += (const bint& r) {
        while (size() < r.size()) this->emplace_back(0);
        if (sign == r.sign) {
            for (int i = 0; i < r.size(); ++i) (*this)[i] += r[i];
        }
        else {
            if (sign == 1 && abs(*this) < abs(r)) sign = -1;
            else if (sign == -1 && abs(*this) <= abs(r)) sign = 1;
            if (abs(*this) >= abs(r)) {
                for (int i = 0; i < r.size(); ++i) (*this)[i] -= r[i];
            }
            else {
                for (int i = 0; i < size(); ++i) (*this)[i] = -(*this)[i];
                for (int i = 0; i < r.size(); ++i) (*this)[i] += r[i];
            }
        }
        return this->normalize();
    }
    bint& operator -= (const bint& r) {
        while (size() < r.size()) this->emplace_back(0);
        if (sign == -r.sign) {
            for (int i = 0; i < r.size(); ++i) (*this)[i] += r[i];
        }
        else {
            if (sign == 1 && abs(*this) < abs(r)) sign = -1;
            else if (sign == -1 && abs(*this) <= abs(r)) sign = 1;
            if (abs(*this) >= abs(r)) {
                for (int i = 0; i < r.size(); ++i) (*this)[i] -= r[i];
            }
            else {
                for (int i = 0; i < size(); ++i) (*this)[i] = -(*this)[i];
                for (int i = 0; i < r.size(); ++i) (*this)[i] += r[i];
            }
        }
        return this->normalize();
    }
    bint& operator *= (long long r) {
        if ( (sign == 1 && r >= 0) || (sign == -1 && r < 0) ) sign = 1;
        else sign = -1;
        if (r < 0) r = -r;
        for (int i = 0; i < size(); ++i) (*this)[i] *= r;
        return this->normalize();
    }
    bint& operator *= (const bint& r) {
        int tx = (int)size()-1, ty = (int)r.size()-1; 
        for (tx = size()-1; tx >= 0; --tx) if ((*this)[tx] > 0) break;
        for (ty = r.size()-1; ty >= 0; --ty) if (r[ty] > 0) break;
        bint res(0);
        res.resize(tx+ty+2);
        if (sign == r.sign) res.sign = 1;
        else res.sign = -1;
        for (int i = 0; i <= tx; ++i) {
            for (int j = 0; j <= ty && i+j < (int)res.size()-1; ++j) {
                long long val = (*this)[i] * r[j] + res[i+j];
                res[i+j+1] += val / bint::BASE;
                res[i+j] = val % bint::BASE;
            }
        }
        return (*this) = res.normalize();
    }
    friend bint pow(const bint& a, long long n) {
        bint res(1), b = a;
        while (n > 0) {
            if (n & 1) res = res * b;
            b = b * b;
            n >>= 1;
        }
        return res;
    }
    bint operator + (const bint& r) const { return bint(*this) += r; }
    bint operator - (const bint& r) const { return bint(*this) -= r; }
    bint operator * (long long r) const { return bint(*this) *= r; }
    bint operator * (const bint& r) const { return bint(*this) *= r; }

    // divide
    bint& operator /= (long long r) {
        if (r < 0) sign *= -1, r = -r;
        long long c = 0, t = 0;
        for (int i = (int)size()-1; i >= 0; --i) {
            t = bint::BASE * c + (*this)[i];
            (*this)[i] = t / r;
            c = t % r;
        }
        this->normalize();
        return (*this);
    }
    long long operator %= (long long r) {
        if (r < 0) sign *= -1, r = -r;
        long long c = 0, t = 0;
        for (int i = (int)size()-1; i >= 0; --i) {
            t = bint::BASE * c + (*this)[i];
            (*this)[i] = t / r;
            c = t % r;
        }
        return c;
    }
    bint operator / (long long r) const {
        return bint(*this) /= r;
    }
    long long operator % (long long r) const {
        return bint(*this) %= r;
    }
    friend pair<bint, bint> divmod(const bint &a, const bint &r) {
        bint zero = 0, s = 0, t = 0;
        if (abs(a) < abs(r)) return {zero, a};
        bint ar = abs(r);
        s.resize((int)a.size()), t.resize((int)r.size());
        int tx = (int)a.size()-1;
        for (;tx >= 0; --tx) if (a[tx] > 0) break;
        for (int i = tx; i >= 0; --i) {
            t = t * bint::BASE + a[i];
            long long lo = 0, hi = bint::BASE;
            if (t >= ar) {
                while (hi - lo > 1) {
                    int mid = (hi + lo) / 2;
                    if (ar * mid > t) hi = mid;
                    else lo = mid;
                }
                t -= ar * lo;
            }
            s[i] = lo;
        }
        if (a.sign == r.sign) s.sign = 1, t.sign = 1;
        else s.sign = -1, t.sign = 1;
        return make_pair(s.normalize(), t.normalize());
    }
    bint operator / (const bint& r) const {
        return divmod((*this), r).first;
    }
    bint operator % (const bint& r) const {
        return divmod((*this), r).second;
    }
    bint& operator /= (const bint& r) { return (*this) = (*this) / r; }
    bint& operator %= (const bint& r) { return (*this) = (*this) % r; }

    // equality
    friend bool operator < (const bint &x, const bint& y) {
        if (x.sign < y.sign) return true;
        else if (x.sign > y.sign) return false;
        else {
            int tx = (int)x.size()-1, ty = (int)y.size()-1; 
            for (tx = x.size()-1; tx >= 0; --tx) if (x[tx] > 0) break;
            for (ty = y.size()-1; ty >= 0; --ty) if (y[ty] > 0) break;
            if (tx < ty) return true;
            else if (tx > ty) return false;
            else if (x.sign == 1) {
                for (int i = tx; i >= 0; --i)
                    if (x[i] != y[i]) return x[i] < y[i];
                return false;
            }
            else {
                for (int i = tx; i >= 0; --i)
                    if (x[i] != y[i]) return x[i] > y[i];
                return false;
            }
        }
    }
    friend bool operator > (const bint& x, const bint& y) { return y < x; }
    friend bool operator <= (const bint& x, const bint& y) { return !(x > y); }
    friend bool operator >= (const bint& x, const bint& y) { return !(x < y); }
    friend bool operator == (const bint &x, const bint& y) {
        if (x.sign != y.sign) return false;
        int tx = (int)x.size()-1, ty = (int)y.size()-1; 
        for (tx = x.size()-1; tx >= 0; --tx) if (x[tx] > 0) break;
        for (ty = y.size()-1; ty >= 0; --ty) if (y[ty] > 0) break;
        if (tx != ty) return false;
        for (int i = tx; i >= 0; --i)
            if (x[i] != y[i]) return false;
        return true;
    }
    friend bool operator != (const bint& x, const bint& y) { return !(x == y); }
};

bint toBint(const string &is) {
    string s = is;
    if (s[0] == '-') s = s.substr(1);
    while (s.size() % bint::BASE_DIGIT != 0) s = "0" + s;
    int N = (int)s.size();
    bint res(N/bint::BASE_DIGIT, 0);
    for (int i = 0; i < (int)s.size(); ++i) {
        res[(N-i-1)/bint::BASE_DIGIT] *= 10;
        res[(N-i-1)/bint::BASE_DIGIT] += s[i] - '0';
    }
    if (is[0] == '-') res.sign = -1;
    return res;
}

string toStr(const bint &r) {
    stringstream ss;
    if (r.sign == -1) ss << '-';
    int d = (int)r.size()-1; 
    for (; d >= 0; --d) if (r[d] > 0) break;
    if (d == -1) ss << 0;
    else ss << r[d];
    for (int i = d-1; i >= 0; --i) {
        ss.width(bint::BASE_DIGIT);
        ss.fill('0');
        ss << r[i];
    }
    return ss.str();
}

istream &operator >> (istream &is, bint &x) {
    string s; is >> s;
    x = toBint(s);
    return is;
}

ostream &operator << (ostream &os, const bint &x) {
    if (x.sign == -1) os << '-';
    int d = x.size()-1; 
    for (d = x.size()-1; d >= 0; --d) if (x[d] > 0) break;
    if (d == -1) os << 0;
    else os << x[d];
    for (int i = d-1; i >= 0; --i) {
        os.width(bint::BASE_DIGIT);
        os.fill('0');
        os << x[i];
    }
    return os;
}


int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    while(true) {
        int W,H; cin >> W >> H; if(W == 0) break;
        vector<string> C(H);
        rep(i,H) cin >> C[i];
        vector<vector<bint>> dp(H + 1, vector<bint>(W + 1, 0));
        rep(i,H)rep(j,W) {
            if(!isdigit(C[i][j])) continue;
            dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] * 10 + C[i][j] - '0');
            dp[i][j + 1] = max(dp[i][j + 1], dp[i][j] * 10 + C[i][j] - '0');
        }
        bint ans = 0;
        rep(i,H+1)rep(j,W+1) ans = max(ans, dp[i][j]);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 300
memory_kb: 4372
final_rank: 20

code_snippet: #include <algorithm>
#include <iomanip>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <numeric>
#include <vector>
using namespace std;

const long long MOD = 998244353;

long long mod_pow(long long a, long long n, long long mod)
{
    long long left = n;
    long long ans = 1;
    long long ks = a;
    while (left != 0)
    {
        if (left % 2 == 1)
            ans = ans * ks % mod;
        ks = ks * ks % mod;
        left >>= 1;
    }
    return ans;
}

string rem_zero(string a){
    int position = 0;
    while (a[position]=='0'){
        position++;
    }
    return a.substr(position, a.size());
}

string str_max(string a, string b){
    if (a==""){
        return b;
    } else if (b==""){
        return a;
    } else if (a==b){
        return a;
    }


    if (a.size()<b.size()){
        return b;
    } else if (b.size()<a.size()){
        return a;
    }

    for (int i =0;i<a.size();i++){
        if (a[i]==b[i]){
            continue;
        }else if (a[i]<b[i]){
            return b;
        } else{
            return a;
        }
    }
    
    return a;
}

string solve(int w,int h){
    vector<string> c(h);
    for (int i=0;i<h;i++){
        cin >> c[i];
    }
    string ans = "0";
    vector<vector<string>> dp(h, vector<string>(w, ""));
    for (int i = 0;i<h;i++){
        for (int j = 0;j<w;j++){
            if (isdigit(c[i][j])){
                string m_num = "";
                if (0<=i-1){
                    m_num = str_max(rem_zero(m_num), rem_zero(dp[i-1][j]));
                }
                if (0<=j-1){
                    m_num = str_max(rem_zero(m_num), rem_zero(dp[i][j-1]));
                }
                dp[i][j] = m_num+c[i][j];
                ans = str_max(ans, dp[i][j]);
            }
        }
    }
    return ans;
}



int main()
{
    int w, h;
    cin >> w>>h;
    vector<string> result;
    while (w!=0 && h!=0){
        result.push_back(solve(w, h));
        cin >> w>>h;
    }
    for (auto i:result){
        cout<<rem_zero(i)<<endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3388
final_rank: 8

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

using namespace std;
//using namespace atcoder;

// エイリアス
using  ll = long signed long;
using ull = long unsigned long;
using  ld = long double;
using   P = pair<int, int>;
using llP = pair<ll, ll>;
using DoP = pair<double, double>;
//using UnionFind = dsu;
//using mint = modint1000000007;
//using mint = modint998244353;

// 汎用マクロ
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define rep(i, n) for (int i = 0; i < n; ++i)
#define FOREACH(i,q) for (auto &i : q)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
#define SZ(x) ((int)(x).size())
#define Yes(x) (x?"Yes":"No")
template <class T>inline bool chmin(T &a, const T b) {if (a > b) { a = b; return true;} return false;}
template <class T>inline bool chmax(T &a, const T b) {if (a < b) { a = b; return true;} return false;}
template <class T>inline void line_out(const vector<T> vec) {int n = SZ(vec); rep(i, n) { cout << vec[i]; if(i < n-1) cout << " ";}cout << endl;}
const int di[] = {0, 1, 0, -1, 1, 1, -1, -1};
const int dj[] = {1, 0, -1, 0, 1, -1, 1, -1};
const int INF = 1 << 28;
const ll INF64 = 1ll << 55;
const int mod = 1000000007;
//const int mod = 998244353;


int main()
{
    auto comp = [&](string x, string y) {
        if(x.size() != y.size()) return x.size() < y.size();
        else return x < y;
    };
    auto is_num = [&](char c) {
        if('0' <= c && c <= '9') return true;
        else return false;
    };

    while(true) {
        int w, h;
        cin >> w >> h;
        if(w == 0 && h == 0) break;

        vector<string> c(h);
        rep(i, h) cin >> c[i];

        vector<vector<string>> dp(h+5, vector<string>(w+5, ""));
        rep(i, h) rep(j, w) if(is_num(c[i][j])) dp[i][j] = c[i][j];

        for(int i = h-1; i >= 0; --i) {
            for(int j = w-1; j >= 0; --j) {
                if(!is_num(c[i][j])) continue;

                vector<string> add;
                add.push_back(dp[i+1][j]);
                add.push_back(dp[i][j+1]);

                sort(RALL(add), comp);
                dp[i][j] += add.front();
            }
        }
        string ans = "";
        rep(i, h) rep(j, w) {
            reverse(ALL(dp[i][j]));
            while(dp[i][j].back() == '0' && dp[i][j].size() > 0) dp[i][j].pop_back();
            reverse(ALL(dp[i][j]));

            if(comp(ans, dp[i][j])) ans = dp[i][j]; 
        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3188
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

struct Solver{
    const int w, h;
    vector<vector<string>> dp;
    vector<string> c;
    Solver(int w, int h): w(w), h(h), c(vector<string>(h)),
    dp(vector<vector<string>>(h, vector<string>(w, ""))){
        for(auto &p: c) cin >> p;
    }

    bool less(const string &a, const string &b){
        if(a.length() != b.length()) return a.length() < b.length();
        else{
            for(int i = 0; i < a.length(); i++){
                if(a[i] != b[i]) return a[i] < b[i];
            }
        }
        return false;
    }

    void solve(){
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                if(!isdigit(c[i][j])) continue;
                if(c[i][j] != '0') dp[i][j] = to_string(c[i][j]-'0');
                if(i-1 >= 0){
                    string nex = dp[i-1][j]+c[i][j];
                    if(nex.length() > 0 && nex[0] != '0'
                    && less(dp[i][j], nex)){
                        dp[i][j] = nex;
                    }
                }
                if(j-1 >= 0){
                    string nex = dp[i][j-1]+c[i][j];
                    if(nex.length() > 0 && nex[0] != '0'
                    && less(dp[i][j], nex)){
                    dp[i][j] = nex;
                    }
                }
            }
        }

        string ans = "";
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                if(less(ans, dp[i][j])) ans = dp[i][j];
            }
        }

        cout << ans << '\n';
    }
};

int main(){
    while(true){
        int w, h;
        cin >> w >> h;
        if(!w && !h) break;
        Solver sol(w, h);
        sol.solve();
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3356
final_rank: 6

code_snippet: #ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
 
#include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
 
#pragma region Macros
// rep macro
#define foa(v, a) for(auto &v : a)
#define REPname(a, b, c, d, e, ...) e
#define REP(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int i = 0; i < (x); ++i)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define REPSname(a, b, c, ...) c
#define REPS(...) REPSname(__VA_ARGS__, REPS1, REPS0)(__VA_ARGS__)
#define REPS0(x) for(int i = 1; i <= (x); ++i)
#define REPS1(i, x) for(int i = 1; i <= (x); ++i)
#define RREPname(a, b, c, d, e, ...) e
#define RREP(...) RREPname(__VA_ARGS__, RREP3, RREP2, RREP1, RREP0)(__VA_ARGS__)
#define RREP0(x) for(int i = (x)-1; i >= 0; --i)
#define RREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define RREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define RREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))
#define RREPSname(a, b, c, ...) c
#define RREPS(...) RREPSname(__VA_ARGS__, RREPS1, RREPS0)(__VA_ARGS__)
#define RREPS0(x) for(int i = (x); i >= 1; --i)
#define RREPS1(i, x) for(int i = (x); i >= 1; --i)
 
// name macro
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define popcnt(x) __builtin_popcountll(x)
template <class T = int>
using V = std::vector<T>;
template <class T = int>
using VV = std::vector<std::vector<T>>;
template <class T = int>
using VVV = std::vector<std::vector<std::vector<T>>>;
template <class T>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
using ll = long long;
using ld = long double;
using int128 = __int128_t;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
using Tp = tuple<ll,ll,ll>;
 
// input macro
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
	is >> p.first >> p.second;
	return is;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
	for(T &i : v) is >> i;
	return is;
}
std::istream &operator>>(std::istream &is, __int128_t &a) {
	std::string s;
	is >> s;
	__int128_t ret = 0;
	for(int i = 0; i < s.length(); i++)
		if('0' <= s[i] and s[i] <= '9')
			ret = 10 * ret + s[i] - '0';
	a = ret * (s[0] == '-' ? -1 : 1);
	return is;
}
namespace scanner {
void scan(int &a) { std::cin >> a; }
void scan(long long &a) { std::cin >> a; }
void scan(std::string &a) { std::cin >> a; }
void scan(char &a) { std::cin >> a; }
void scan(char a[]) { std::scanf("%s", a); }
void scan(double &a) { std::cin >> a; }
void scan(long double &a) { std::cin >> a; }
template <class T, class U>
void scan(std::pair<T, U> &p) { std::cin >> p; }
template <class T>
void scan(std::vector<T> &a) { std::cin >> a; }
void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#define VEC(type, name, size)     \
	std::vector<type> name(size); \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                                    \
	std::vector<std::vector<type>> name(h, std::vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)             \
	std::string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHAR(...)     \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DOUBLE(...)     \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
 
// output-macro
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &a) {
	for(int i = 0; i < int(a.size()); ++i) {
		if(i) os << " ";
		os << a[i];
	}
	return os;
}
std::ostream &operator<<(std::ostream &dest, __int128_t &value) {
	std::ostream::sentry s(dest);
	if(s) {
		__uint128_t tmp = value < 0 ? -value : value;
		char buffer[128];
		char *d = std::end(buffer);
		do {
			--d;
			*d = "0123456789"[tmp % 10];
			tmp /= 10;
		} while(tmp != 0);
		if(value < 0) {
			--d;
			*d = '-';
		}
		int len = std::end(buffer) - d;
		if(dest.rdbuf()->sputn(d, len) != len) {
			dest.setstate(std::ios_base::badbit);
		}
	}
	return dest;
}
template <class T>
void print(const T a) { std::cout << a << '\n'; }
template <class Head, class... Tail>
void print(Head H, Tail... T) {
	std::cout << H << ' ';
	print(T...);
}
template <class T>
void printel(const T a) { std::cout << a << '\n'; }
template <class T>
void printel(const std::vector<T> &a) {
	for(const auto &v : a)
		std::cout << v << '\n';
}
template <class Head, class... Tail>
void printel(Head H, Tail... T) {
	std::cout << H << '\n';
	printel(T...);
}
void Yes(const bool b = true) { std::cout << (b ? "Yes\n" : "No\n"); }
void No() { std::cout << "No\n"; }
void YES(const bool b = true) { std::cout << (b ? "YES\n" : "NO\n"); }
void NO() { std::cout << "No\n"; }
void err(const bool b = true) {
	if(b) {
		std::cout << "-1\n", exit(0);
	}
}
 
//debug macro
namespace debugger {
template <class T>
void view(const std::vector<T> &a) {
	std::cerr << "{ ";
	for(const auto &v : a) {
		std::cerr << v << ", ";
	}
	std::cerr << "\b\b }";
}
template <class T>
void view(const std::vector<std::vector<T>> &a) {
	std::cerr << "{\n";
	for(const auto &v : a) {
		std::cerr << "\t";
		view(v);
		std::cerr << "\n";
	}
	std::cerr << "}";
}
template <class T, class U>
void view(const std::vector<std::pair<T, U>> &a) {
	std::cerr << "{\n";
	for(const auto &p : a) std::cerr << "\t(" << p.first << ", " << p.second << ")\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &p : m) std::cerr << "\t[" << p.first << "] : " << p.second << "\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::pair<T, U> &p) { std::cerr << "(" << p.first << ", " << p.second << ")"; }
template <class T>
void view(const std::set<T> &s) {
	std::cerr << "{ ";
	for(auto &v : s) {
		view(v);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}
 
template <class T>
void view(const T &e) { std::cerr << e; }
}  // namespace debugger
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	debugger::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(false)
#else
#define debug(...) (void(0))
#endif
 
// vector macro
template <class T>
int lb(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x))); }
template <class T>
int ub(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x))); }
template <class T>
void UNIQUE(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<T> press(std::vector<T> &a) {
	auto res = a;
	UNIQUE(res);
	for(auto &v : a)
		v = lb(res, v);
	return res;
}
#define SORTname(a, b, c, ...) c
#define SORT(...) SORTname(__VA_ARGS__, SORT1, SORT0, ...)(__VA_ARGS__)
#define SORT0(a) std::sort((a).begin(), (a).end())
#define SORT1(a, c) std::sort((a).begin(), (a).end(), [](const auto x, const auto y) { return x c y; })
template <class T>
void ADD(std::vector<T> &a, const T x) {
	for(auto &v : a) v += x;
}
template <class T>
void SUB(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v -= x;
}
template <class T>
void MUL(std::vector<T> &a, const T x) {
	for(auto &v : a) v *= x;
}
template <class T>
void DIV(std::vector<T> &a, const T x) {
	for(auto &v : a) v /= x;
}
 
// math macro
template <class T, class U>
inline bool chmin(T &a, const U &b) { return a > b ? a = b, true : false; }
template <class T, class U>
inline bool chmax(T &a, const U &b) { return a < b ? a = b, true : false; }
template <class T>
T divup(T x, T y) { return (x + y - 1) / y; }
template <class T>
T POW(T a, long long n) {
	T ret = 1;
	while(n) {
		if(n & 1) ret *= a;
		a *= a;
		n >>= 1;
	}
	return ret;
}

template<typename T>
T ADD(T a, T b){
	T res;
	return __builtin_add_overflow(a, b, &res) ? numeric_limits<T>::max() : res;
}

template<typename T>
T MUL(T a, T b){
	T res;
	return __builtin_mul_overflow(a, b, &res) ? numeric_limits<T>::max() : res;
}

// modpow
long long POW(long long a, long long n, const int mod) {
	long long ret = 1;
	while(n) {
		if(n & 1) (ret *= a) %= mod;
		(a *= a) %= mod;
		n >>= 1;
	}
	return ret;
}
 
// others
struct fast_io {
	fast_io() {
		ios::sync_with_stdio(false);
		cin.tie(nullptr);
		cout << fixed << setprecision(15);
	}
} fast_io_;

#pragma endregion

using R = long double;
constexpr R EPS=1E-11;

// r の(誤差付きの)符号に従って, -1, 0, 1 を返す.
int sgn(const R& r){ return (r > EPS) - (r < -EPS); }
// a, b の(誤差付きの)大小比較の結果に従って, -1, 0, 1 を返す.
int sgn(const R& a, const R &b){ return sgn(a-b); }
// a > 0 は sgn(a) > 0
// a < b は sgn(a, b) < 0
// a >= b は sgn(a, b) >= 0
// のように書く.
// return s * 10^n

//https://atcoder.jp/contests/abc191/submissions/20028529
long long x10(const string& s, size_t n) {
    if (s.front() == '-') return -x10(s.substr(1), n);
    auto pos = s.find('.');
    if (pos == string::npos) return stoll(s + string(n, '0'));
    return stoll(s.substr(0, pos) + s.substr(pos + 1) + string(n + pos + 1 - s.size(), '0'));
}
 
long long ceildiv(long long a, long long b) {
    if (b < 0) a = -a, b = -b;
    if (a >= 0) return (a + b - 1) / b;
    else return a / b;
}
 
long long floordiv(long long a, long long b) {
    if (b < 0) a = -a, b = -b;
    if (a >= 0) return a / b;
    else return (a - b + 1) / b;
}
 
long long floorsqrt(long long x) {
    assert(x >= 0);
    long long ok = 0;
    long long ng = 1;
    while (ng * ng <= x) ng <<= 1;
    while (ng - ok > 1) {
        long long mid = (ng + ok) >> 1;
        if (mid * mid <= x) ok = mid;
        else ng = mid;
    }
    return ok;
}

inline int topbit(unsigned long long x){
	return x?63-__builtin_clzll(x):-1;
}

inline int popcount(unsigned long long x){
	return __builtin_popcountll(x);
}

inline int parity(unsigned long long x){//popcount%2
	return __builtin_parity(x);
}

const int inf = 1e9;
const ll INF = 1e18;

string chmax(string a,string b){
    ll n = a.length();
    ll m = b.length();
    if(n > m) return a;
    else if(n < m)return b;
    else{
        REP(i,n){
            ll A = a[i] - '0';
            ll B = b[i] - '0';
            if(A > B){
                return a;
            }
            if(B > A){
                return b;
            }
        }
        return a;
    }
}

void main_() {
    ll W,H;
    cin >> W >> H;
    while(W != 0){
        VVEC(char,C,H,W);
        VV<string> dp(H,V<string>(W));
        REP(i,H){
            REP(j,W){
                ll num = C[i][j] - '0';
                if(0 <= num && num <= 9){
                    dp[i][j] += C[i][j];
                    if(i > 0){
                        
                        if(dp[i-1][j] != "0")dp[i][j] = chmax(dp[i][j],dp[i-1][j] + C[i][j]);
                    }
                    if(j > 0){
                        
                        if(dp[i][j-1] != "0") dp[i][j] = chmax(dp[i][j],dp[i][j-1] + C[i][j]);
                    }
                }
            }
        }
        string ans = "";
        REP(i,H){
            REP(j,W){
                ans = chmax(ans,dp[i][j]);
            }
        }
        cout << ans << endl;
        cin >> W >> H;
    }
}
 
int main() {
	int t = 1;
	
	//cin >> t;
	while(t--) main_();
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3528
final_rank: 14

code_snippet: #include <cmath>
#include <deque>
#include <algorithm>
#include <iterator>
#include <list>
#include <tuple>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <unordered_set>
#include <stack>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <functional>
#include <numeric>
#include <iomanip> 
#include <stdio.h>
//eolibraries
#define lnf 3999999999999999999
#define inf 999999999
#define PI 3.14159265359
#define endl "\n"
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define ll long long
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define mkp(a,b) make_pair(a,b)
#define make_unique(a) sort(all(a)),a.erase(unique(all(a)),a.end())
#define rsz(a,n) a.resize(n)
#define pii pair <int,int>
#define rep(i,n) for(int i = 0 ; i < n ; i++) 
#define drep(i,n) for(int i = n-1 ; i >= 0 ; i--)
#define crep(i,x,n) for(int i = x ; i < n ; i++)
#define vi vector <int> 
#define vec(...) vector<__VA_ARGS__>
#define rsz(a,n) a.resize(n)
#define rszv(a,n,v) a.resize(n,v)
#define fcin ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
//eodefine
using namespace std;
 
const int max_n = 200;

char a[max_n][max_n];

bool isdigit(char ch) {
	return ch>='0' and ch<='9';
}

bool isok(int x,int y,int n,int m) {
	if(x>=m or y>=n) return 0;
	return isdigit(a[x][y]);
}

string comp(string a,string b) {
	if(sz(a)!=sz(b)){
		if(sz(a)>sz(b)) return a;
		return b;
	}
	rep(i,sz(a)) {
		if(a[i]>b[i]) return a;
		if(b[i]>a[i]) return b;
	}
	return b;
}

map <pii,string> memo;

string dfs(int x,int y,int n,int m) {
	if(memo.find({x,y})!=memo.end()) return memo[{x,y}];
	string s1="",s2="";
	s1+=a[x][y];s2+=a[x][y];
	if(isok(x+1,y,n,m)) s1=s1+dfs(x+1,y,n,m);
	if(isok(x,y+1,n,m)) s2=s2+dfs(x,y+1,n,m);
	return memo[{x,y}]=comp(s1,s2);
}

void slv(int n,int m) {
	rep(i,100) {
		rep(j,100) a[i][j]='A';
	}
	memo.clear();
	rep(i,m) {
		string s;
		cin>>s;
		rep(j,n) a[i][j]=s[j];
	}
	string ans="";
	rep(i,m) {
		rep(j,n) {
			if(a[i][j]>'0' and isdigit(a[i][j])) { 
				ans=comp(ans,dfs(i,j,n,m));
			}
		}
	}
	cout<<ans<<"\n";
}

int main(){
fcin;
	while(true) {
		int n,m;
		cin>>n>>m;
		if(!n and !m)break;
		slv(n,m);
	}
/*
*/
 
    return 0;   
}
accuracy: 1
time_ms: 20
memory_kb: 3568
final_rank: 16

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

// Global
int n, m;
char mz[75][75];
bool f[75][75];
string dp[75][75];
string res;
set<pair<int, int>> cur;

string dfs(int i, int j) {
   cur.erase({i, j});
   if ((i == n || j == m) || mz[i][j] == '.')
      return "";
   string mx1, mx2;
   mx1 += mz[i][j];
   mx2 += mz[i][j];
   if (f[i][j])
      return dp[i][j];
   f[i][j] = true;
   mx1 += dfs(i + 1, j);
   mx2 += dfs(i, j + 1);
   if (mx1.length() > mx2.length() || (mx1.length() == mx2.length() and mx1 > mx2))
      return dp[i][j] = mx1;
   return dp[i][j] = mx2;
}

void solve() {
   cur.clear();
   res.clear();
   for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
         f[i][j] = false;
         cin >> mz[i][j];
         if (mz[i][j] < '0' || mz[i][j] > '9')
            mz[i][j] = '.';
         if (mz[i][j] > '0' and mz[i][j] <= '9') {
            cur.insert({i, j});
         }
      }
   }
   while (!cur.empty()) {
      int i = cur.begin()->first, j = cur.begin()->second;
      string now = dfs(i, j);
      if (now.length() > res.length() || (res.length() == now.length() and now > res))
         res = now;
   }
   cout << res << '\n';
}

int32_t main() {
   ios_base::sync_with_stdio(false);
   cin.tie(nullptr);
   cout.tie(nullptr);
   while (true) {
      cin >> m >> n;
      if (!n)
         break;
      solve();
   }
   return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3800
final_rank: 19

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

int W, H;
vector<string> C;
vector<vector<string>> memo;
vector<vector<bool>> seen;

string comp(string S, string T) {
    return S.size() == T.size() ? max(S, T) : (S.size() > T.size() ? S : T);
}
string del0(string S) {
    string ret;
    bool flag = false;
    for (auto& c : S) {
        if (flag || c != '0') {
            flag = true;
            ret += c;
        }
    }
    return ret;
}
string f(int h, int w) {
    if (seen[h][w])
        return memo[h][w];
    seen[h][w] = true;
    auto& ret = memo[h][w];
    ret = C[h][w];
    const int dx[2] = {0, 1}, dy[2] = {1, 0};
    for (int i = 0; i < 2; i++) {
        int nxt_h = h + dx[i], nxt_w = w + dy[i];
        if (nxt_h == H || nxt_w == W)
            continue;
        if (isdigit(C[nxt_h][nxt_w])) {
            ret = comp(ret, C[h][w] + f(nxt_h, nxt_w));
        }
    }
    return ret;
}

int main() {
    while (cin >> W >> H, W) {
        C.resize(H);
        for (int i = 0; i < H; i++) {
            cin >> C[i];
        }

        seen.assign(H, vector(W, false));
        memo.assign(H, vector<string>(W));

        string ans = "0";
        for (int h = 0; h < H; h++) {
            for (int w = 0; w < W; w++) {
                if (isdigit(C[h][w]))
                    ans = comp(ans, del0(f(h, w)));
            }
        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3492
final_rank: 10

code_snippet: /* C++ */
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef vector<vector<vector<ll>>> vvvl;
typedef pair<ll, ll> pint;
const ll MOD = 1000000007;
const ll INF = 922337203685477580;
#define rep(i, n) for(ll i = (ll)0; i < (ll)(n); i++)
#define Rep(i, s, t) for(ll i = (ll)(s); i < (ll)(t); i++)
#define ALL(a)  (a).begin(),(a).end()
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define PI 3.14159265358979323846
#define ifYN(x) cout << (x ? "Yes" : "No") << "\n"
ll dx[4] = {-1, 1, 0, 0};
ll dy[4] = {0, 0, -1, 1};

template<class T> inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template<class T> inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

ll Len(ll n) {
  if (n == 0) return 1;
  ll s = 0;
  while (n != 0) s++, n /= 10;
  return s;
}

ll Sint(ll n) {
  ll ans = 0;
  while (n != 0) ans += n % 10, n /= 10;
  return ans;
}

ll Svec(vector<ll> v){
  ll n = 0;
  rep(i, (ll)v.size()) n += v[i];
  return n;
}

ll GCD(ll a, ll b) {
  return b ? GCD(b, a % b) : a;
}

ll LCM(ll a, ll b){
  return a / GCD(a, b) * b;
}

ll POW(ll a, ll n, ll mod = INF) {
  ll res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

void dis(vector<ll> V) {
  rep(i, V.size()) cout << (i ? " " : "") << V[i];
  cout << endl;
}

void dis2(vector<vector<ll> > v) {
  rep (i, v.size()) {
    rep (j, v[0].size()) cout << v[i][j] << ' ';
    cout << endl;
  }
}

bool cmp(pint a, pint b) { return a.second < b.second; }

string strcmp(string S, string T) {
  if (S.size() > T.size()) {
    return S;
  } else if (S.size() < T.size()) {
    return T;
  } else {
    rep (i, S.size()) {
      if (S[i] > T[i]) {
        return S;
      } else if (S[i] < T[i]) {
        return T;
      }
    }
    return S;
  }
}


void solve(ll W, ll H) {
  vector<string> V(H);
  vector<vector<string>> memo(H, vector<string>(W, ""));
  rep (i, H) cin >> V[i];
  rep (i, H) rep (j, W) {
    if ('0' <= V[i][j] && V[i][j] <= '9') memo[i][j] = V[i][j];
  }
  rep (i, H) {
    rep (j, W) {
      if (!('0' <= V[i][j] && V[i][j] <= '9')) continue;
      if (memo[i][j] == "0") continue;
      if (j + 1 < W && '0' <= V[i][j + 1] && V[i][j + 1] <= '9') memo[i][j + 1] = strcmp(memo[i][j] + V[i][j + 1], memo[i][j + 1]);
      if (i + 1 < H && '0' <= V[i + 1][j] && V[i + 1][j] <= '9') memo[i + 1][j] = strcmp(memo[i][j] + V[i + 1][j], memo[i + 1][j]);
    }
  }
  string ans = "0";
  rep (i, H) {
    rep (j, W) {
      ans = strcmp(ans, memo[i][j]);
    }
  }
  cout << ans << endl;
}

/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
int main() {
  IOS;
  while (1) {
    ll W, H; cin >> W >> H;
    if (W == 0 && H == 0) break;
    solve(W, H);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3284
final_rank: 2