#include <vector>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <numeric>


#include<functional>

namespace detail
{
    template< typename T, std::size_t NDIMS > struct vector_builder
    {
        using type = std::vector< typename vector_builder<T,NDIMS-1>::type > ;

        static type make( std::vector<std::size_t> dims, const T& v = {} )
        {
            const auto vec = std::vector<T>( dims.empty() ? 0 : dims.back(), v ) ;
            if( !dims.empty() ) dims.pop_back() ;
            return vector_builder< std::vector<T>, NDIMS-1 >::make( dims, vec ) ;
        }
    };

    template< typename T > struct vector_builder<T,1>
    {
        using type = std::vector<T> ;

        static type make( std::vector<std::size_t> dims, const T& v = {} )
        { return type( dims.empty() ? 0 : dims.back(), v ) ; }
    };
}



template< typename T, typename... SIZE_T >
auto exvector( const T& v, SIZE_T... dims )
{
    static_assert( sizeof...(dims) != 0, "invalid dimension" ) ;
    std::vector<std::size_t> vec_dims{ dims... } ;
    return detail::vector_builder< T, sizeof...(dims) >::make( vec_dims, v ) ;
}


using namespace std;
//********************  dumps ************************//

template<typename T>
void dump(const T& data, vector<int>& iter) {
    cout << data << " ";
}
template<typename T>
void dump(const vector<T>& data, vector<int>& iter) {
    for(auto elem: data)
        dump(elem, iter);
    cout << endl;
}

template<typename T>
void dump(const vector<vector<T>>& data, vector<int>& iter) {
    for(auto elem : iter) {
        cout << "[" << elem << "]" ;
    }
    cout << endl;
    for(int i=0; i<data.size(); i++) {
        iter.push_back(i);
        dump(data[i], iter);
        iter.pop_back();
    }
    cout << endl;
}

template<typename T>
void dump(const vector<T>& data, int dummy) {
    for(int i=0; i<data.size(); i++) {
        cout <<"[" << i << "] " <<  data[i] << endl;
    }
}
template<typename T>
void dump(const T& data) { // T : data, U = base type val.
    vector<int> iter;
    dump(data, iter);
}

// ===================================
// getter / setter

template<typename T, typename U>
void setval(T& container, vector<int>& pos, U val, int iter) {
    container = (T)val;
}

template<typename T, typename U>
void setval(vector<T>& container, vector<int>& pos, U val, int iter) {
    setval(container[pos[iter]], pos, val, iter+1);
}
/*
template<typename T, typename U>
void setval(T& container, vector<int>& pos,  U val) {
    int iter = 0;
    setval(container, pos, val, iter);    
}
*/
template<typename T, typename U>
void setval(T& container, vector<int> pos,  U val) {
    int iter = 0;
    setval(container, pos, val, iter);    
}

template<typename T>
T getval(T& container, vector<int>& pos, T tmp,int iter) {
    return tmp = container;
}

template<typename T, typename U>
U getval(vector<T>& container, vector<int>& pos, U tmp, int iter) {
    return getval(container[pos[iter]], pos, tmp, iter+1);
}

template<typename T, typename U>
U getval(T& container, vector<int>& pos, U& tmp) {
    int iter = 0;
    return getval(container, pos, tmp, iter);    
}


//-----------------------------------
template<typename T>
void getindices(T& container, vector<int>& iter, vector<vector<int>>& res) {
    res.push_back(iter);
}
template<typename T>
void getindices(vector<T>& container, vector<int>& iter, vector<vector<int>>& res) {
    for(int i=0; i<container.size(); i++) {
        iter.push_back(i);
        getindices(container[i], iter, res);
        iter.pop_back();
    }
}

template<typename T>
vector<vector<int>> getindices(vector<T>& container) {
    vector<int> iter;
    vector<vector<int>> res;
    getindices(container, iter, res);
    return res;

}



template<typename T>
function<T(T, T)>  op_max = [] (T a, T b)-> T{
    return max(a, b);
};
template<typename T>
function<T(T, T)>  op_min = [] (T a, T b)-> T{
    return min(a, b);
};

template<typename T>
function<T(T, T)>  op_sum = [] (T a, T b)-> T{
    return a + b;
};




// prev->cur のように、完全に表を更新するタイプのDP
template<
    typename Tval,
    typename Tbase

>
vector<Tbase> update_dp(
        Tbase base_vector, 
        int iter,
        Tval initial_value,
        function<Tval(Tval, Tval)> op_merge,
        function<vector<vector<int>>(const vector<int>&)> update_pos,
        function<Tval(Tval, vector<int>& , vector<int>&)> op_edge
         ) {
    auto order = getindices(base_vector);
    vector<Tbase> result;
    result.push_back(base_vector);
    for(int i=0; i<iter; i++) {
        Tbase& prev_table = result.back();
        vector<int> current(base_vector.size(), initial_value);
        for(auto next : order) {
            // vector<int> next_ind = {i+1, j};
            vector<int> next_ind = {i+1};
            for(auto elem : next) next_ind.push_back(elem);
            vector<vector<int>> prev = update_pos(next_ind);
            for(auto prev_ind : prev) {
                setval(current, next,   
                    op_merge( 
                        getval(current, next, initial_value), 
                        op_edge(
                            getval(prev_table, prev_ind ,initial_value)
                            , prev_ind, next_ind)));
            }
        }
        result.push_back(current);
    }
    //dump(result);
    return result;
    
} 

int main() {
    auto base_vector = exvector((int)0, 3);

    int N;
    cin >> N;
    auto input = exvector((int)0, N, 3);
    for(int i=0; i<N; i++) {
        for(int j=0; j<3; j++)
            cin >> input[i][j];

    }

    int iter = N;
    function<vector<vector<int>>(const vector<int>&)> update_pos = 
            [](const vector<int> &a) -> vector<vector<int>>{
        vector<vector<int>> ret;
        for(int i=0; i<3; i++)
            if(a[1] != i)  {
                ret.push_back({i});
            }
        return ret;
    };
    int tmp_for_template;
    function<int(int, vector<int>&, vector<int>&)> op_edge = 
            [&](int val, vector<int>& from, vector<int>& to) -> int{
        return val + input[to[0]-1][to[1]];

    };
    vector<vector<int>> order;
    for(int i=0; i<3; i++) {
        order.push_back({i});
    }

    auto result = update_dp(
        vector<int> (3, 0),
        N, 0,
        op_max<int>, update_pos, op_edge
    );
    //cout << max({result[N][0], result[N][1], result[N][2]}) << endl;
    cout << accumulate(result[N].begin(), result[N].end(), 0, op_max<int>) << endl;
    
    return 0;
}

Measured memory_bytes: 12212