int f[MAXN][MAXN]; int seq[MAXN]; longlongint ans[MAXN];
bool inGraph[MAXN];
int n;
inlineintgetint(){ int s = 0, x = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') x = -1; ch = getchar(); } while (isdigit(ch)) { s = s * 10 + ch - '0'; ch = getchar(); } return s * x; }
inlinevoidputint(int x, bool returnValue){ if (x < 0) { x = -x; putchar('-'); } if (x >= 10) putint(x / 10, false); putchar(x % 10 + '0'); if (returnValue) putchar('\n'); }
inlinevoidaddEdge(int s, int t, int w){ f[s][t] = f[t][s] = w; }
intmain(int argc, char *const argv[]){ n = getint(); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { f[i][j] = getint(); } } for (int i = 1; i <= n; ++i) { seq[i] = getint(); } for (int l = n; l > 0; --l) { int k = seq[l]; inGraph[k] = true; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { f[i][j] = std::min(f[i][j], f[i][k] + f[k][j]); if (inGraph[i] && inGraph[j]) ans[l] += f[i][j]; } } } for (int i = 1; i <= n; ++i) cout << ans[i] << ' '; return0; }