#include <assert.h>
#include <stdio.h>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <sstream>
#include <cstring>

using namespace std;

#define Size(x) (int)(x).size()
#define For(i,a,b) for(int i=(int)(a);i<=(int)(b);++i)
#define Ford(i,a,b) for(int i=(int)(a);i>=(int)(b);--i) 
#define RepV(i,v) for (int i=0;i<Size(v);++i)
#define All(c) (c).begin(),(c).end()
#define Fill(a,b) memset(&a,b,sizeof(a))
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Abs(a) ((a)<0?-(a):(a))

const int maxn = 100;
const int INF = 1000000;

int c[maxn+1][maxn+1]; // capacities
int f[maxn+1][maxn+1]; // flow

int max_flow(int s, int t, int start, int finish){
   Fill(f,0);
   int flow[maxn+1], p[maxn+1], res=0;
   while (true) {
      Fill(flow,0); flow[s]=INF; Fill(p,0);
      queue <int> q; q.push(s);
      while (!q.empty()){
         int u=q.front(); q.pop();
         For(i,start,finish) if (c[u][i]-f[u][i]>0 && flow[i]==0) {
            flow[i] = Min(flow[u],c[u][i]-f[u][i]);
            p[i]=u;
            q.push(i);
            if (i==t) break;
         }
         if (flow[t]>0) break;
      }
      if (flow[t]==0) break;
      res += flow[t];
      int u=t;
      while (u!=s) {
         f[p[u]][u]+=flow[t];
         f[u][p[u]]=-f[p[u]][u];
         u=p[u];
      }
   }
   return res;
}

const int MAXN = 30;

int n, m[MAXN], begin[MAXN], end[MAXN], t[MAXN][MAXN];

int main(){
//   freopen("input.txt","rt",stdin);
//   freopen("output.txt","wt",stdout);
   
   // Input data
   scanf("%d",&n);
   
   assert(n>=1 && n<=20);
   
   For(i,1,n) {
      scanf("%d",&m[i]);
      assert(m[i]>=1 && m[i]<=50);
   }
   For(i,1,n) {
      int h1, h2, m1, m2;
      scanf("%d:%d %d:%d",&h1,&m1,&h2,&m2);
      assert(h1>=0 && h1<=23 && m1>=0 && m1<=59 && h2>=0 && h2<=23 && m2>=0 && m2<=59);
      begin[i] = h1*60+m1; end[i] = h2*60+m2;
      assert(end[i]-begin[i]>=1);
   }
   
   For(i,1,n) For(j,1,n) {
      scanf("%d",&t[i][j]);
      assert(t[i][j]>=0 && t[i][j] <= 24*60);
   }
   
   // Solving
   
   int st = 0, fn = 2*n+1;
   
   Fill(c,0);
   For(i,1,n) c[st][i] = INF, c[n+i][fn]=INF, c[i][n+i]=INF;
   For(i,1,n) For(j,1,n) if (end[i] + t[i][j] <= begin[j]) c[n+i][j]=INF;
   
   For(i,1,n) c[i][n+i] -= m[i];
   c[fn][st]=INF;
   
   int st2=fn+1, fn2=fn+2;
   For(i,1,n) c[st2][n+i]=m[i], c[i][fn2]=m[i];
   
   max_flow(st2,fn2,st,fn2);
   
   // Assertion: feasible flow should always exist in given network!
   For(i,1,n) assert( f[st2][n+i]==m[i] );
   
   c[fn][st]=0; f[fn][st]=0; f[st][fn]=0;
   For(i,1,n) c[i][n+i] += m[i], f[i][n+i]+=m[i], f[n+i][i]-=m[i];
   
   int mf=0;
   For(i,1,n) mf += f[st][i];
   
   For(i,st,fn) For(j,st,fn) assert( f[i][j]+f[j][i]==0 );
   
   For(i,st,fn) For(j,st,fn) if (f[i][j] > 0) {
      c[i][j] = INF-f[i][j];
      c[j][i] = f[i][j] - (i>=1 && i<=n ? m[i] : 0);
   }
   
   mf -= max_flow(fn,st,st,fn);
   
   // Output data
   
   cout << mf;
   
   return 0;
}
