#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
using namespace std;
int g[22][22], cost[22];
int dp[(1 << 20) + 10];
int n, ans;
void floyd() {
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
if (i == k)continue;
for (int j = 0; j < n; j++) {
if (j == k || i == j)continue;
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
}
}
}
}
void dfs(int last, int count, int now) {
if (ans == n)return;
if (ans < count)ans = count;
if (dp[now] <= 0)return;
for (int i = 0; i < n; i++) {
if (!(now&(1 << i)) && dp[now] - g[last][i] - cost[i] >= 0) {
if (dp[now | (1 << i)] < dp[now] - g[last][i] - cost[i]){
dp[now | (1 << i)] = dp[now] - g[last][i] - cost[i];
dfs(i, count + 1, now | (1 << i));
}
}
}
}
int main() {
while (scanf("%d", &n) && n) {
for (int i = 0; i < n; ++i)
scanf("%d", cost + i);
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
scanf("%d", &g[i][j]);
floyd();
memset(dp, -1, sizeof(dp));
ans = 0;
for (int i = 0; i < n; ++i)
if (cost[i] <= 420) {
dp[1 << i] = 420 - cost[i];
dfs(i, 1, 1 << i);
}
printf("%d\n", ans);
}
return 0;
}