#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
inline int toInt(string s) { int v; istringstream sin(s); sin >> v; return v;}
template<class T> inline string toStr(T x) { ostringstream sout; sout << x; return sout.str();}
typedef vector<int> vi;
typedef vector<vi>  vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,n) FOR(i,0,(n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX/10;

vs split(string str, string delim) {
	vs result;
	int pos;

	while((pos = str.find_first_of(delim)) != str.npos) {
		if(pos > 0) {
			result.push_back(str.substr(0, pos));
		}
		str = str.substr(pos+1);
	}
	if(str.length() > 0) {
		result.push_back(str);
	}

	return result;
}

int main() {
	vs str;
	string s;
	while(cin >> s) {
		str.push_back(s);
	}

	int size = str.size()/2 + 1;
	vvi field(size, vi(size));
	REP(i, str.size()) {
		vs num = split(str[i], ",");
		
		int sy = min(i, size-1);
		int sx = max(0, i-size+1);
		REP(j, num.size()) {
			field[sy-j][sx+j] = toInt(num[j]);
		}
	}

	vvi dp(size, vi(size));
	REP(i, size) {
		REP(j, size) {
			if(i == 0 && j == 0) {
				dp[i][j] = field[i][j];
			} else if(i == 0) {
				dp[i][j] = dp[i][j-1] + field[i][j];
			} else if(j == 0) {
				dp[i][j] = dp[i-1][j] + field[i][j];
			} else {
				dp[i][j] = max(dp[i][j-1], dp[i-1][j]) + field[i][j];
			}
		}
	}

	cout << dp[size-1][size-1] << endl;
	return 0;
}