// Arup Guha
// 8/7/2018
// Solution to 2018 NAQ Proposed Problem: Peg Game

import java.util.*;

public class peggame_arup {
	
	final public static int SIZE = 5;
	final public static int NUMHOLES = 15;

	// Possible jump directions.
	final public static int[] DX = {-1,-1,0,0,1,1};
	final public static int[] DY = {-1,0,-1,1,0,1};

	public static int[][] board;
	public static int[][] indexLookup;
	public static int[] lookup;

	// Will store the scores of each board we've calculated so far to avoid
	// redundant calculations.
	public static HashMap<Long,Integer> memo;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);

		board = new int[SIZE][SIZE];
		indexLookup = new int[SIZE][SIZE];
		lookup = new int[NUMHOLES+1];

		// Read in the board and store the lookup and backwards lookup.
		int ID = 1;
		for (int i=0; i<SIZE; i++) {
			for (int j=0; j<=i; j++) {
				board[i][j] = stdin.nextInt();
				//if (board[i][j] == 0) continue;
				lookup[ID] = board[i][j];
				indexLookup[i][j] = ID;
				ID++;
			}
		}

		memo = new HashMap<Long,Integer>();

		// This is the initial board position.
		// An item x>0 in position i in the mask indicates that the item
		// that started in position x is now in position i. If 0 is in the
		// mask, that indicates an empty square.
		long initMask = 0;
		for (int i=NUMHOLES; i>=1; i--) {
			initMask = (initMask << 4);
			if (lookup[i] != 0) initMask += i;
		}
		
		// Output the result.
		System.out.println(solveIt(initMask));
	}

	public static int solveIt(long mask) {

		// Memoization to avoid redundancy.
		if (memo.containsKey(mask)) return memo.get(mask);

		// See what we could do next.
		ArrayList<state> next = getNextPos(mask);

		// Oops, nothing game is over so the score is 0.
		if (next.size() == 0) return 0;

		// We couldn't do this bad based on the bounds.
		int res = -1000000;

		// Try each move.
		for (state s: next) {

			// So our game score would be this minus our opponent's best score.
			int tmp = s.pts - solveIt(s.mask);

			// We want to take the best of all of our options.
			res = Math.max(res, tmp);
		}

		// Store it, so we don't have to do all this work again!
		memo.put(mask, res);

		// Ta da!
		return res;
	}

	// Returns all possible future positions from the board position represented by mask.
	public static ArrayList<state> getNextPos(long mask) {

		ArrayList<state> pos = new ArrayList<state>();

		// Try each potential starting position.
		for (int r=0; r<SIZE; r++) {
			for (int c=0; c<=r; c++) {

				// Now try each move.
				for (int dir=0; dir<DX.length; dir++) {

					// Ending square is out of bounds.
					if (!inbounds(r+2*DX[dir], c+2*DY[dir])) continue;
					
					// These are my bitmask locations.
					int slocI = indexLookup[r][c];
					int mlocI = indexLookup[r+DX[dir]][c+DY[dir]];
					int elocI = indexLookup[r+2*DX[dir]][c+2*DY[dir]];
					int sloc = (int)get(mask, slocI);
					int mloc = (int)get(mask, mlocI);
					
					// A move is valid only if the first two holes have pegs and the destination doesn't.
					if (on(mask, slocI) && on(mask, mlocI) && !on(mask, elocI)) {
						long newpos = apply(mask, dir, r, c);
						state tmp = new state(newpos, lookup[sloc]*lookup[mloc]);
						pos.add(tmp);
					}
				}
			}
		}

		// Here is a list of all the possible moves.
		return pos;
	}

	// Returns the result of appplying the move from (r,c) in direction dir on the board stored in mask.
	public static long apply(long mask, int dir, int r, int c) {

		// Get the numeric location(0-14) of the starting hole, middle hole and ending hole of the jump.
		int start = indexLookup[r][c];
		int mid = indexLookup[r+DX[dir]][c + DY[dir]];
		int end = indexLookup[r+2*DX[dir]][c + 2*DY[dir]];

		// Put holes in these two squares.
		long res = turnOff(mask, start);
		res = turnOff(res, mid);

		// This is what we get when we put the token that was on start at end.
		long code = (mask >> (4*start-4)) & 15L;
		
		return turnOn(res, end, code);
	}

	// Replaces location loc with 0, should be immediately replaced.
	public static long turnOff(long mask, int loc) {
		return mask - get(mask, loc)*(1L << (4*loc-4));
	}

	// Assumes mask has location loc zeroed out. Adds to loc the value val (must be 0 - 15).
	public static long turnOn(long mask, int loc, long val) {
		return mask + val*(1L<<(4*loc-4));
	}

	// Returns true iff this location has a peg in it (doesn't have an empty hole).
	public static boolean on(long mask, int loc) {
		return get(mask, loc) != 0;
	}

	public static long get(long mask, int loc) {
		return (mask >> (4*loc-4)) & 15L;
	}

	// Returns true iff (myr, myc) is inbounds.
	public static boolean inbounds(int myr, int myc) {
		return myr >= 0 && myr < SIZE && myc >= 0 && myc <= myr;
	}
}

class state {

	public long mask;
	public int pts;

	public state(long m, int p) {
		mask = m;
		pts = p;
	}
}
