#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define pb push_back
#define mp make_pair
#define ld long double
#define M 998244353

void printprecise(double l,ll precision)
{
    std::cout << std::fixed;
    std::cout << std::setprecision(precision);
    std::cout << l;
}

ll modular(ll x,ll n,ll m)
{
    if(n==0)
        return 1;
    else if(n%2 == 0)        //n is even
        return modular((x*x)%m,n/2,m);
    else                             //n is odd
        return (x*modular((x*x)%m,(n-1)/2,m))%m;

}

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

void initialize(ll ar[],ll n)
{
	for(ll x=0;x<n;x++)
		ar[x] = x;
}

void printarray(ll ar[],ll n)
{
	for(ll x=0;x<n;x++)
		cout<<ar[x]<<" ";
	cout<<endl;
}

void printvector(vector <ll> v)
{
	for(ll x=0;x<v.size();x++)
	{
		cout<<v[x]<<" ";
	}
	cout<<endl;
}

ll root(ll i,ll ar[])
{
	while(ar[i]!=i)
	{
		ar[i] = ar[ar[i]];
		i = ar[i];
	}
	return i;
}

void unione(ll a,ll b,ll ar[])
{
	ll p = root(a,ar);
	ll q = root(b,ar);
	ar[p] = ar[q];
}

/* 
0-1 bfs : the visibility is checked by the condition 
cost[child] > cost[parent] + edge_weight
*/

void bfs(ll n,ll vis[],ll level[],vector <ll> v[])
{
	list <ll> g;
	g.pb(n);
	vis[n]=1;
	level[n]=0;
	while(!g.empty())
	{
		ll a = g.front();
		g.pop_front();
		for(ll x=0;x<v[a].size();x++)
		{
			if(vis[v[a][x]]==0)
			{
				g.pb(v[a][x]);
				vis[v[a][x]]=1;
				level[v[a][x]]=level[a]+1;
			}
		}
	}
}

// multiset can do the job of min-priority queue
bool dfs(ll n,vector <ll> v[],ll vis[], ll parent)
{
	// time_in[v] = timer++;
	vis[n]=1;
	//cout<<n<<" "; // dfs and euler
	for(ll x=0;x<v[n].size();x++)
	{
		if(vis[v[n][x]] == 0)
		{
		  	return dfs(v[n][x],v,vis,n);
		  	//cout<<n<<" "; //euler tour
		}
		else 
		{
			if(v[n][x] != parent)
				return true;
		}
	}
	return false;
  	//cout<<n<<" ";  //topological
  	// time_out[v] = timer++;
}

void computelpsarray(string s,ll lps[])
{
	ll i=1;
	ll j=0;
	lps[0] = 0;
	while(i<s.length())
	{
		if(s[i]==s[j])
		{
			lps[i] = j+1;
			i++;
			j++;
		}
		else
		{
			if(j==0)
			{
				lps[i] = 0;
				i++;
			}
			else
			{
				j = lps[j-1];
			}
		}
	}
}


void getZarr(string str, ll Z[]) 
{ 
    ll n = str.length(); 
    ll L, R, k; 
    L = R = 0; 
    Z[0] = 0;
    for (ll i = 1; i < n; ++i) 
    { 
        if (i > R) 
        { 
            L = R = i; 
            while (R<n && str[R-L] == str[R]) 
                R++; 
            Z[i] = R-L; 
            R--; 
        } 
        else
        {  
            k = i-L; 
            if (Z[k] < R-i+1) 
                Z[i] = Z[k]; 
            else
            { 
                L = i; 
                while (R<n && str[R-L] == str[R]) 
                    R++; 
                Z[i] = R-L; 
                R--; 
            } 
        } 
    } 
} 

int myXOR(int x, int y) 
{ 
   return (x | y) & (~x | ~y); 
} 

ll func(ll x, ll ar[], ll dp[]) {
  if(dp[x] != -1) 
    return dp[x];
  return (dp[x] = min(func(x-1, ar, dp)+abs(ar[x]-ar[x-1]), func(x-2, ar, dp)+abs(ar[x]-ar[x-2])));
}
   

int main()
{	
	ll n;
	cin >> n;
	ll ar[3][n+1];
	for(ll x = 1; x <= n; x++) {
		for(ll y = 0; y < 3; y++) {
			cin >> ar[y][x];
		}
	}

	for(ll x = n-1; x >= 1; x--) {
		ar[0][x] = ar[0][x] + max(ar[1][x+1], ar[2][x+1]);
		ar[1][x] = ar[1][x] + max(ar[0][x+1], ar[2][x+1]);
		ar[2][x] = ar[2][x] + max(ar[0][x+1], ar[1][x+1]);
	}

	cout << max(ar[0][1], max(ar[1][1], ar[2][1]));
}	

Measured memory_bytes: 5888