// Original C++ solution (slower):
// Author : Mohamed Sameh

#include <bits/stdc++.h>

typedef long long ll ;

#define pb push_back

#define f first

#define s second

#define all(v) v.begin(),v.end()

#define rall(v) v.rbegin(),v.rend()

#define SZ(a) (int)a.size()

#define Flush fflush(stdout);

using namespace std ;

const int N = 16;

const ll MN = -1e9*N;

int n;

int a[N][N];

ll dp[(1<<N)];

ll value[(1<<N)];

int arr[N];

ll solve(int msk = (1<<n)-1)

{

  if (!msk)return 0;

  ll &ret = dp[msk];

  if (~ret)return ret;

  ret = MN;

  for (int cur_msk = msk; cur_msk; cur_msk=(cur_msk-1)&msk)

  {

    ret = max(ret, value[cur_msk] + solve(msk^cur_msk));

  }

  return ret;

}

ll get_cost(int sz)

{

  ll ret = 0;

  for (int i = 0; i < sz; i++)

    for (int j = i+1; j < sz; j++)

      ret += a[arr[i]][arr[j]];

  return ret;

}

int main()

{

  scanf("%d", &n);

  for (int i = 0; i < n; i++)

    for (int j = 0; j < n; j++)

      scanf("%d", a[i]+ j);

  memset(dp, -1, sizeof dp);

  for (int i = 0; i < (1<<n); i++)

  {

    int idx = 0;

    for (int j = 0; j < n; j++)

    {

      if (i & (1<<j))arr[idx++] = j;

    }

    value[i] = get_cost(idx);

  }

  printf("%lld\n", solve());

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define eps 1e-3

#define pi acos(-1.0)

#define inf 0x3f

#define INF 0x3f3f3f3f

#define pb push_back

#define debug1 cout<<"&&";

#define debug2 cout<<"**";

#define ms(a, x) memset(a, x, sizeof(a))

#define for0(i, n) for(int i = 0; i < n; ++i)

#define for1(i, n) for(int i = 1; i <= n; ++i)

using namespace std;

typedef double db;

typedef long long ll;

typedef unsigned long long ull;

typedef pair<int, int> pii;

typedef pair<long long, int> pli;

typedef pair<long long, long long> pll;

const int mod = 1e9 + 7;

const int N = 50;

const int M = 1e5+10;

/*=================================================================================*/



int n, a[N][N], con[N];

ll ans, dp[M], tmp[M];



int main() {

   scanf("%d", &n);

   for0(i, n) for0(j, n) scanf("%d", &a[i][j]);



   for0(now, (1<<n)) {

      int cnt = 0;

      for0(i, 16)

         if(now & (1<<i)) {

            con[cnt++] = i;

         }

      ll sum = 0;

      for0(i, cnt) for(int j = i + 1; j < cnt; ++j) {

         sum += a[con[i]][con[j]];

      }

      dp[now] = tmp[now] = sum;

   }



   for0(now, (1<<n)) for(int last = now; last; last = (last-1) & now) {

      dp[now] = max(dp[now], dp[now ^ last] + tmp[last]);

   }



   cout<<dp[(1<<n) - 1]<<endl;

   return 0;

}

// Fastest known solution for this problem:
#include <iostream>

#include <algorithm>

#include <vector>

#include <cassert>



using namespace std;





int main() {



  int N;



  cin >> N;

  vector< vector<long long> > A(N, vector<long long>(N));



  for (auto i=0;i <N; i++)

  for (auto j=0;j <N; j++) cin >> A[i][j];



  vector<long long> F( 1<<17, 0);



  // consider all sub sets of {1..N}

  vector<int> l(16, 0);

  for (long long s = 1; s < (1<<N); s++) {

    l.resize(0);



    auto ss= s;

    int c = 0;

    while(ss != 0) {

      if (ss & 1 ) l.push_back(c);

      ss = ss >> 1;

      c++;

    }



    // for (auto tt=0; tt<l.size(); tt++) 

    // cout << "l" << l[tt] << "  ";

    // cout << endl;

    F[s] = 0;

    for (auto i=0; i < l.size(); i++)

    for (auto j=i+1; j < l.size(); j++) F[s] += A[l[i]][l[j]];



    auto L = l.size();



    for (int j = s; j; j = (j-1)&s) {

      F[s] = max( F[s], F[s^j]+F[j]);

    }



    // cout << endl;

  }





  cout << F[ (1<<N)-1] << endl;



  return 0;

}