#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
template < class S, class T> inline S chmin( S & a, T b) {
if ( a> b) {
a= b;
}
return a;
}
#define main dummy_main
int main( ) {
return 0 ;
}
#undef main
int dp[ 4096 ] ;
int nx[ 4096 ] ;
class Solution{
public :
int connectTwoGroups( vector< vector< int >> & A) {
int i, mask;
int x = A.size ( ) ;
int y = A[ 0 ] .size ( ) ;
dp[ 0 ] = 0 ;
for ( mask= ( 1 ) ; mask< ( 1 << y) ; mask++ ) {
dp[ mask] = 1073709056 ;
}
for ( i= ( 0 ) ; i< ( x) ; i++ ) {
int j;
for ( mask= ( 0 ) ; mask< ( 1 << y) ; mask++ ) {
nx[ mask] = 1073709056 ;
}
for ( j= ( 0 ) ; j< ( y) ; j++ ) {
for ( mask= ( 0 ) ; mask< ( 1 << y) ; mask++ ) {
chmin( nx[ mask | ( 1 << j) ] , dp[ mask] + A[ i] [ j] ) ;
chmin( nx[ mask | ( 1 << j) ] , nx[ mask] + A[ i] [ j] ) ;
}
}
for ( mask= ( 0 ) ; mask< ( 1 << y) ; mask++ ) {
dp[ mask] = nx[ mask] ;
}
}
return dp[ ( 1 << y) - 1 ] ;
}
}
;
// cLay varsion 20200920-1
// --- original code ---
// #define main dummy_main
// {}
// #undef main
//
// int dp[4096], nx[4096];
//
// class Solution {
// public:
// int connectTwoGroups(vector<vector<int>>& A) {
// int x = A.size(), y = A[0].size();
//
// dp[0] = 0;
// rep(mask,1,1<<y) dp[mask] = int_inf;
//
// rep(i,x){
// rep(mask,1<<y) nx[mask] = int_inf;
// rep(j,y) rep(mask,1<<y){
// nx[mask | (1<<j)] <?= dp[mask] + A[i][j];
// nx[mask | (1<<j)] <?= nx[mask] + A[i][j];
// }
// rep(mask,1<<y) dp[mask] = nx[mask];
// }
//
// return dp[(1<<y)-1];
// }
// };
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnRlbXBsYXRlPGNsYXNzIFMsIGNsYXNzIFQ+IGlubGluZSBTIGNobWluKFMgJmEsIFQgYil7CiAgaWYoYT5iKXsKICAgIGE9YjsKICB9CiAgcmV0dXJuIGE7Cn0KI2RlZmluZSBtYWluIGR1bW15X21haW4KaW50IG1haW4oKXsKICByZXR1cm4gMDsKfQojdW5kZWYgbWFpbgppbnQgZHBbNDA5Nl07CmludCBueFs0MDk2XTsKY2xhc3MgU29sdXRpb257CiAgcHVibGljOgogIGludCBjb25uZWN0VHdvR3JvdXBzKHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIEEpewogICAgaW50IGksIG1hc2s7CiAgICBpbnQgeCA9IEEuc2l6ZSgpOwogICAgaW50IHkgPSBBWzBdLnNpemUoKTsKICAgIGRwWzBdID0gMDsKICAgIGZvcihtYXNrPSgxKTttYXNrPCgxPDx5KTttYXNrKyspewogICAgICBkcFttYXNrXSA9IDEwNzM3MDkwNTY7CiAgICB9CiAgICBmb3IoaT0oMCk7aTwoeCk7aSsrKXsKICAgICAgaW50IGo7CiAgICAgIGZvcihtYXNrPSgwKTttYXNrPCgxPDx5KTttYXNrKyspewogICAgICAgIG54W21hc2tdID0gMTA3MzcwOTA1NjsKICAgICAgfQogICAgICBmb3Ioaj0oMCk7ajwoeSk7aisrKXsKICAgICAgICBmb3IobWFzaz0oMCk7bWFzazwoMTw8eSk7bWFzaysrKXsKICAgICAgICAgIGNobWluKG54W21hc2sgfCAoMTw8aildLCBkcFttYXNrXSArIEFbaV1bal0pOwogICAgICAgICAgY2htaW4obnhbbWFzayB8ICgxPDxqKV0sIG54W21hc2tdICsgQVtpXVtqXSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvcihtYXNrPSgwKTttYXNrPCgxPDx5KTttYXNrKyspewogICAgICAgIGRwW21hc2tdID0gbnhbbWFza107CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBkcFsoMTw8eSktMV07CiAgfQp9CjsKLy8gY0xheSB2YXJzaW9uIDIwMjAwOTIwLTEKCi8vIC0tLSBvcmlnaW5hbCBjb2RlIC0tLQovLyAjZGVmaW5lIG1haW4gZHVtbXlfbWFpbgovLyB7fQovLyAjdW5kZWYgbWFpbgovLyAKLy8gaW50IGRwWzQwOTZdLCBueFs0MDk2XTsKLy8gCi8vIGNsYXNzIFNvbHV0aW9uIHsKLy8gcHVibGljOgovLyAgIGludCBjb25uZWN0VHdvR3JvdXBzKHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIEEpIHsKLy8gICAgIGludCB4ID0gQS5zaXplKCksIHkgPSBBWzBdLnNpemUoKTsKLy8gCi8vICAgICBkcFswXSA9IDA7Ci8vICAgICByZXAobWFzaywxLDE8PHkpIGRwW21hc2tdID0gaW50X2luZjsKLy8gCi8vICAgICByZXAoaSx4KXsKLy8gICAgICAgcmVwKG1hc2ssMTw8eSkgbnhbbWFza10gPSBpbnRfaW5mOwovLyAgICAgICByZXAoaix5KSByZXAobWFzaywxPDx5KXsKLy8gICAgICAgICBueFttYXNrIHwgKDE8PGopXSA8Pz0gZHBbbWFza10gKyBBW2ldW2pdOwovLyAgICAgICAgIG54W21hc2sgfCAoMTw8aildIDw/PSBueFttYXNrXSArIEFbaV1bal07Ci8vICAgICAgIH0KLy8gICAgICAgcmVwKG1hc2ssMTw8eSkgZHBbbWFza10gPSBueFttYXNrXTsKLy8gICAgIH0KLy8gCi8vICAgICByZXR1cm4gZHBbKDE8PHkpLTFdOwovLyAgIH0KLy8gfTsK