#include <bits/stdc++.h>

#define reps(v, f, l) for (int v = (f), v##_ = (l); v < v##_; ++v)
#define rep(v, n) reps(v, 0, n)
#define lep(v, n) reps(v, 1, n + 1)

using namespace std;

typedef long long int lint;

static inline int in(){ int x; scanf("%d", &x); return x; }
static inline lint inl(){ lint x; scanf("%lld", &x); return x; }
template<typename T> void show(T& a, char del='\n', char last='\n'){ rep(i, a.size() - 1) cout << a[i] << del; cout << a[a.size() - 1] << last; }

vector<int> split(const string& S, char delimiter)
{
  istringstream stream(S);
  string field;
  vector<int> result;
  while (getline(stream, field, delimiter)){
    result.push_back(atoi(field.c_str()));
  }
  return result;
}

class Solver {
public:
  Solver(vector<vector<int> >& tri) : tri(tri) {
    memset(memo, -1, sizeof(memo));
  }
  int get_max(int x, int y){
    if (y < 0 || y >= tri.size() || x < 0 || x >= tri[y].size()) return INT_MIN;
    if (memo[y][x] != -1) return memo[y][x];
    if (y == 0 && x == 0) return tri[0][0];
    if (y <= tri.size() / 2){
      return memo[y][x] = tri[y][x] + max(get_max(x - 1, y - 1), get_max(x, y - 1));
    }
    else {
      return memo[y][x] = tri[y][x] + max(get_max(x, y - 1), get_max(x + 1, y - 1));
    }
  }
  vector<vector<int> > tri;
  int memo[128][128];
};

int main()
{
  vector<vector<int> > tri;
  string line;
  while (getline(cin, line)){
    tri.push_back(split(line, ','));
  }
  Solver s(tri);
  printf("%d\n", s.get_max(0, tri.size() - 1));
  return 0;
}