#include <iostream>
#include <algorithm>
#include <cmath>
#include <string.h>
using namespace std;
#define MAXN 20
#define INF 1e20;
int n, m;
int value[MAXN];
int c[MAXN][MAXN];
int ans[MAXN];
int copys[MAXN];
bool vis[MAXN];
bool choice[MAXN];
int pre[MAXN];
struct Edge
{
int u, v;
double w;
}edge[MAXN * MAXN];
int e;
void add(int u, int v, int val)
{
edge[e].u = u;
edge[e].v = v;
edge[e++].w = val;
}
bool cmp(Edge a, Edge b)
{
return a.w < b.w;
}
int find(int x)
{
return x == pre[x] ? x : (pre[x] = find(pre[x]));
}
double cal(int co[])
{
memset(choice, false, sizeof(choice));
double temp = 0;
for (int i = 0; i < m; i++)
{
choice[co[i]] = true;
temp += value[co[i]];
}
int num = 1;
double res = 0;
for (int i = 0; i < n; i++)
{
pre[i] = i;
}
for (int i = 0; i < e; i++)
{
int u = edge[i].u, v = edge[i].v, w = edge[i].w;
if (choice[u] && choice[v])
{
int fu = find(u), fv = find(v);
if (fu != fv)
{
pre[fu] = fv;
res += w;
num++;
}
if (num == m)
{
return res / temp;
}
}
}
}
double temp;
void dfs(int x, int len)
{
if (len == m)
{
double r = cal(copys);
if (r - temp < -(1e-12))
{
temp = r;
for (int i = 0; i < m; i++)
{
ans[i] = copys[i];
}
}
return ;
}
else
{
for (int i = x; i < n; i++)
{
if (!vis[i])
{
vis[i] = true;
copys[len++] = i;
dfs(i, len);
len--;
vis[i] = false;
}
}
}
}
void input()
{
int u, v;
double val;
while (cin >> n >> m)
{
if (!n && !m)
{
break;
}
e = 0;
memset(vis, false, sizeof(vis));
for (int i = 0; i < n; i++)
{
cin >> value[i];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> val;
if (i < j)
{
add(i, j, val);
}
}
}
sort(edge, edge + e, cmp);
temp = INF;
dfs(0, 0);
for (int i = 0; i < m; i++)
{
cout << ans[i] + 1;
if (i != m - 1)
{
cout << ' ';
}
}
cout << endl;
}
}
int main()
{
input();
return 0;
}
注意精度(看了别人的)。