Problem:
Score : 100 points

Problem Statement

Taro's summer vacation starts tomorrow, and he has decided to make plans for it now.

The vacation consists of N days.
For each i (1 \leq i \leq N), Taro will choose one of the following activities and do it on the i-th day:

A: Swim in the sea. Gain a_i points of happiness.

B: Catch bugs in the mountains. Gain b_i points of happiness.

C: Do homework at home. Gain c_i points of happiness.

As Taro gets bored easily, he cannot do the same activities for two or more consecutive days.

Find the maximum possible total points of happiness that Taro gains.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq a_i, b_i, c_i \leq 10^4

Input

Input is given from Standard Input in the following format:

N
a_1 b_1 c_1
a_2 b_2 c_2
:
a_N b_N c_N

Output

Print the maximum possible total points of happiness that Taro gains.

Sample Input 1

3
10 40 70
20 50 80
30 60 90

Sample Output 1

210

If Taro does activities in the order C, B, C, he will gain 70 + 50 + 90 = 210 points of happiness.

Sample Input 2

1
100 10 1

Sample Output 2

100

Sample Input 3

7
6 7 8
8 8 3
2 5 2
7 8 6
4 6 8
2 3 4
7 5 1

Sample Output 3

46

Taro should do activities in the order C, A, B, A, C, B, A.

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.io.*;
import java.util.*;
import java.math.BigInteger;

public class Main {


	public void readInput() throws Exception {
 		  
 			 
 		//BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
 		//BufferedReader buf = new BufferedReader(new FileReader("input.txt"));         
        int N = input.nextInt();
        int [][] tasks = new int[N][3];
        int [][] dp = new int[N][3];
        for(int i=0;i<N;i++){
            tasks[i][0] = input.nextInt();
            tasks[i][1] = input.nextInt();
            tasks[i][2] = input.nextInt();
        }
        dp[0][0] = tasks[0][0];
        dp[0][1] = tasks[0][1];
        dp[0][2] = tasks[0][2];
        int max = 0;
        for(int i=1;i<N;i++){
            for(int j=0;j<3;j++){
                max = 0;
                for(int k=0;k<3;k++){
                    if(k!=j) {
                        max = Math.max(dp[i-1][k], max);
                        //System.out.printf("tasks[%d][%d]: %d max: %d\n",(i-1), k, tasks[i-1][k], max);
                    }
                }
                //System.out.printf("max: %d\n",max);
                dp[i][j] = tasks[i][j] + max ;
                //System.out.printf("dp[%d][%d]: %d\n",i,j, dp[i][j]);
            }
        }
        max =0;
        for(int i=0;i<3;i++){
            max = Math.max(max, dp[N-1][i]);
        }
        System.out.printf("%d\n",max);
           
    }

    private void print(int[][] matrix) {
        for(int i=0;i<matrix.length;i++){
            System.out.println(Arrays.toString(matrix[i]));
        }
        System.out.println();
    }
  
   

    private static void swap(char []array, int i, int j){
        char temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
 

	public static void main(String[] args) throws Exception {
		Main ans = new Main();
		ans.readInput(); 
        out.close();
		//shouldReturn10();
		
	}


    private static InputStream inputStream = System.in;
    private static InputReader input = new InputReader(inputStream);
    private static OutputStream outputStream = System.out;
    private static PrintWriter out = new PrintWriter(outputStream);
	 
    static class InputReader {
        private BufferedReader buf;
        private StringTokenizer token;
        public InputReader(InputStream inputStream){
            buf = new BufferedReader(new InputStreamReader(inputStream),32768);
            token = null;
        }
        
        private String next(){
            while(token==null || !token.hasMoreTokens()){
                try{
                    token = new StringTokenizer(buf.readLine());
                }catch(Exception e){
                    throw new RuntimeException("Error in reading input",e);
                }
            }
            return token.nextToken();
        }
        
        public int nextInt(){
            return Integer.parseInt(next());
        }

        public String nextString(){
            return next();
        }

        public long nextLong(){
            return Long.parseLong(next());
        }
    }
}

class XCoordinateComparator implements Comparator<Point>{

    public int compare(Point p1, Point p2){
        if (p1.x == p2.x) return p1.y - p2.y;
        return p1.x-p2.x;
    }

}
class YCoordinateComparator implements Comparator<Point>{

    public int compare(Point p1, Point p2){
        if (p1.y == p2.y) return p1.x - p2.x;
        return p1.y-p2.y;
    }

}
class Point{
    int x,y;
    public Point(int x, int y){
        this.x = x;
        this.y = y;
    }
    public String toString(){
        return "("+x+","+y+")";
    }

    public int hashCode(){
        String s = x+""+y;
        return s.hashCode();
    }
    @Override
    public boolean equals(Object obj){
        Point p = (Point) obj;         
        return this.x == p.x && this.y == p.y;
    }
}
class DNode{
    int val;
    int index;
    DNode next,prev;
    public DNode(int val, int index){
        this.val = val;
        this.index = index;
    }
    public boolean equals(Object o){
        if (!(o instanceof DNode)){
            return false;
        }
        DNode other = (DNode)o;
        return (other.val==this.val) && (other.index == this.index);

    }

    public String toString() {
        return this.index + " -> " + this.val;
    }
}
class DList{

    DNode tail,head;
    int count;

    public DList() {
        tail = new DNode(-1,-1);         
        head = new DNode(-2,-2);
        head.next = tail;
        head.prev = tail;
        tail.prev = head;
        tail.next = head;
        count =0;
    }
    public void add(int val, int index){
        DNode curr = new DNode(val, index);
        count++;
        addNode(curr);
    }
    public void addLast(int val, int index){
        DNode curr = new DNode(val, index);
        count++;
        addLast(curr);
    }

    private void addNode(DNode curr) {
        DNode temp = head.next;
        head.next = curr;
        curr.prev = head;

        curr.next = temp;
        temp.prev = curr;
    }

    private void addLast(DNode curr) {
        DNode temp = tail.prev;
        tail.prev = curr;
        curr.next = tail;

        curr.prev = temp;
        temp.next = curr;
    }

    public boolean hasNext(){
        return !head.next.equals(tail);
    }
    public DNode remove() {
        count--;
        DNode temp = head.next;
        DNode nextNode = temp.next;
        head.next = nextNode;
        nextNode.prev = head;
        return temp;
    }
    
    public int size(){
        return count;
    }

    public void printNodes() {
        DNode curr = head.next;
        while(!curr.equals(tail)){
            System.out.println(curr);
            //System.out.print("->");
            curr = curr.next;
        }
        System.out.println("NULL");
    }


}