Problem: The annual college sports-ball tournament is approaching, which for trademark reasons we'll refer to as Third Month Insanity. There are a total of 2N teams participating in the tournament, numbered from 1 to 2N. The tournament lasts N rounds, with each round eliminating half the teams. The first round consists of 2N - 1 games, numbered starting from 1. In game i, team 2·i - 1 will play against team 2·i. The loser is eliminated and the winner advances to the next round (there are no ties). Each subsequent round has half as many games as the previous round, and in game i the winner of the previous round's game 2·i - 1 will play against the winner of the previous round's game 2·i.

Every year the office has a pool to see who can create the best bracket. A bracket is a set of winner predictions for every game. For games in the first round you may predict either team to win, but for games in later rounds the winner you predict must also be predicted as a winner in the previous round. Note that the bracket is fully constructed before any games are actually played. Correct predictions in the first round are worth 1 point, and correct predictions in each subsequent round are worth twice as many points as the previous, so correct predictions in the final game are worth 2N - 1 points.

For every pair of teams in the league, you have estimated the probability of each team winning if they play against each other. Now you want to construct a bracket with the maximum possible expected score.

Input

Input will begin with a line containing N (2 ≤ N ≤ 6).

2N lines follow, each with 2N integers. The j-th column of the i-th row indicates the percentage chance that team i will defeat team j, unless i = j, in which case the value will be 0. It is guaranteed that the i-th column of the j-th row plus the j-th column of the i-th row will add to exactly 100.

Output

Print the maximum possible expected score over all possible brackets. Your answer must be correct to within an absolute or relative error of 10 - 9.

Formally, let your answer be a, and the jury's answer be b. Your answer will be considered correct, if <image>.

Examples

Input

2
0 40 100 100
60 0 40 40
0 60 0 45
0 60 55 0


Output

1.75


Input

3
0 0 100 0 100 0 0 0
100 0 100 0 0 0 100 100
0 0 0 100 100 0 0 0
100 100 0 0 0 0 100 100
0 100 0 100 0 0 100 0
100 100 100 100 100 0 0 0
100 0 100 0 0 100 0 0
100 0 100 0 100 100 100 0


Output

12


Input

2
0 21 41 26
79 0 97 33
59 3 0 91
74 67 9 0


Output

3.141592

Note

In the first example, you should predict teams 1 and 4 to win in round 1, and team 1 to win in round 2. Recall that the winner you predict in round 2 must also be predicted as a winner in round 1.

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

/*
 public class _859D {

 }

 */

public class _859D {

  class perme {
    int f;
    int s;
    int w;

    public perme(int f, int s, int w) {
      super();
      this.f = f;
      this.s = s;
      this.w = w;
    }
  }

  class winner {
    int w;
    double wp;

    public winner() {
      super();
    }


    public winner(int w, double wp) {
      super();
      this.w = w;
      this.wp = wp;
    }


  }

  public void solve() throws FileNotFoundException {
    InputStream inputStream = System.in;

    InputHelper inputHelper = new InputHelper(inputStream);

    PrintStream out = System.out;

    // actual solution
    int n = inputHelper.readInteger();

    double[][] gp = new double[1 << n][1 << n];

    for (int i = 0; i < (1 << n); i++) {
      for (int j = 0; j < (1 << n); j++) {
        gp[i][j] = inputHelper.readInteger();
        gp[i][j] /= 100;
      }
    }

    dpp = new double[1 << (n + 1)][1 << n];
    dps = new double[1 << (n + 1)][1 << n];

    for (int i = 0; i < (1 << (n + 1)); i++) {
      for (int j = 0; j < (1 << n); j++) {
        dpp[i][j] = -1;
      }
    }

    double ans = 0;

    for (int i = 0; i < (1 << n); i++) {
      dfs2(0, 0, (1 << n) - 1, gp, (1 << (n - 1)), i);
    }

    for (int i = 0; i < (1 << n); i++) {
      ans = Math.max(ans, dps[0][i]);
    }

    System.out.println(ans);
    // end here
  }

  double[][] dpp;
  double[][] dps;

  void dfs2(int i, int rs, int re, double[][] gp, double score, int winner) {

    if (dpp[i][winner] != -1) {
      return;
    }

    if (rs == re) {
      if (rs == winner)
        dpp[i][winner] = 1;
      else
        dpp[i][winner] = 0;

      dps[i][winner] = 0;
      return;
    }

    int mid = (rs + re) / 2;

    for (int j = rs; j <= mid; j++)
      dfs2(i * 2 + 1, rs, mid, gp, score / 2, j);

    for (int j = mid + 1; j <= re; j++)
      dfs2(i * 2 + 2, mid + 1, re, gp, score / 2, j);

    dpp[i][winner] = 0;
    dps[i][winner] = 0;

    if (winner >= rs && winner <= mid) {
      for (int j = mid + 1; j <= re; j++) {
        dpp[i][winner] += dpp[i * 2 + 1][winner] * dpp[i * 2 + 2][j] * gp[winner][j];
      }

      for (int j = mid + 1; j <= re; j++) {
        dps[i][winner] =
            Math.max(dps[i][winner], dps[i * 2 + 1][winner] + dps[i * 2 + 2][j] + score
                * dpp[i][winner]);
      }
    } else if (winner > mid && winner <= re) {
      for (int j = rs; j <= mid; j++) {
        dpp[i][winner] += dpp[i * 2 + 1][j] * dpp[i * 2 + 2][winner] * gp[winner][j];
      }

      for (int j = rs; j <= mid; j++) {
        dps[i][winner] =
            Math.max(dps[i][winner], dps[i * 2 + 1][j] + dps[i * 2 + 2][winner] + score
                * dpp[i][winner]);
      }
    }
  }

  // List dfs(int i, int rs, int re, double[][] gp, int score, List[] wa) {
  // if (rs == re) {
  // return wa[i] = Arrays.asList(new winner(rs, 1.0));
  // }
  //
  // wa[i * 2 + 1] = dfs(i * 2 + 1, rs, (rs + re) / 2, gp, score / 2, wa);
  // wa[i * 2 + 2] = dfs(i * 2 + 2, (rs + re) / 2 + 1, re, gp, score / 2, wa);
  //
  // wa[i] = new ArrayList<winner>();
  //
  // int n1 = wa[i * 2 + 1].size();
  // int n2 = wa[i * 2 + 2].size();
  //
  // for (int j = 0; j < wa[i * 2 + 1].size(); j++) {
  // for (int k = 0; k < wa[i * 2 + 2].size(); k++) {
  // int fw = ((winner) wa[i * 2 + 1].get(j)).w;
  // double fwp = ((winner) wa[i * 2 + 1].get(j)).wp;
  //
  // int sw = ((winner) wa[i * 2 + 2].get(k)).w;
  // double swp = ((winner) wa[i * 2 + 2].get(k)).wp;
  //
  // tscore += (score * fwp * swp * Math.max(gp[sw][fw], gp[fw][sw]));
  // }
  // }
  //
  // double[] winp = new double[n1 + n2];
  //
  // for (int j = 0; j < wa[i * 2 + 1].size(); j++) {
  // for (int k = 0; k < wa[i * 2 + 2].size(); k++) {
  //
  // int fw = ((winner) wa[i * 2 + 1].get(j)).w;
  // double fwp = ((winner) wa[i * 2 + 1].get(j)).wp;
  //
  // int sw = ((winner) wa[i * 2 + 2].get(k)).w;
  // double swp = ((winner) wa[i * 2 + 2].get(k)).wp;
  //
  // winp[j] += fwp * swp * gp[fw][sw];
  // winp[n1 + k] += fwp * swp * gp[sw][fw];
  // }
  // }
  //
  // for (int j = 0; j < n1; j++) {
  // wa[i].add(new winner(((winner) wa[i * 2 + 1].get(j)).w, winp[j]));
  // }
  //
  // for (int j = n1; j < n1 + n2; j++) {
  // wa[i].add(new winner(((winner) wa[i * 2 + 2].get(j - n1)).w, winp[j]));
  // }
  //
  // return wa[i];
  // }

  public static void main(String[] args) throws FileNotFoundException {
    (new _859D()).solve();
  }

  class InputHelper {
    StringTokenizer tokenizer = null;
    private BufferedReader bufferedReader;

    public InputHelper(InputStream inputStream) {
      InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
      bufferedReader = new BufferedReader(inputStreamReader, 16384);
    }

    public String read() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          String line = bufferedReader.readLine();
          if (line == null) {
            return null;
          }
          tokenizer = new StringTokenizer(line);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      return tokenizer.nextToken();
    }

    public Integer readInteger() {
      return Integer.parseInt(read());
    }

    public Long readLong() {
      return Long.parseLong(read());
    }
  }
}