#include<iostream>
#include<vector>
#include<numeric>
#include<algorithm>
#define PB push_back
using namespace std;
int main()
{
  int n;cin>>n;
  vector<int>fanta,fanta1;
  for(int i=0;i<n;i++)
  {
     int y;cin>>y;
     fanta.PB(y);
  }
  int sum=0;
   fanta1=fanta;
   int sum1=0;
    sort(fanta1.begin(),fanta1.end());

  int m;cin>>m;
  vector<vector<int>>fanti(m);
  for(int i=0;i<m;i++)
  {
    int k,l,r;
    cin>>k>>l>>r;
     fanti[i].PB(k);fanti[i].PB(l); fanti[i].PB(r);
  }
   for(int i=0;i<m;i++)
   { long double int ans1=accumulate(fanta.begin(),fanta.end(),sum);
     if(fanti[i][0]==1)
     {
        for(int j=0;j<fanti[i][1]-1;j++)
        {
           ans1=ans1-fanta[j];
        }
        for(int j=fanti[i][2];j<n;j++)
        {
          ans1=ans1-fanta[j];
        }
        cout<<ans1<<"\n";
     }
     if(fanti[i][0]==2)
     {
        for(int j=0;j<fanti[i][1]-1;j++)
        {
           ans1=ans1-fanta1[j];
        }
        for(int j=fanti[i][2];j<n;j++)
        {
          ans1=ans1-fanta1[j];
        }
        cout<<ans1<<"\n";
     }
   }

}


#include<iostream>
#include<vector>
#include<numeric>
#include<algorithm>
#define PB push_back
using namespace std;
int main()
{
  int n;cin>>n;
  vector<int>fanta,fanta1;
  for(int i=0;i<n;i++)
  {
     int y;cin>>y;
     fanta.PB(y);
  }
   fanta1=fanta;
    sort(fanta1.begin(),fanta1.end());
  int m;cin>>m;
  vector<vector<int>>fanti(m);
  for(int i=0;i<m;i++)
  {
    int k,l,r;
    cin>>k>>l>>r;
     fanti[i].PB(k);fanti[i].PB(l); fanti[i].PB(r);
  }
   for(int i=0;i<m;i++)
   {
     if(fanti[i][0]==1)
     {
       int sum1=0;
        for(int j=fanti[i][1]-1;j<=fanti[i][2]-1;j++)
        {
           sum1=sum1+fanta[j];
        }
        cout<<sum1<<"\n";

     }
     if(fanti[i][0]==2)
     { int sum=0;
        for(int j=fanti[i][1]-1;j<=fanti[i][2]-1;j++)
        {
           sum=sum+fanta1[j];
        }
        cout<<sum<<"\n";
     }
   }

}


#include <iostream>
#include <vector>
#include <set>
#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long int n;
    cin>>n;
    vector <long long int> v1;
    vector <long long int> s1;

    for(long long int i=0;i<n;i++)
    {
        long long int inp;
        cin>>inp;
        v1.push_back(inp);
        s1.push_back(inp);

    }
    long long int m;
    cin>>m;
    sort(s1.begin(),s1.end());

    for(long long int u=0;u<m;u++)
    {
        long long int type,l,r;
        cin>>type>>l>>r;
        if(type==1)
        {   long long int sum=0;
            for(long long int f=l-1;f<r;f++)
                {
                    sum=sum+v1[f];
                }

                cout<<sum<<endl;

        }
        else
        {
                 long long int sum=0;
            for(long long int f=l-1;f<r;f++)
                {
                    sum=sum+s1[f];
                }

                cout<<sum<<endl;

        }
    }

}


#include <iostream>
#include <vector>
#include <set>
#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long int n;
    cin>>n;
    vector <long long int> v1;
    vector <long long int> s1;

    for(long long int i=0;i<n;i++)
    {
        long long int inp;
        cin>>inp;
        v1.push_back(inp);
        s1.push_back(inp);

    }
    long long int m;
    cin>>m;
    sort(s1.begin(),s1.end());

    for(long long int u=0;u<m;u++)
    {
        long long int type,l,r;
        cin>>type>>l>>r;
        if(type==1)
        {
            cout<<accumulate(v1.begin()+l-1,v1.begin()+r,0)<<endl;
        }
        else
        {
            cout<<accumulate(s1.begin()+l-1,s1.begin()+r,0)<<endl;
        }
    }

}


#include <iostream>
#include <vector>
#include <set>
#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long int n;
    cin>>n;
    vector <long long int> v1;
    vector <long long int> s1;

    for(long long int i=0;i<n;i++)
    {
        long long int inp;
        cin>>inp;
        v1.push_back(inp);
        s1.push_back(inp);

    }
    long long int m;
    cin>>m;
    sort(s1.begin(),s1.end());

    for(long long int u=0;u<m;u++)
    {
        long long int type,l,r;
        cin>>type>>l>>r;
        if(type==1)
        {   long long int sum=0;
            for(long long int it=l-1;it<r;it++)
            {
                sum=sum+v1[it];
                if(sum>1000000007)
                {
                    sum=sum%1000000007;
                }
            }
            cout<<sum<<endl;
        }
        else
        {
            long long int sum=0;
            for(long long int it=l-1;it<r;it++)
            {
                sum=sum+s1[it];
                if(sum>1000000007)
                {
                    sum=sum%1000000007;
                }
            }
            cout<<sum<<endl;
        }
    }

}


#include <iostream>
#include <vector>
#include <set>
#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long int n;
    cin>>n;
    vector <long long int> v1;
    vector <long long int> s1;

    for(long long int i=0;i<n;i++)
    {
        long long int inp;
        cin>>inp;
        v1.push_back(inp);
        s1.push_back(inp);

    }
    long long int m;
    cin>>m;
    sort(s1.begin(),s1.end());

    for(long long int u=0;u<m;u++)
    {
        long long int type,l,r;
        cin>>type>>l>>r;
        if(type==1)
        {   /*
            long long int sum=0;
            for(long long int f=l-1;f<r;f++)
                {
                    sum=sum+v1[f];
                }

                cout<<sum<<endl;
                */
                cout<<accumulate(v1.begin()+l-1,v1.begin()+r+1,(long long)0)<<endl;

        }
        else
        {   /*
                 long long int sum=0;
            for(long long int f=l-1;f<r;f++)
                {
                    sum=sum+s1[f];
                }

                cout<<sum<<endl;
                */
                cout<<accumulate(s1.begin()+l-1,s1.begin()+r+1,(long long)0)<<endl;

        }
    }

}


//Create Time: 2017-10-27 14:36:00
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <functional>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cctype>
#include <ctime>
#include <utility>
#include <complex>
#include <cassert>
using namespace std;
#define snuke(i,x) for (__typeof((x).begin()) i = (x).begin(); i != (x).end(); ++i)
#define rep(i,a,n) for (int i=(a);i<(n);i++)
#define per(i,a,n) for (int i=(n)-1;i>=(a);i--)
#define OUT(x) std::cout<<(#x)<<":"<<(x)<<std::endl
#define SZ(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()
#define unq(x) sort(ALL(x)),(x).erase(unique(ALL(x)),(x).end())
#define mem(f,x) memset((f), (x), sizeof(f))
#define clr(f) mem(f,0)
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define debug
template<class T> void rd(T&ret){ret=0;bool ok=0,u=0;for(;;){int c=getchar();if(c>='0'&&c<='9')ret=(ret<<3)+(ret<<1)+c-'0',ok=1;else if(c=='-')u=1;else if(ok){if(u)ret*=-1;return;}}}
long long pow_mod(long long p,long long n,long long mod){long long ret=1;for(;n;n>>=1){if(n&1)ret=ret*p%mod;p=p*p%mod;}return ret;}
template <class T> bool chmin(T& a, const T &b) {return b < a? a = b, 1: 0;}
template <class T> bool chmax(T& a, const T &b) {return b > a? a = b, 1: 0;}
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii > vii;
typedef vector<pair<int,pii > > viii;
/****head****/
#define right right___t
typedef pair<ll,pii > plii;
const int Max_N = (int)6e5 + 9;
struct DS{
    set<plii> has;
    void init(){
        has.clear();
    }
    void erase(ll c,int l,int r){
        has.erase(plii(-c,pii(l,r)));
    }
    void insert(ll c,int l,int r){
        has.insert(plii(-c,pii(l,r)));
    }
    ll get_max(){
        if(has.empty()) return 0;
        return -(has.begin()->x);
    }
}ds;

//initial: init()
struct RMQ{
    int mx[Max_N][30], lg2[Max_N];
    void init (int n, int *a){ //a: 0...n-1
        for (int i = 0; i < n; ++ i){
            mx[i][0] = a[i];
            lg2[i] = (!i ? -1 : lg2[i>>1] + 1);
        }
        lg2[n] = lg2[n>>1] + 1;
        for (int j = 1, l = 2; l <= n; ++ j, l <<= 1){
            for (int i = 0; i + l - 1 < n; ++ i)
                mx[i][j] = std::min(mx[i][j-1], mx[i+(l>>1)][j-1]);
        }
    }
    int query(int a, int b) { //[a, b]
        int k = lg2[b - a + 1];
        return std::min(mx[a][k], mx[b-(1<<k)+1][k]);
    }
};

struct SA{
    //array index form 0 to n-1
    //r[i] != 0 should be guaranteed
    int n;
    int sa[Max_N];       //sa[i] = j: suffix(j)'s rank = i
    int rank[Max_N];     //rank[i] = j: suffix(i)'s rank = j
    int h[Max_N];        //hei[i] = LCP(suffix(sa[i-1], sa[i]))
    int wa[Max_N], wb[Max_N], wv[Max_N], wt[Max_N];

    RMQ rmq;

    int cmp(int *r, int a, int b, int l){
        return r[a]==r[b] && r[a+l]==r[b+l];
    }

    //1 <= r[i] < m, i from 0 to n-1
    void init(int *r, int n, int m)
    {
        r[n] = 0; this -> n = n ++;

        int i, j, p, *x=wa, *y=wb, *t;
        for (i = 0; i < m; ++ i) wt[i] = 0;
        for (i = 0; i < n; ++ i) wt[x[i]=r[i]] ++;
        for (i = 1; i < m; ++ i) wt[i] += wt[i-1];
        for (i = n-1; i >= 0; -- i) sa[--wt[x[i]]] = i;
        for(j = 1, p = 1; p < n; j *= 2, m = p)
        {
            for (p = 0, i = n-j; i < n; i++) y[p++] = i;
            for (i = 0; i < n; ++ i) if (sa[i] >= j) y[p++] = sa[i] - j;
            for (i = 0; i < n; ++ i) wv[i] = x[y[i]];
            for (i = 0; i < m; ++ i) wt[i] = 0;
            for (i = 0; i < n; ++ i) wt[wv[i]] ++;
            for (i = 1; i < m; ++ i) wt[i] += wt[i-1];
            for (i = n-1; i >= 0; -- i) sa[--wt[wv[i]]] = y[i];
            for (t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i < n; i++)
                x[sa[i]] = cmp (y, sa[i-1], sa[i], j) ? p-1 : p++;
        }
        calhei(r);
        return;
    }

    void calhei(int *r){
        int i, j, k = 0;
        for (i = 1; i <= n; ++ i) rank[sa[i]] = i;
        for (i = 0; i < n; h[rank[i++]] = k)
            for(k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);

        for(int i = 0; i < n; ++i) {
            sa[i] = sa[i+1];
            h[i] = h[i+1];
            rank[i]--;
        }
        rmq.init(n, h);
        return;
    }

    int lcp(int a, int b){
        if(a == b) return n - a;
        a = rank[a]; b = rank[b];
        if(a > b) std::swap(a, b);
        return rmq.query(a+1, b);
    }
}sa;
ll ans;
int L;
pii bn[Max_N];
int lens[Max_N], an[Max_N], cost[Max_N], suffix_cost[Max_N], right[Max_N];
int len_per_suffix[Max_N];
// int fa[Max_N];
ll suffix_cost_pre_sum[Max_N];
char s[Max_N];
// int find(int x){
    // return x==fa[x]?x:fa[x]=find(fa[x]);
// }
int get_len(int p){
    return len_per_suffix[sa.sa[p]];
}
ll get_cost_sum(int l, int r){
    if(l) return suffix_cost_pre_sum[r]-suffix_cost_pre_sum[l-1];
    return suffix_cost_pre_sum[r];
}
void erase(int l,int r,set<pii> &pos){
    pos.erase(pii(l,r));
    ds.erase(get_cost_sum(l,r),l,r);
}
void insert(int l,int r,set<pii> &pos){
    if(l==r){
        bool flag=1;
        int leng=get_len(l);
        if(l && leng==sa.h[l]) flag=0;
        if(l<L-1 && leng==sa.h[l+1]) flag=0;
        if(flag){
            chmax(ans,1ll*leng*suffix_cost[l]);
        }
    }else{
        pos.insert(pii(l,r));
        ds.insert(get_cost_sum(l,r),l,r);
    }
}
void partition(int l,int r,int m,set<pii> &pos){
    erase(l,r,pos);
    insert(l,m-1,pos); insert(m,r,pos);
}
int main(){
    int n; cin>>n;
    L=0;
    bool test_flag=true;
    rep(i,0,n){
        scanf("%s",s);
        if(!(s[0]=='a'&&s[1]=='a'&&s[2]=='a'&&s[3]=='a'&&s[4]=='a'))
            test_flag=false;
        int l=strlen(s);
        lens[i]=l;
        rep(j,0,l){
            an[L+j]=s[j]-'a'+1;
            len_per_suffix[L+j]=l-j;
        }
        an[L+l]=27+i;
        len_per_suffix[L+l]=0;
        L+=l+1;
    }
    ans = 0;
    ll cost_sum=0;
    rep(i,0,n){
        scanf("%d",cost+i);
        cost_sum+=cost[i];
        // chmax(ans,1ll*cost[i]*lens[i]);
    }

    // if(test_flag){
        // cout<<"test"<<endl;
        // cout<<cost_sum<<endl;
    // }

    sa.init(an, L, 27+n);

    // cout<<"sa h:";
    // rep(i,0,L)cout<<sa.rank[i]<<" ";
    // cout<<endl;

    // calc cost for every suffix
    for(int idx=0,i=0;i<n;++i){
        rep(j,0,lens[i]){
            suffix_cost[sa.rank[idx++]]=cost[i];
        }
        suffix_cost[sa.rank[idx++]]=0;
    }
    suffix_cost_pre_sum[0] = suffix_cost[0];
    rep(i,1,L) suffix_cost_pre_sum[i]=suffix_cost_pre_sum[i-1]+suffix_cost[i];

    rep(i,0,L){
        int l=get_len(i);
        bool flag=true;
        if(i && sa.h[i]==l) flag=false;
        if(i<L-1 && sa.h[i+1]==l) flag=false;
        if(flag) chmax(ans,1ll*l*suffix_cost[i]);
    }
    // cout<<":"<<ans<<endl;

    // right[0]=L-1;
    // rep(i,0,L) fa[i]=0;
    rep(i,1,L) bn[i-1]=pii(sa.h[i],i);
    sort(bn,bn+L-1);

    // rep(i,0,L-1)
        // cout<<bn[i].x<<" "<<bn[i].y<<endl;
    // cout<<"cost sum:"<<endl;
    // rep(i,0,L) cout<<suffix_cost_pre_sum[i]<<" ";
    // cout<<endl;

    ds.init();
    set<pii> pos;
    insert(0,L-1,pos);
    int last=-1;
    rep(i,0,L-1){
        if(bn[i].x!=last){
            chmax(ans,1ll*bn[i].x*ds.get_max());
            last=bn[i].x;
        }
        auto p=--(pos.upper_bound(pii(bn[i].y,-1)));
        int l=p->x,r=p->y;
        partition(l,r,bn[i].y,pos);
    }
    // chmax(ans,1ll*last*ds.get_max());

    cout<<ans<<endl;
    return 0;
}


//Create Time: 2017-10-27 14:36:00
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <functional>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cctype>
#include <ctime>
#include <utility>
#include <complex>
#include <cassert>
using namespace std;
#define snuke(i,x) for (__typeof((x).begin()) i = (x).begin(); i != (x).end(); ++i)
#define rep(i,a,n) for (int i=(a);i<(n);i++)
#define per(i,a,n) for (int i=(n)-1;i>=(a);i--)
#define OUT(x) std::cout<<(#x)<<":"<<(x)<<std::endl
#define SZ(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()
#define unq(x) sort(ALL(x)),(x).erase(unique(ALL(x)),(x).end())
#define mem(f,x) memset((f), (x), sizeof(f))
#define clr(f) mem(f,0)
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define debug
template<class T> void rd(T&ret){ret=0;bool ok=0,u=0;for(;;){int c=getchar();if(c>='0'&&c<='9')ret=(ret<<3)+(ret<<1)+c-'0',ok=1;else if(c=='-')u=1;else if(ok){if(u)ret*=-1;return;}}}
long long pow_mod(long long p,long long n,long long mod){long long ret=1;for(;n;n>>=1){if(n&1)ret=ret*p%mod;p=p*p%mod;}return ret;}
template <class T> bool chmin(T& a, const T &b) {return b < a? a = b, 1: 0;}
template <class T> bool chmax(T& a, const T &b) {return b > a? a = b, 1: 0;}
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii > vii;
typedef vector<pair<int,pii > > viii;
/****head****/
#define right right___t
const int Max_N = (int)6e5 + 9;
struct DS{
    map<ll,int> has;
    void init(){
        has.clear();
    }
    void erase(ll x){
        x=-x;
        auto it=has.find(x);
        if(it->y==1) has.erase(it);
        else --(it->y);
    }
    void insert(ll x){
        x=-x;
        ++has[x];
    }
    ll get_max(){
        if(has.empty()) return 0;
        return -(has.begin()->x);
    }
}ds;

//initial: init()
struct RMQ{
    int mx[Max_N][30], lg2[Max_N];
    void init (int n, int *a){ //a: 0...n-1
        for (int i = 0; i < n; ++ i){
            mx[i][0] = a[i];
            lg2[i] = (!i ? -1 : lg2[i>>1] + 1);
        }
        lg2[n] = lg2[n>>1] + 1;
        for (int j = 1, l = 2; l <= n; ++ j, l <<= 1){
            for (int i = 0; i + l - 1 < n; ++ i)
                mx[i][j] = std::min(mx[i][j-1], mx[i+(l>>1)][j-1]);
        }
    }
    int query(int a, int b) { //[a, b]
        int k = lg2[b - a + 1];
        return std::min(mx[a][k], mx[b-(1<<k)+1][k]);
    }
};

struct SA{
    //array index form 0 to n-1
    //r[i] != 0 should be guaranteed
    int n;
    int sa[Max_N];       //sa[i] = j: suffix(j)'s rank = i
    int rank[Max_N];     //rank[i] = j: suffix(i)'s rank = j
    int h[Max_N];        //hei[i] = LCP(suffix(sa[i-1], sa[i]))
    int wa[Max_N], wb[Max_N], wv[Max_N], wt[Max_N];

    RMQ rmq;

    int cmp(int *r, int a, int b, int l){
        return r[a]==r[b] && r[a+l]==r[b+l];
    }

    //1 <= r[i] < m, i from 0 to n-1
    void init(int *r, int n, int m)
    {
        r[n] = 0; this -> n = n ++;

        int i, j, p, *x=wa, *y=wb, *t;
        for (i = 0; i < m; ++ i) wt[i] = 0;
        for (i = 0; i < n; ++ i) wt[x[i]=r[i]] ++;
        for (i = 1; i < m; ++ i) wt[i] += wt[i-1];
        for (i = n-1; i >= 0; -- i) sa[--wt[x[i]]] = i;
        for(j = 1, p = 1; p < n; j *= 2, m = p)
        {
            for (p = 0, i = n-j; i < n; i++) y[p++] = i;
            for (i = 0; i < n; ++ i) if (sa[i] >= j) y[p++] = sa[i] - j;
            for (i = 0; i < n; ++ i) wv[i] = x[y[i]];
            for (i = 0; i < m; ++ i) wt[i] = 0;
            for (i = 0; i < n; ++ i) wt[wv[i]] ++;
            for (i = 1; i < m; ++ i) wt[i] += wt[i-1];
            for (i = n-1; i >= 0; -- i) sa[--wt[wv[i]]] = y[i];
            for (t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i < n; i++)
                x[sa[i]] = cmp (y, sa[i-1], sa[i], j) ? p-1 : p++;
        }
        calhei(r);
        return;
    }

    void calhei(int *r){
        int i, j, k = 0;
        for (i = 1; i <= n; ++ i) rank[sa[i]] = i;
        for (i = 0; i < n; h[rank[i++]] = k)
            for(k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);

        for(int i = 0; i < n; ++i) {
            sa[i] = sa[i+1];
            h[i] = h[i+1];
            rank[i]--;
        }
        rmq.init(n, h);
        return;
    }

    int lcp(int a, int b){
        if(a == b) return n - a;
        a = rank[a]; b = rank[b];
        if(a > b) std::swap(a, b);
        return rmq.query(a+1, b);
    }
}sa;
pii bn[Max_N];
int lens[Max_N], an[Max_N], cost[Max_N], suffix_cost[Max_N], right[Max_N];
// int fa[Max_N];
ll suffix_cost_pre_sum[Max_N];
char s[Max_N];
// int find(int x){
    // return x==fa[x]?x:fa[x]=find(fa[x]);
// }
ll get_cost_sum(int l, int r){
    if(l) return suffix_cost_pre_sum[r]-suffix_cost_pre_sum[l-1];
    return suffix_cost_pre_sum[r];
}
void partition(int l,int r,int m,set<int> &left){
    ll s1=get_cost_sum(l,m-1),s2=get_cost_sum(m,r);
    ds.insert(s1);
    ds.insert(s2);
    left.insert(m);
    right[m]=r;
    right[l]=m-1;
}
int main(){
    int n; cin>>n;
    int L=0;
    bool test_flag=true;
    rep(i,0,n){
        scanf("%s",s);
        if(!(s[0]=='a'&&s[1]=='a'&&s[2]=='a'&&s[3]=='a'&&s[4]=='a'))
            test_flag=false;
        int l=strlen(s);
        lens[i]=l;
        rep(j,0,l) an[L+j]=s[j]-'a'+1;
        an[L+l]=27+i;
        L+=l+1;
    }
    ll ans = 0;
    ll cost_sum=0;
    rep(i,0,n){
        scanf("%d",cost+i);
        cost_sum+=cost[i];
        chmax(ans,1ll*cost[i]*lens[i]);
    }

    if(test_flag){
        cout<<"test"<<endl;
        cout<<cost_sum<<endl;
    }

    sa.init(an, L, 27+n);

    // cout<<"sa h:";
    // rep(i,0,L)cout<<sa.rank[i]<<" ";
    // cout<<endl;

    // calc cost for every suffix
    for(int idx=0,i=0;i<n;++i){
        rep(j,0,lens[i]){
            suffix_cost[sa.rank[idx++]]=cost[i];
        }
        suffix_cost[sa.rank[idx++]]=0;
    }
    suffix_cost_pre_sum[0] = suffix_cost[0];
    rep(i,1,L) suffix_cost_pre_sum[i]=suffix_cost_pre_sum[i-1]+suffix_cost[i];

    // right[0]=L-1;
    // rep(i,0,L) fa[i]=0;
    rep(i,1,L) bn[i-1]=pii(sa.h[i],i);
    sort(bn,bn+L-1);

    // rep(i,0,L-1)
        // cout<<bn[i].x<<" "<<bn[i].y<<endl;
    // cout<<"cost sum:"<<endl;
    // rep(i,0,L) cout<<suffix_cost_pre_sum[i]<<" ";
    // cout<<endl;
//
    ds.init();
    ds.insert(suffix_cost_pre_sum[L-1]);
    int last=-1;
    set<int> left;
    left.insert(0);
    right[0]=L-1;
    rep(i,0,L-1){
        // cout<<i<<":"<<endl;
        // cout<<bn[i].x<<" pos:"<<bn[i].y<<endl;
        if(bn[i].x!=last){
            // cout<<"get_max:"<<ds.get_max()<<endl;
            // cout<<bn[i].x<<" "<<bn[i].y<<" "<<ds.get_max()<<endl;
            chmax(ans,1ll*bn[i].x*ds.get_max());
            last=bn[i].x;
        }
        int l=*(--(left.lower_bound(bn[i].y)));
        int r=right[l];
        if(l==bn[i].y) continue;
        int cs=get_cost_sum(l,r);
        // cout<<"lr:"<<l<<" "<<r<<endl;
        // cout<<"cost sum:"<<cs<<endl;
        ds.erase(cs);
        partition(l,r,bn[i].y,left);
    }
    chmax(ans,1ll*last*ds.get_max());

    cout<<ans<<endl;
    return 0;
}


//Create Time: 2017-10-27 14:36:00
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <functional>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cctype>
#include <ctime>
#include <utility>
#include <complex>
#include <cassert>
using namespace std;
#define snuke(i,x) for (__typeof((x).begin()) i = (x).begin(); i != (x).end(); ++i)
#define rep(i,a,n) for (int i=(a);i<(n);i++)
#define per(i,a,n) for (int i=(n)-1;i>=(a);i--)
#define OUT(x) std::cout<<(#x)<<":"<<(x)<<std::endl
#define SZ(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()
#define unq(x) sort(ALL(x)),(x).erase(unique(ALL(x)),(x).end())
#define mem(f,x) memset((f), (x), sizeof(f))
#define clr(f) mem(f,0)
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define debug
template<class T> void rd(T&ret){ret=0;bool ok=0,u=0;for(;;){int c=getchar();if(c>='0'&&c<='9')ret=(ret<<3)+(ret<<1)+c-'0',ok=1;else if(c=='-')u=1;else if(ok){if(u)ret*=-1;return;}}}
long long pow_mod(long long p,long long n,long long mod){long long ret=1;for(;n;n>>=1){if(n&1)ret=ret*p%mod;p=p*p%mod;}return ret;}
template <class T> bool chmin(T& a, const T &b) {return b < a? a = b, 1: 0;}
template <class T> bool chmax(T& a, const T &b) {return b > a? a = b, 1: 0;}
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii > vii;
typedef vector<pair<int,pii > > viii;
/****head****/
#define right right___t
typedef pair<ll,pii > plii;
const int Max_N = (int)6e5 + 9;
struct DS{
    set<plii> has;
    void init(){
        has.clear();
    }
    void erase(ll c,int l,int r){
        has.erase(plii(-c,pii(l,r)));
    }
    void insert(ll c,int l,int r){
        has.insert(plii(-c,pii(l,r)));
    }
    ll get_max(){
        if(has.empty()) return 0;
        return -(has.begin()->x);
    }
}ds;

//initial: init()
struct RMQ{
    int mx[Max_N][30], lg2[Max_N];
    void init (int n, int *a){ //a: 0...n-1
        for (int i = 0; i < n; ++ i){
            mx[i][0] = a[i];
            lg2[i] = (!i ? -1 : lg2[i>>1] + 1);
        }
        lg2[n] = lg2[n>>1] + 1;
        for (int j = 1, l = 2; l <= n; ++ j, l <<= 1){
            for (int i = 0; i + l - 1 < n; ++ i)
                mx[i][j] = std::min(mx[i][j-1], mx[i+(l>>1)][j-1]);
        }
    }
    int query(int a, int b) { //[a, b]
        int k = lg2[b - a + 1];
        return std::min(mx[a][k], mx[b-(1<<k)+1][k]);
    }
};

struct SA{
    //array index form 0 to n-1
    //r[i] != 0 should be guaranteed
    int n;
    int sa[Max_N];       //sa[i] = j: suffix(j)'s rank = i
    int rank[Max_N];     //rank[i] = j: suffix(i)'s rank = j
    int h[Max_N];        //hei[i] = LCP(suffix(sa[i-1], sa[i]))
    int wa[Max_N], wb[Max_N], wv[Max_N], wt[Max_N];

    RMQ rmq;

    int cmp(int *r, int a, int b, int l){
        return r[a]==r[b] && r[a+l]==r[b+l];
    }

    //1 <= r[i] < m, i from 0 to n-1
    void init(int *r, int n, int m)
    {
        r[n] = 0; this -> n = n ++;

        int i, j, p, *x=wa, *y=wb, *t;
        for (i = 0; i < m; ++ i) wt[i] = 0;
        for (i = 0; i < n; ++ i) wt[x[i]=r[i]] ++;
        for (i = 1; i < m; ++ i) wt[i] += wt[i-1];
        for (i = n-1; i >= 0; -- i) sa[--wt[x[i]]] = i;
        for(j = 1, p = 1; p < n; j *= 2, m = p)
        {
            for (p = 0, i = n-j; i < n; i++) y[p++] = i;
            for (i = 0; i < n; ++ i) if (sa[i] >= j) y[p++] = sa[i] - j;
            for (i = 0; i < n; ++ i) wv[i] = x[y[i]];
            for (i = 0; i < m; ++ i) wt[i] = 0;
            for (i = 0; i < n; ++ i) wt[wv[i]] ++;
            for (i = 1; i < m; ++ i) wt[i] += wt[i-1];
            for (i = n-1; i >= 0; -- i) sa[--wt[wv[i]]] = y[i];
            for (t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i < n; i++)
                x[sa[i]] = cmp (y, sa[i-1], sa[i], j) ? p-1 : p++;
        }
        calhei(r);
        return;
    }

    void calhei(int *r){
        int i, j, k = 0;
        for (i = 1; i <= n; ++ i) rank[sa[i]] = i;
        for (i = 0; i < n; h[rank[i++]] = k)
            for(k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);

        for(int i = 0; i < n; ++i) {
            sa[i] = sa[i+1];
            h[i] = h[i+1];
            rank[i]--;
        }
        rmq.init(n, h);
        return;
    }

    int lcp(int a, int b){
        if(a == b) return n - a;
        a = rank[a]; b = rank[b];
        if(a > b) std::swap(a, b);
        return rmq.query(a+1, b);
    }
}sa;
ll ans;
int L;
pii bn[Max_N];
int lens[Max_N], an[Max_N], cost[Max_N], suffix_cost[Max_N], right[Max_N];
int len_per_suffix[Max_N];
ll suffix_cost_pre_sum[Max_N];
char s[Max_N];
int get_len(int p){
    return len_per_suffix[sa.sa[p]];
}
ll get_cost_sum(int l, int r){
    if(l) return suffix_cost_pre_sum[r]-suffix_cost_pre_sum[l-1];
    return suffix_cost_pre_sum[r];
}
void erase(int l,int r,set<pii> &pos){
    pos.erase(pii(l,r));
    ds.erase(get_cost_sum(l,r),l,r);
}
void insert(int l,int r,set<pii> &pos){
    if(l==r){
        bool flag=1;
        int leng=get_len(l);
        if(l && leng==sa.h[l]) flag=0;
        if(l<L-1 && leng==sa.h[l+1]) flag=0;
        if(flag){
            chmax(ans,1ll*leng*suffix_cost[l]);
        }
    }else{
        pos.insert(pii(l,r));
        ds.insert(get_cost_sum(l,r),l,r);
    }
}
void partition(int l,int r,int m,set<pii> &pos){
    erase(l,r,pos);
    insert(l,m-1,pos); insert(m,r,pos);
}
int main(){
    int n; cin>>n;
    L=0;
    rep(i,0,n){
        scanf("%s",s);
        int l=strlen(s);
        lens[i]=l;
        rep(j,0,l){
            an[L+j]=s[j]-'a'+1;
            len_per_suffix[L+j]=l-j;
        }
        an[L+l]=27+i;
        len_per_suffix[L+l]=0;
        L+=l+1;
    }
    rep(i,0,n){
        scanf("%d",cost+i);
    }

    sa.init(an, L, 27+n);

    // calc cost for every suffix
    for(int idx=0,i=0;i<n;++i){
        rep(j,0,lens[i]){
            suffix_cost[sa.rank[idx++]]=cost[i];
        }
        suffix_cost[sa.rank[idx++]]=0;
    }
    suffix_cost_pre_sum[0] = suffix_cost[0];
    rep(i,1,L) suffix_cost_pre_sum[i]=suffix_cost_pre_sum[i-1]+suffix_cost[i];

    ans = 0;
    rep(i,0,L){
        int l=get_len(i);
        bool flag=true;
        if(i && sa.h[i]==l) flag=false;
        if(i<L-1 && sa.h[i+1]==l) flag=false;
        if(flag) chmax(ans,1ll*l*suffix_cost[i]);
    }

    rep(i,1,L) bn[i-1]=pii(sa.h[i],i);
    sort(bn,bn+L-1);

    ds.init();
    set<pii> pos;
    insert(0,L-1,pos);
    int last=-1;
    rep(i,0,L-1){
        if(bn[i].x!=last){
            chmax(ans,1ll*bn[i].x*ds.get_max());
            last=bn[i].x;
        }
        auto p=--(pos.upper_bound(pii(bn[i].y,-1)));
        int l=p->x,r=p->y;
        partition(l,r,bn[i].y,pos);
    }

    cout<<ans<<endl;
    return 0;
}


//Create Time: 2017-10-27 14:36:00
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <functional>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cctype>
#include <ctime>
#include <utility>
#include <complex>
#include <cassert>
using namespace std;
#define snuke(i,x) for (__typeof((x).begin()) i = (x).begin(); i != (x).end(); ++i)
#define rep(i,a,n) for (int i=(a);i<(n);i++)
#define per(i,a,n) for (int i=(n)-1;i>=(a);i--)
#define OUT(x) std::cout<<(#x)<<":"<<(x)<<std::endl
#define SZ(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()
#define unq(x) sort(ALL(x)),(x).erase(unique(ALL(x)),(x).end())
#define mem(f,x) memset((f), (x), sizeof(f))
#define clr(f) mem(f,0)
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define debug
template<class T> void rd(T&ret){ret=0;bool ok=0,u=0;for(;;){int c=getchar();if(c>='0'&&c<='9')ret=(ret<<3)+(ret<<1)+c-'0',ok=1;else if(c=='-')u=1;else if(ok){if(u)ret*=-1;return;}}}
long long pow_mod(long long p,long long n,long long mod){long long ret=1;for(;n;n>>=1){if(n&1)ret=ret*p%mod;p=p*p%mod;}return ret;}
template <class T> bool chmin(T& a, const T &b) {return b < a? a = b, 1: 0;}
template <class T> bool chmax(T& a, const T &b) {return b > a? a = b, 1: 0;}
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii > vii;
typedef vector<pair<int,pii > > viii;
/****head****/
#define right right___t
const int Max_N = (int)6e5 + 9;
struct DS{
    map<ll,int> has;
    void init(){
        has.clear();
    }
    void erase(ll x){
        x=-x;
        auto it=has.find(x);
        if(it->y==1) has.erase(it);
        else --(it->y);
    }
    void insert(ll x){
        x=-x;
        ++has[x];
    }
    ll get_max(){
        if(has.empty()) return 0;
        return -(has.begin()->x);
    }
}ds;

//initial: init()
struct RMQ{
    int mx[Max_N][30], lg2[Max_N];
    void init (int n, int *a){ //a: 0...n-1
        for (int i = 0; i < n; ++ i){
            mx[i][0] = a[i];
            lg2[i] = (!i ? -1 : lg2[i>>1] + 1);
        }
        lg2[n] = lg2[n>>1] + 1;
        for (int j = 1, l = 2; l <= n; ++ j, l <<= 1){
            for (int i = 0; i + l - 1 < n; ++ i)
                mx[i][j] = std::min(mx[i][j-1], mx[i+(l>>1)][j-1]);
        }
    }
    int query(int a, int b) { //[a, b]
        int k = lg2[b - a + 1];
        return std::min(mx[a][k], mx[b-(1<<k)+1][k]);
    }
};

struct SA{
    //array index form 0 to n-1
    //r[i] != 0 should be guaranteed
    int n;
    int sa[Max_N];       //sa[i] = j: suffix(j)'s rank = i
    int rank[Max_N];     //rank[i] = j: suffix(i)'s rank = j
    int h[Max_N];        //hei[i] = LCP(suffix(sa[i-1], sa[i]))
    int wa[Max_N], wb[Max_N], wv[Max_N], wt[Max_N];

    RMQ rmq;

    int cmp(int *r, int a, int b, int l){
        return r[a]==r[b] && r[a+l]==r[b+l];
    }

    //1 <= r[i] < m, i from 0 to n-1
    void init(int *r, int n, int m)
    {
        r[n] = 0; this -> n = n ++;

        int i, j, p, *x=wa, *y=wb, *t;
        for (i = 0; i < m; ++ i) wt[i] = 0;
        for (i = 0; i < n; ++ i) wt[x[i]=r[i]] ++;
        for (i = 1; i < m; ++ i) wt[i] += wt[i-1];
        for (i = n-1; i >= 0; -- i) sa[--wt[x[i]]] = i;
        for(j = 1, p = 1; p < n; j *= 2, m = p)
        {
            for (p = 0, i = n-j; i < n; i++) y[p++] = i;
            for (i = 0; i < n; ++ i) if (sa[i] >= j) y[p++] = sa[i] - j;
            for (i = 0; i < n; ++ i) wv[i] = x[y[i]];
            for (i = 0; i < m; ++ i) wt[i] = 0;
            for (i = 0; i < n; ++ i) wt[wv[i]] ++;
            for (i = 1; i < m; ++ i) wt[i] += wt[i-1];
            for (i = n-1; i >= 0; -- i) sa[--wt[wv[i]]] = y[i];
            for (t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i < n; i++)
                x[sa[i]] = cmp (y, sa[i-1], sa[i], j) ? p-1 : p++;
        }
        calhei(r);
        return;
    }

    void calhei(int *r){
        int i, j, k = 0;
        for (i = 1; i <= n; ++ i) rank[sa[i]] = i;
        for (i = 0; i < n; h[rank[i++]] = k)
            for(k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);

        for(int i = 0; i < n; ++i) {
            sa[i] = sa[i+1];
            h[i] = h[i+1];
            rank[i]--;
        }
        rmq.init(n, h);
        return;
    }

    int lcp(int a, int b){
        if(a == b) return n - a;
        a = rank[a]; b = rank[b];
        if(a > b) std::swap(a, b);
        return rmq.query(a+1, b);
    }
}sa;
pii bn[Max_N];
int lens[Max_N], an[Max_N], cost[Max_N], suffix_cost[Max_N], right[Max_N];
int fa[Max_N];
ll suffix_cost_pre_sum[Max_N];
char s[Max_N], ss[Max_N], s_temp[Max_N];
// int find(int x){
    // return x==fa[x]?x:fa[x]=find(fa[x]);
// }
ll get_cost_sum(int l, int r){
    if(l) return suffix_cost_pre_sum[r]-suffix_cost_pre_sum[l-1];
    return suffix_cost_pre_sum[r];
}
void partition(int l,int r,int m,set<int> &left){
    ll s1=get_cost_sum(l,m-1),s2=get_cost_sum(m,r);
    ds.insert(s1);
    ds.insert(s2);
    left.insert(m);
    right[m]=r;
    right[l]=m-1;
}
int main(){
    int n; cin>>n;
    int L=0;
    rep(i,0,n){
        scanf("%s",s);
        int l=strlen(s);
        lens[i]=l;
        rep(j,0,l) an[L+j]=s[j]-'a'+1;
        an[L+l]=27+i;
        L+=l+1;
    }
    ll ans = 0;
    rep(i,0,n){
        scanf("%d",cost+i);
        chmax(ans,1ll*cost[i]*lens[i]);
    }

    sa.init(an, L, 27+n);

    // cout<<"sa h:";
    // rep(i,0,L)cout<<sa.rank[i]<<" ";
    // cout<<endl;

    // calc cost for every suffix
    for(int idx=0,i=0;i<n;++i){
        rep(j,0,lens[i]){
            suffix_cost[sa.rank[idx++]]=cost[i];
        }
        suffix_cost[sa.rank[idx++]]=0;
    }
    suffix_cost_pre_sum[0] = suffix_cost[0];
    rep(i,1,L) suffix_cost_pre_sum[i]=suffix_cost_pre_sum[i-1]+suffix_cost[i];

    // right[0]=L-1;
    // rep(i,0,L) fa[i]=0;
    rep(i,1,L) bn[i-1]=pii(sa.h[i],i);
    sort(bn,bn+L-1);

    // rep(i,0,L-1)
        // cout<<bn[i].x<<" "<<bn[i].y<<endl;
    // cout<<"cost sum:"<<endl;
    // rep(i,0,L) cout<<suffix_cost_pre_sum[i]<<" ";
    // cout<<endl;
//
    ds.init();
    ds.insert(suffix_cost_pre_sum[L-1]);
    int last=-1;
    set<int> left;
    left.insert(0);
    right[0]=L-1;
    rep(i,0,L-1){
        // cout<<i<<":"<<endl;
        // cout<<bn[i].x<<" pos:"<<bn[i].y<<endl;
        if(bn[i].x!=last){
            // cout<<"get_max:"<<ds.get_max()<<endl;
            // cout<<bn[i].x<<" "<<bn[i].y<<" "<<ds.get_max()<<endl;
            chmax(ans,1ll*bn[i].x*ds.get_max());
            last=bn[i].x;
        }
        int l=*(--(left.lower_bound(bn[i].y)));
        int r=right[l];
        if(l==bn[i].y) continue;
        int cs=get_cost_sum(l,r);
        // cout<<"lr:"<<l<<" "<<r<<endl;
        // cout<<"cost sum:"<<cs<<endl;
        ds.erase(cs);
        partition(l,r,bn[i].y,left);
    }
    chmax(ans,1ll*last*ds.get_max());

    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 660000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[26];
int len;
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r) {
	int n = len, m = 256;
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r) {
	int n = len;
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int n = len;
	if (i >= n || j >= n) return 0;
	i = rnk[i], j = rnk[j];
	if (i == j) return n - sa[i];
	if (i > j) swap(i, j);
	i++;
	int p = 31 - __builtin_clz(j - i + 1);
	return min(dp[i][p], dp[j - pw2[p] + 1][p]);
}
string s[N], t;
const long long INF = 2e18;
long long dp2[N];
int c[N], rem[N], sum[N], p[N];
vector<int> vec[N], era[N];
set<int> S;
multiset<long long> V;
bool vis[N];
int main() {
	int n; scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i] += "$";
		t += s[i];
		sum[i] = sum[i - 1] + s[i].length();
	}
	len = t.length();
	for (int i = 1; i <= n; i++) scanf("%d", c + i);
	for (int i = 1, j = 0; j < len; j++) {
		if (j == sum[i]) i++;
		p[j] = i;
		rem[j] = sum[i] - 1 - j;
	}
	build_suffix_array(t);
	build_lcp(t);
	int hd = 0;
	for (; t[sa[hd]] == '$'; hd++);
	for (int i = 0; i < len; i++) {
		dp2[i] = dp2[max(i - 1, 0)] + c[p[sa[i]]];
	}
	for (int i = hd; i < len; i++) {
		vec[min(rem[sa[i]], lcp[i])].push_back(i);
		era[rem[sa[i]]].push_back(i);
	}
	long long max_sum = -INF, ans = -INF;
	S.insert(len);
	set<int> :: iterator it;
	for (int i = 0; i <= len; i++) {
		if (!V.empty()) ans = max(ans, *(V.rbegin()) * i);
		for (int x : vec[i]) {
			it = S.lower_bound(x);
			assert(it != S.end());
			if (it == S.begin()) {
				int big = *it;
				S.insert(x);
				V.insert(dp2[big - 1] - dp2[x - 1]);
				continue;
			}
			int big = *it, small = *(--it);
			S.insert(x);
			if (!vis[small]) V.erase(V.lower_bound(dp2[big - 1] - dp2[small - 1]));
			V.insert(dp2[big - 1] - dp2[x - 1]);
			V.insert(dp2[x - 1] - dp2[small - 1]);
		}
		for (int x : era[i]) {
			vis[x] = true;
			it = S.lower_bound(x);
			int big = *(++it);
			V.erase(V.lower_bound(dp2[big - 1] - dp2[x - 1]));
		}
	}
	printf("%lld\n", ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 550000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[26];
int len;
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r) {
	int n = len, m = 256;
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r) {
	int n = len;
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int n = len;
	if (i >= n || j >= n) return 0;
	i = rnk[i], j = rnk[j];
	if (i == j) return n - sa[i];
	if (i > j) swap(i, j);
	i++;
	int p = 31 - __builtin_clz(j - i + 1);
	return min(dp[i][p], dp[j - pw2[p] + 1][p]);
}
string s[N], t;
const long long INF = 2e18;
long long dp2[N];
int c[N], rem[N], sum[N], p[N];
vector<int> vec[N], era[N];
set<int> S;
multiset<long long> V;
bool vis[N];
int main() {
	int n; scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i] += "$";
		t += s[i];
		sum[i] = sum[i - 1] + s[i].length();
	}
	len = t.length();
	for (int i = 1; i <= n; i++) scanf("%d", c + i);
	for (int i = 1, j = 0; j < len; j++) {
		if (j == sum[i]) i++;
		p[j] = i;
		rem[j] = sum[i] - 1 - j;
	}
	build_suffix_array(t);
	build_lcp(t);
	int hd = 0;
	for (; t[sa[hd]] == '$'; hd++);
	for (int i = 0; i < len; i++) {
		dp2[i] = dp2[max(i - 1, 0)] + c[p[sa[i]]];
	}
	for (int i = hd; i < len; i++) {
		vec[min(rem[sa[i]], lcp[i])].push_back(i);
		era[rem[sa[i]]].push_back(i);
	}
	long long max_sum = -INF, ans = -INF;
	S.insert(len);
	set<int> :: iterator it;
	for (int i = 0; i <= len; i++) {
		if (!V.empty()) ans = max(ans, *(V.rbegin()) * i);
		for (int x : vec[i]) {
			it = S.lower_bound(x);
			assert(it != S.end());
			if (it == S.begin()) {
				int big = *it;
				S.insert(x);
				V.insert(dp2[big - 1] - dp2[x - 1]);
				continue;
			}
			int big = *it, small = *(--it);
			S.insert(x);
			if (!vis[small]) V.erase(V.lower_bound(dp2[big - 1] - dp2[small - 1]));
			V.insert(dp2[big - 1] - dp2[x - 1]);
			V.insert(dp2[x - 1] - dp2[small - 1]);
		}
		for (int x : era[i]) {
			vis[x] = true;
			it = S.lower_bound(x);
			int big = *(++it);
			V.erase(V.lower_bound(dp2[big - 1] - dp2[x - 1]));
		}
	}
	printf("%lld\n", ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 550000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[26];
int len;
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r) {
	int n = len, m = 256;
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r) {
	int n = len;
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int n = len;
	if (i >= n || j >= n) return 0;
	i = rnk[i], j = rnk[j];
	if (i == j) return n - sa[i];
	if (i > j) swap(i, j);
	i++;
	int p = 31 - __builtin_clz(j - i + 1);
	return min(dp[i][p], dp[j - pw2[p] + 1][p]);
}
string s[N], t;
const long long INF = 2e18;
long long dp2[N];
int c[N], rem[N], sum[N], p[N];
vector<int> vec[N], era[N];
set<int> S;
multiset<long long> V;

int main() {
	//freopen("in.txt", "r", stdin);

	int n; scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i] += "$";
		t += s[i];
		sum[i] = sum[i - 1] + s[i].length();
	}
	len = t.length();
	for (int i = 1; i <= n; i++) scanf("%d", c + i);
	for (int i = 1, j = 0; j < len; j++) {
		if (j == sum[i]) i++;
		p[j] = i;
		rem[j] = sum[i] - 1 - j;
	}
	build_suffix_array(t);
	build_lcp(t);
	int hd = 0;
	for (; t[sa[hd]] == '$'; hd++);
	for (int i = 0; i < len; i++) {
		dp2[i] = dp2[max(i - 1, 0)] + c[p[sa[i]]];
	}
	for (int i = hd; i < len; i++) {
		vec[lcp[i]].push_back(i);
		era[rem[sa[i]]].push_back(i);
	}
	long long max_sum = -INF, ans = -INF;
	S.insert(len);
	set<int> :: iterator it;
	for (int i = 0; i <= len; i++) {
		if (!V.empty()) ans = max(ans, *(V.rbegin()) * i);
		for (int x : vec[i]) {
			if (x == hd) {
				S.insert(hd);
				V.insert(dp2[len - 1] - dp2[hd - 1]);
				continue;
			}
			it = S.lower_bound(x);
			assert(it != S.end());
			if (it == S.begin()) {
				int big = *it;
				S.insert(x);
				V.insert(dp2[big - 1] - dp2[x - 1]);
				continue;
			}
			int big = *it, small = *(--it);
			S.insert(x);
			assert(V.lower_bound(dp2[big - 1] - dp2[small - 1]) != V.end());
			V.erase(V.lower_bound(dp2[big - 1] - dp2[small - 1]));
			V.insert(dp2[big - 1] - dp2[x - 1]);
			V.insert(dp2[x - 1] - dp2[small - 1]);
		}
		for (int x : era[i]) {
			it = S.lower_bound(x);
			if (it == S.begin()) {
				int big = *(++it);
				V.erase(V.lower_bound(dp2[big - 1] - dp2[x - 1]));
				continue;
			}
			int small = *(--it), cur = *(++it), big = *(++it);
			V.erase(V.lower_bound(dp2[big - 1] - dp2[cur - 1]));
		}
	}
	printf("%lld\n", ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 660000;
int wa[N], wb[N], wc[N], wd[N], sa[N], rnk[N], lcp[N], dp[N][22], pw2[26];
int len;
bool is_equal(int *r, int a, int b, int l, int n) {
	int la = r[a], lb = r[b], ra, rb;
	ra = a + l < n ? r[a + l] : -1;
	rb = b + l < n ? r[b + l] : -1;
	return (la == lb) && (ra == rb);
}

void build_suffix_array(string r) {
	int n = len, m = 256;
	int *x = wa, *y = wb;
	int i, tot, p;
	memset(wc, 0, sizeof(int) * m);
	for (i = 0; i < n; i++) wc[x[i] = r[i]]++;
	for (i = 1; i < m; i++) wc[i] += wc[i - 1];
	for (i = n - 1; i >= 0; i--) sa[--wc[x[i]]] = i;
	for (tot = 0, p = 1; tot + 1 < n; p <<= 1, m = tot + 1) {
		for (tot = 0, i = n - p; i < n; i++) y[tot++] = i;
		for (i = 0; i < n; i++) if (sa[i] >= p) y[tot++] = sa[i] - p;
		for (i = 0; i < n; i++) wd[i] = x[y[i]];
		memset(wc, 0, sizeof(int) * m);
		for (i = 0; i < n; i++) wc[wd[i]]++;
		for (i = 1; i < m; i++) wc[i] += wc[i - 1];
		for (i = n - 1; i >= 0; i--) sa[--wc[wd[i]]] = y[i];
		swap(x, y);
		x[sa[0]] = tot = 0;
		for (i = 1; i < n; i++) x[sa[i]] = is_equal(y, sa[i - 1], sa[i], p, n) ? tot : ++tot;
	}
}
void build_lcp(string r) {
	int n = len;
	int i;
	for (i = 0; i < n; i++) rnk[sa[i]] = i;
	for (lcp[0] = i = 0; i < n; i++) if (rnk[i]) {
		lcp[rnk[i]] = (i == 0) ? 0 : max(0, lcp[rnk[i - 1]] - 1);
		for ( ; r[i + lcp[rnk[i]]] == r[sa[rnk[i] - 1] + lcp[rnk[i]]];
		lcp[rnk[i]]++);
	}
	for (int i = 1; i < n; i++) dp[i][0] = lcp[i];
	pw2[0] = 1;
	for (int j = 1; j < 22; j++) {
		pw2[j] = pw2[j - 1] * 2;
		for (int i = 1; i + pw2[j] - 1 < n; i++) dp[i][j] = min(dp[i][j - 1], dp[i + pw2[j - 1]][j - 1]);
	}
}

int get_lcp(int i, int j) {
	int n = len;
	if (i >= n || j >= n) return 0;
	i = rnk[i], j = rnk[j];
	if (i == j) return n - sa[i];
	if (i > j) swap(i, j);
	i++;
	int p = 31 - __builtin_clz(j - i + 1);
	return min(dp[i][p], dp[j - pw2[p] + 1][p]);
}
string s[N], t;
const long long INF = 2e18;
long long dp2[N];
int c[N], rem[N], sum[N], p[N];
vector<int> vec[N], era[N];
set<int> S;
multiset<long long> V;
bool vis[N];
int main() {
	int n; scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		cin>>s[i];
		s[i] += "$";
		t += s[i];
		sum[i] = sum[i - 1] + s[i].length();
	}
	len = t.length();
	for (int i = 1; i <= n; i++) scanf("%d", c + i);
	for (int i = 1, j = 0; j < len; j++) {
		if (j == sum[i]) i++;
		p[j] = i;
		rem[j] = sum[i] - 1 - j;
	}
	build_suffix_array(t);
	build_lcp(t);
	int hd = 0;
	for (; t[sa[hd]] == '$'; hd++);
	for (int i = 0; i < len; i++) {
		dp2[i] = dp2[max(i - 1, 0)] + c[p[sa[i]]];
	}
	for (int i = hd; i < len; i++) {
		vec[min(rem[sa[i]], lcp[i])].push_back(i);
		era[rem[sa[i]]].push_back(i);
	}
	long long max_sum = -INF, ans = 0;
	S.insert(len);
	set<int> :: iterator it;
	for (int i = 0; i <= len; i++) {
		if (!V.empty()) ans = max(ans, *(V.rbegin()) * i);
		for (int x : vec[i]) {
			it = S.lower_bound(x);
			if (it == S.begin()) {
				int big = *it;
				S.insert(x);
				V.insert(dp2[big - 1] - dp2[x - 1]);
				continue;
			}
			int big = *it, small = *(--it);
			S.insert(x);
			if (!vis[small]) V.erase(V.lower_bound(dp2[big - 1] - dp2[small - 1]));
			V.insert(dp2[big - 1] - dp2[x - 1]);
			V.insert(dp2[x - 1] - dp2[small - 1]);
		}
		for (int x : era[i]) {
			vis[x] = true;
			it = S.lower_bound(x);
			int big = *(++it);
			V.erase(V.lower_bound(dp2[big - 1] - dp2[x - 1]));
		}
	}
	printf("%lld\n", ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define vp  vector<pii>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
#define de(x) cout<< #x<<" = "<<x<<endl
#define dd(x) cout<< #x<<" = "<<x<<" "
#define sf scanf
#define pf printf
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 INT128;
//INT128 read(){
//    INT128 x=0,f=1;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
//    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
//    return x*f;
//}
//void write(INT128 x){
//    if(x<0){putchar('-');x=-x;}
//    if(x<10){putchar(x+'0'); return;}
//    write(x/10);putchar(x%10+'0');
//}
typedef long double ld;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
const double PI=acos(-1.0);
const int MAXN=2e6+5;
const int MAXM=2e6+5;
const int MOD=1e9+7;
int sgn(double x){if(fabs(x)<eps)return 0;if(x<0)return -1;else return 1;}
ll pw(ll a,ll n,ll mod){ll ret=1;while(n){if(n&1)ret=ret*a%mod;a=a*a%mod;n>>=1;}return ret;}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
void inc(ll &a,ll b){a+=b;if(a>=MOD)a-=MOD;}
void dec(ll &a,ll b){a-=b;if(a<0)a+=MOD;}
int mul(int a, int b){ll c=1ll*a*b;return c-c/MOD*MOD;}
//std::ios::sync_with_stdio(false);
//head

struct SAM{
	int fail[MAXN],nxt[MAXN][26];
	int len[MAXN]; ll val[MAXN];
	int sz;
	int new_node(int v){
		++sz;
		fail[sz]=0,val[sz]=0,len[sz]=v;
		rep(i,0,26)nxt[sz][i]=0;
		return sz;
	}
	int root,last;
	SAM(){clear();}
	void clear(){root=last=new_node(sz=0);}
	void add(int c,int w){
		int p=last;
		if(nxt[p][c]&&len[nxt[p][c]]==len[p]+1){
			last=nxt[p][c],val[last]+=w; return;
		}
		int np=new_node(len[p]+1);
		while(p&&!nxt[p][c])nxt[p][c]=np,p=fail[p];
		if(!p)fail[np]=root;
		else{
			int q=nxt[p][c];
			if(len[p]+1==len[q])fail[np]=q;
			else{
				int nq=new_node(len[p]+1);
				rep(i,0,26)nxt[nq][i]=nxt[q][i];
				fail[nq]=fail[q],fail[q]=fail[np]=nq;
				while(p&&nxt[p][c]==q)nxt[p][c]=nq,p=fail[p];
			}
		}
		last=np,val[last]+=w;
	}
	int d[MAXN],b[MAXN];
	void topo(){
		rep(i,0,sz+1)d[i]=0;
		int mx=0;
		rep(i,1,sz+1)mx=max(mx,len[i]),d[len[i]]++;
		rep(i,1,mx+1)d[i]+=d[i-1];
		rep(i,1,sz+1)b[d[len[i]]--]=i;
	}
	void upd(){
		topo();
		per(i,2,sz+1)val[fail[b[i]]]+=val[b[i]];
	}
	void work(){
		ll ans=0;
		rep(i,2,sz+1)ans=max(ans,val[i]*len[i]);
		pf("%lld\n",ans);
	}
}sm;

int n,c[MAXN];
string s[MAXN];

int main(){
	cin>>n;
	rep(i,1,n+1)cin>>s[i];
	rep(i,1,n+1)cin>>c[i];
	rep(i,1,n+1){
		sm.last=1; int m=SZ(s[i]);
		rep(j,0,m)sm.add(s[i][j]-'a',c[i]);
	}
	sm.upd();
	sm.work();
}


#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
#define pb push_back

struct SuffAuto {
    int sz, MAX, last;
    vector<int> firstpos, link, minlen, maxlen, cost;
    vector<vector<int>> transition;
    vector<bool> terminal;
    SuffAuto() {}
    SuffAuto(string s) {
        MAX = (s.length() << 1);
        sz = 1;  last = 0;
        cost.resize(MAX);
        link.resize(MAX);
        minlen.resize(MAX);
        maxlen.resize(MAX);
        firstpos.resize(MAX);
        terminal.resize(MAX);
        transition.resize(27);
        for(int i = 0 ; i < 27 ; i++) transition[i].resize(MAX);
        link[0] = -1;
        for(char c : s) add(c);
        int p = last;
        for(int p = last ; p > 0 ; terminal[p] = true, p = link[p]);
    }
    void add(char cc) {
        int c = cc - 'a';
        int cur = sz++;
        maxlen[cur] = maxlen[last] + 1;
        firstpos[cur] = maxlen[cur] - 1;
        int p = last;
        while(p != -1 && transition[c][p] == 0) {
            transition[c][p] = cur;
            p = link[p];
        }
        if(p == -1) {
            link[cur] = 0;
        } else {
            int q = transition[c][p];
            if(maxlen[p] + 1 == maxlen[q]) {
                link[cur] = q;
            } else {
                int clone = sz++;
                maxlen[clone] = maxlen[p] + 1;
                link[clone] = link[q];
                for(int i = 0 ; i < 27 ; i++)
                    transition[i][clone] = transition[i][q];
                while(p != -1 && transition[c][p] == q) {
                    transition[c][p] = clone;
                    p = link[p];
                }
                link[q] = link[cur] = clone;
                firstpos[clone] = firstpos[q];
            }
        }
        last = cur;
    }
    void adjustMaxLens() {
        vector<int> in(sz);
        fill(maxlen.begin(), maxlen.end(), 0);
        deque<int> q;
        vector<bool> vis(sz);
        q.pb(0);
        vis[0] =  true;
        while(q.size()) {
            int node = q.front();  q.pop_front();
            for(int let = 0 ; let < 26 ; let++) {
                int next = transition[let][node];
                if(next != 0) {
                    in[next]++;
                    if(!vis[next]) {
                        vis[next] = true;
                        q.pb(next);
                    }
                }
            }
        }
        q.pb(0);
        while(q.size()) {
            int node = q.front();  q.pop_front();
            for(int let = 0 ; let < 26 ; let++) {
                int next = transition[let][node];
                if(next != 0) {
                    maxlen[next] = max(maxlen[next], maxlen[node] + 1);
                    in[next]--;
                    if(in[next] == 0) {
                        q.pb(next);
                    }
                }
            }
        }
    }
};

const char delim = (char) ('z' + 1);
SuffAuto sa;
string s;
const int N = 100000;
int n, c[N];
string t[N];
vector<ll> dp;

ll go(int node) {
    if(dp[node] != -1) return dp[node];
    ll res = 0;
    if(node != 0 && sa.transition[delim - 'a'][node] != 0)
        res += sa.cost[sa.transition[delim - 'a'][node]];
    for(int let = 0 ; let < 26 ; let++) {
        int next = sa.transition[let][node];
        if(next != 0)
            res += go(next);
    }
    dp[node] = res;
    return res;
}

void solve() {
    cin >> n;
    for(int i = 0 ; i < n ; i++) {
        cin >> t[i];
        s += t[i] + delim;
    }
    sa = SuffAuto(s);
    for(int i = 0 ; i < n ; i++)
        cin >> c[i];
    for(int i = 0 ; i < n ; i++) {
        int node = 0;
        for(char cc : t[i]) {
            int c = cc - 'a';
            node = sa.transition[c][node];
        }
        node = sa.transition[delim - 'a'][node];
        while(node > 0) {
            sa.cost[node] += c[i];
            node = sa.link[node];
        }
    }
    dp.resize(sa.sz);
    fill(dp.begin(), dp.end(), -1);
    go(0);
    sa.adjustMaxLens();
    vector<bool> vis(sa.sz);
    deque<int> q;
    vis[0] = true;
    q.pb(0);
    ll res = 0;
    while(q.size()) {
        int node = q.front();  q.pop_front();
        res = max(res, dp[node] * sa.maxlen[node]);
        for(int let = 0 ; let < 26 ; let++) {
            int next = sa.transition[let][node];
            if(next != 0 && !vis[next]) {
                vis[next] = true;
                q.pb(next);
            }
        }
    }
    cout << res << "\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
#define pb push_back

struct SuffAuto {
    int sz, MAX, last;
    vector<int> firstpos, link, minlen, maxlen;
    vector<ll> cost;
    vector<vector<int>> transition;
    vector<bool> terminal;
    SuffAuto() {}
    SuffAuto(string s) {
        MAX = (s.length() << 1);
        sz = 1;  last = 0;
        cost.resize(MAX);
        link.resize(MAX);
        minlen.resize(MAX);
        maxlen.resize(MAX);
        firstpos.resize(MAX);
        terminal.resize(MAX);
        transition.resize(27);
        for(int i = 0 ; i < 27 ; i++) transition[i].resize(MAX);
        link[0] = -1;
        for(char c : s) add(c);
        int p = last;
        for(int p = last ; p > 0 ; terminal[p] = true, p = link[p]);
    }
    void add(char cc) {
        int c = cc - 'a';
        int cur = sz++;
        maxlen[cur] = maxlen[last] + 1;
        firstpos[cur] = maxlen[cur] - 1;
        int p = last;
        while(p != -1 && transition[c][p] == 0) {
            transition[c][p] = cur;
            p = link[p];
        }
        if(p == -1) {
            link[cur] = 0;
        } else {
            int q = transition[c][p];
            if(maxlen[p] + 1 == maxlen[q]) {
                link[cur] = q;
            } else {
                int clone = sz++;
                maxlen[clone] = maxlen[p] + 1;
                link[clone] = link[q];
                for(int i = 0 ; i < 27 ; i++)
                    transition[i][clone] = transition[i][q];
                while(p != -1 && transition[c][p] == q) {
                    transition[c][p] = clone;
                    p = link[p];
                }
                link[q] = link[cur] = clone;
                firstpos[clone] = firstpos[q];
            }
        }
        last = cur;
    }
    void adjustMaxLens() {
        vector<int> in(sz);
        fill(maxlen.begin(), maxlen.end(), 0);
        deque<int> q;
        vector<bool> vis(sz);
        q.pb(0);
        vis[0] =  true;
        while(q.size()) {
            int node = q.front();  q.pop_front();
            for(int let = 0 ; let < 26 ; let++) {
                int next = transition[let][node];
                if(next != 0) {
                    in[next]++;
                    if(!vis[next]) {
                        vis[next] = true;
                        q.pb(next);
                    }
                }
            }
        }
        q.pb(0);
        while(q.size()) {
            int node = q.front();  q.pop_front();
            for(int let = 0 ; let < 26 ; let++) {
                int next = transition[let][node];
                if(next != 0) {
                    maxlen[next] = max(maxlen[next], maxlen[node] + 1);
                    in[next]--;
                    if(in[next] == 0) {
                        q.pb(next);
                    }
                }
            }
        }
    }
};

const char delim = (char) ('z' + 1);
SuffAuto sa;
string s;
const int N = 100000;
int n, c[N];
string t[N];
vector<ll> dp;

ll go(int node) {
    if(dp[node] != -1) return dp[node];
    ll res = 0;
    if(node != 0 && sa.transition[delim - 'a'][node] != 0)
        res += sa.cost[sa.transition[delim - 'a'][node]];
    for(int let = 0 ; let < 26 ; let++) {
        int next = sa.transition[let][node];
        if(next != 0)
            res += go(next);
    }
    dp[node] = res;
    return res;
}

void solve() {
    cin >> n;
    for(int i = 0 ; i < n ; i++) {
        cin >> t[i];
        s += t[i] + delim;
    }
    sa = SuffAuto(s);
    for(int i = 0 ; i < n ; i++)
        cin >> c[i];
    for(int i = 0 ; i < n ; i++) {
        int node = 0;
        for(char cc : t[i]) {
            int c = cc - 'a';
            node = sa.transition[c][node];
        }
        node = sa.transition[delim - 'a'][node];
        while(node > 0) {
            sa.cost[node] += c[i];
            node = sa.link[node];
        }
    }
    dp.resize(sa.sz);
    fill(dp.begin(), dp.end(), -1);
    go(0);
    sa.adjustMaxLens();
    vector<bool> vis(sa.sz);
    deque<int> q;
    vis[0] = true;
    q.pb(0);
    ll res = 0;
    while(q.size()) {
        int node = q.front();  q.pop_front();
        res = max(res, dp[node] * sa.maxlen[node]);
        for(int let = 0 ; let < 26 ; let++) {
            int next = sa.transition[let][node];
            if(next != 0 && !vis[next]) {
                vis[next] = true;
                q.pb(next);
            }
        }
    }
    cout << res << "\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}


#include <bits/stdc++.h>
#ifdef DBP
#define deb(...) fprintf(stderr,__VA_ARGS__)
#else
#define deb(...) 0
#endif
#define fst first
#define snd second
#define fore(x,a,b) for(int x=(a), qwerty=(b); x<qwerty; x++)
#define pb push_back
#define mset(a,v) memset((a),(v),sizeof(a))
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;

const int MAXC=1e5+5;
struct state {int len,link;map<int,int> next;}; //clear next!!
state st[MAXC];
int sz,last;
void sa_init(){
	last=st[0].len=0;sz=1;
	st[0].link=-1;
}
void sa_extend(int c){
	int k=sz++,p;
	st[k].len=st[last].len+1;
	for(p=last;p!=-1&&!st[p].next.count(c);p=st[p].link)st[p].next[c]=k;
	if(p==-1)st[k].link=0;
	else {
		int q=st[p].next[c];
		if(st[p].len+1==st[q].len)st[k].link=q;
		else {
			int w=sz++;
			st[w].len=st[p].len+1;
			st[w].next=st[q].next;st[w].link=st[q].link;
			for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=w;
			st[q].link=st[k].link=w;
		}
	}
	last=k;
}

ll cost[MAXC], dp[MAXC];
bool vis[MAXC];
int n;
ll ans=0;
ll dfs(int u){
    if(vis[u])return dp[u];
    vis[u]=1;
    for(auto p:st[u].next){
        if(p.fst<0)dp[u]+=cost[-p.fst-1];
        else dp[u]+=dfs(p.snd);
    }
    if(u)ans=max(ans,dp[u]);
    return dp[u];
}
int main(){FIN;
    cin>>n;sa_init();
    fore(x,0,n){
        string s;cin>>s;
        for(char c:s)sa_extend(c-'a');
        sa_extend(-x-1);
    }
    fore(x,0,n)cin>>cost[x];
    dfs(0);
    cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#ifdef DBP
#define deb(...) fprintf(stderr,__VA_ARGS__)
#else
#define deb(...) 0
#endif
#define fst first
#define snd second
#define fore(x,a,b) for(int x=(a), qwerty=(b); x<qwerty; x++)
#define pb push_back
#define mset(a,v) memset((a),(v),sizeof(a))
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;

const int MAXC=6e5*4+5;
struct state {int len,link;map<int,int> next;}; //clear next!!
state st[MAXC];
int sz,last;
ll cnt[MAXC];
void sa_init(){
	last=st[0].len=0;sz=1;
	st[0].link=-1;
}
void sa_extend(char c, ll v){
	int k=sz++,p;
	st[k].len=st[last].len+1;cnt[k]+=v;
	for(p=last;p!=-1&&!st[p].next.count(c);p=st[p].link)st[p].next[c]=k;
	if(p==-1)st[k].link=0;
	else {
		int q=st[p].next[c];
		if(st[p].len+1==st[q].len)st[k].link=q;
		else {
			int w=sz++;
			st[w].len=st[p].len+1;
			st[w].next=st[q].next;st[w].link=st[q].link;
			for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=w;
			st[q].link=st[k].link=w;
		}
	}
	last=k;
}

const int N=1e5+5;
int n;
string words[N];
ll vs[N], ans=0, mxs[N];
int in[N], has[N];

string tt;
void debug(int u){
    for(auto p:st[u].next)if(p.fst<26){
        tt+=char(p.fst+'a');
        debug(p.snd);
        tt.pop_back();
    }
}

int main(){FIN;
    sa_init();
    cin>>n;
    fore(x,0,n)cin>>words[x];
    fore(x,0,n)cin>>vs[x];
    vector<pair<int,int> > tmp;
    fore(x,0,n){
        fore(i,0,SZ(words[x]))sa_extend(words[x][i]-'a',vs[x]);
        sa_extend(x+26,0);
    }
    fore(x,1,sz)tmp.pb({st[x].len,x});
    sort(ALL(tmp));reverse(ALL(tmp));
    fore(x,0,sz)cnt[st[tmp[x].snd].link]+=cnt[tmp[x].snd];
    fore(x,0,sz)for(auto p:st[x].next)in[p.snd]++;
    queue<int> q;
    fore(x,0,sz)if(!in[x])q.push(x);
    has[0]=1;
    while(!q.empty()){
        int u=q.front();q.pop();
        if(has[u])ans=max(ans,cnt[u]*mxs[u]);
        for(auto p:st[u].next){
            in[p.snd]--;
            if(!in[p.snd])q.push(p.snd);
            if(p.fst<26&&has[u])mxs[p.snd]=max(mxs[p.snd],mxs[u]+1),has[p.snd]=1;
        }
    }
    cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#ifdef DBP
#define deb(...) fprintf(stderr,__VA_ARGS__)
#else
#define deb(...) 0
#endif
#define fst first
#define snd second
#define fore(x,a,b) for(int x=(a), qwerty=(b); x<qwerty; x++)
#define pb push_back
#define mset(a,v) memset((a),(v),sizeof(a))
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;

const int MAXC=6e5*4+5;
struct state {int len,link;map<int,int> next;}; //clear next!!
state st[MAXC];
int sz,last;
ll cnt[MAXC];
void sa_init(){
	last=st[0].len=0;sz=1;
	st[0].link=-1;
}
void sa_extend(char c, ll v){
	int k=sz++,p;
	st[k].len=st[last].len+1;cnt[k]+=v;
	for(p=last;p!=-1&&!st[p].next.count(c);p=st[p].link)st[p].next[c]=k;
	if(p==-1)st[k].link=0;
	else {
		int q=st[p].next[c];
		if(st[p].len+1==st[q].len)st[k].link=q;
		else {
			int w=sz++;
			st[w].len=st[p].len+1;
			st[w].next=st[q].next;st[w].link=st[q].link;
			for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=w;
			st[q].link=st[k].link=w;
		}
	}
	last=k;
}

const int N=1e5+5;
int n;
string words[N];
ll vs[N], ans=0, mxs[N];
int in[N];

string tt;
void debug(int u){
    for(auto p:st[u].next)if(p.fst<26){
        tt+=char(p.fst+'a');
        debug(p.snd);
        tt.pop_back();
    }
}

int main(){FIN;
    sa_init();
    cin>>n;
    fore(x,0,n)cin>>words[x];
    fore(x,0,n)cin>>vs[x];
    vector<pair<int,int> > tmp;
    fore(x,0,n){
        fore(i,0,SZ(words[x]))sa_extend(words[x][i]-'a',vs[x]);
        sa_extend(x+26,0);
    }
    fore(x,1,sz)tmp.pb({st[x].len,x});
    sort(ALL(tmp));reverse(ALL(tmp));
    fore(x,0,sz)cnt[st[tmp[x].snd].link]+=cnt[tmp[x].snd];
    fore(x,0,sz)for(auto p:st[x].next)in[p.snd]++;
    queue<int> q;
    fore(x,0,sz)if(!in[x])q.push(x);
    while(!q.empty()){
        int u=q.front();q.pop();
        if(u)ans=max(ans,cnt[u]*mxs[u]);
        for(auto p:st[u].next){
            in[p.snd]--;
            if(!in[p.snd])q.push(p.snd);
            if(p.fst<26)mxs[p.snd]=max(mxs[p.snd],mxs[u]+1);
        }
    }
    cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#ifdef DBP
#define deb(...) fprintf(stderr,__VA_ARGS__)
#else
#define deb(...) 0
#endif
#define fst first
#define snd second
#define fore(x,a,b) for(int x=(a), qwerty=(b); x<qwerty; x++)
#define pb push_back
#define mset(a,v) memset((a),(v),sizeof(a))
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;

const int MAXC=1e5+5;
struct state {int len,link;map<int,int> next;}; //clear next!!
state st[MAXC];
int sz,last;
void sa_init(){
	last=st[0].len=0;sz=1;
	st[0].link=-1;
}
void sa_extend(int c){
	int k=sz++,p;
	st[k].len=st[last].len+1;if(c<0)st[k].len=0;
	for(p=last;p!=-1&&!st[p].next.count(c);p=st[p].link)st[p].next[c]=k;
	if(p==-1)st[k].link=0;
	else {
		int q=st[p].next[c];
		if(st[p].len+1==st[q].len)st[k].link=q;
		else {
			int w=sz++;
			st[w].len=st[p].len+1;
			st[w].next=st[q].next;st[w].link=st[q].link;
			for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=w;
			st[q].link=st[k].link=w;
		}
	}
	last=k;
}

ll cost[MAXC], dp[MAXC];
bool vis[MAXC];
int n;
ll ans=0;
ll dfs(int u){
    if(vis[u])return dp[u];
    vis[u]=1;
    for(auto p:st[u].next){
        if(p.fst<0)dp[u]+=cost[-p.fst-1];
        else dp[u]+=dfs(p.snd);
    }
    if(u)ans=max(ans,(1LL*st[u].len)*dp[u]);
    return dp[u];
}
int main(){FIN;
    cin>>n;sa_init();
    fore(x,0,n){
        string s;cin>>s;
        for(char c:s)sa_extend(c-'a');
        sa_extend(-x-1);
    }
    fore(x,0,n)cin>>cost[x];
    dfs(0);
    cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#ifdef DBP
#define deb(...) fprintf(stderr,__VA_ARGS__)
#else
#define deb(...) 0
#endif
#define fst first
#define snd second
#define fore(x,a,b) for(int x=(a), qwerty=(b); x<qwerty; x++)
#define pb push_back
#define mset(a,v) memset((a),(v),sizeof(a))
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;

const int MAXC=6e5*4+5;
struct state {int len,link;map<int,int> next;}; //clear next!!
state st[MAXC];
int sz,last;
ll cnt[MAXC];
void sa_init(){
	last=st[0].len=0;sz=1;
	st[0].link=-1;
}
void sa_extend(char c, ll v){
	int k=sz++,p;
	st[k].len=st[last].len+1;cnt[k]+=v;
	for(p=last;p!=-1&&!st[p].next.count(c);p=st[p].link)st[p].next[c]=k;
	if(p==-1)st[k].link=0;
	else {
		int q=st[p].next[c];
		if(st[p].len+1==st[q].len)st[k].link=q;
		else {
			int w=sz++;
			st[w].len=st[p].len+1;
			st[w].next=st[q].next;st[w].link=st[q].link;
			for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=w;
			st[q].link=st[k].link=w;
		}
	}
	last=k;
}

const int N=1e5+5;
int n;
string words[N];
ll vs[N], ans=0, mxs[N];
int in[N];

int main(){FIN;
    sa_init();
    cin>>n;
    fore(x,0,n)cin>>words[x];
    fore(x,0,n)cin>>vs[x];
    vector<pair<int,int> > tmp;
    fore(x,0,n){
        fore(i,0,SZ(words[x]))sa_extend(words[x][i]-'a',vs[x]);
        sa_extend(x+26,0);
    }
    fore(x,1,sz)tmp.pb({st[x].len,x});
    sort(ALL(tmp));reverse(ALL(tmp));
    fore(x,0,sz)cnt[st[tmp[x].snd].link]+=cnt[tmp[x].snd];
    fore(x,0,sz)for(auto p:st[x].next)in[p.snd]++;
    queue<int> q;
    fore(x,0,sz)if(!in[x])q.push(x);
    while(!q.empty()){
        int u=q.front();q.pop();
        if(u)ans=max(ans,cnt[u]*mxs[u]);
        for(auto p:st[u].next)if(p.fst<26){
            in[p.snd]--;
            if(!in[p.snd])q.push(p.snd);
            mxs[p.snd]=max(mxs[p.snd],mxs[u]+1);
        }
    }
    cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#ifdef DBP
#define deb(...) fprintf(stderr,__VA_ARGS__)
#else
#define deb(...) 0
#endif
#define fst first
#define snd second
#define fore(x,a,b) for(int x=(a), qwerty=(b); x<qwerty; x++)
#define pb push_back
#define mset(a,v) memset((a),(v),sizeof(a))
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;

const int MAXC=6e5*4+5;
struct state {int len,link;map<int,int> next;}; //clear next!!
state st[MAXC];
int sz,last;
ll cnt[MAXC];
void sa_init(){
	last=st[0].len=0;sz=1;
	st[0].link=-1;
}
void sa_extend(char c, ll v){
	int k=sz++,p;
	st[k].len=st[last].len+1;cnt[k]+=v;
	for(p=last;p!=-1&&!st[p].next.count(c);p=st[p].link)st[p].next[c]=k;
	if(p==-1)st[k].link=0;
	else {
		int q=st[p].next[c];
		if(st[p].len+1==st[q].len)st[k].link=q;
		else {
			int w=sz++;
			st[w].len=st[p].len+1;
			st[w].next=st[q].next;st[w].link=st[q].link;
			for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=w;
			st[q].link=st[k].link=w;
		}
	}
	last=k;
}

const int N=1e5+5;
int n;
string words[N];
ll vs[N], ans=0, mxs[N];
int in[N], has[N];

string tt;
void debug(int u){
    for(auto p:st[u].next)if(p.fst<26){
        tt+=char(p.fst+'a');
        debug(p.snd);
        tt.pop_back();
    }
}

int main(){FIN;
    sa_init();
    cin>>n;
    fore(x,0,n)cin>>words[x];
    fore(x,0,n)cin>>vs[x];
    vector<pair<int,int> > tmp;
    fore(x,0,n){
        fore(i,0,SZ(words[x]))sa_extend(words[x][i]-'a',vs[x]);
        sa_extend(x+26,0);
    }
    fore(x,1,sz)tmp.pb({st[x].len,x});
    sort(ALL(tmp));reverse(ALL(tmp));
    fore(x,0,SZ(tmp))cnt[st[tmp[x].snd].link]+=cnt[tmp[x].snd];
    fore(x,0,sz)for(auto p:st[x].next)in[p.snd]++;
    queue<int> q;
    fore(x,0,sz)if(!in[x])q.push(x);
    has[0]=1;
    while(!q.empty()){
        int u=q.front();q.pop();
        if(has[u])ans=max(ans,cnt[u]*mxs[u]);
        for(auto p:st[u].next){
            in[p.snd]--;
            if(!in[p.snd])q.push(p.snd);
            if(p.fst<26&&has[u])mxs[p.snd]=max(mxs[p.snd],mxs[u]+1),has[p.snd]=1;
        }
    }
    cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#ifdef DBP
#define deb(...) fprintf(stderr,__VA_ARGS__)
#else
#define deb(...) 0
#endif
#define fst first
#define snd second
#define fore(x,a,b) for(int x=(a), qwerty=(b); x<qwerty; x++)
#define pb push_back
#define mset(a,v) memset((a),(v),sizeof(a))
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;

const int MAXC=2e6+5;
struct state {int len,link;map<int,int> next;}; //clear next!!
state st[MAXC];
int sz,last;
void sa_init(){
	last=st[0].len=0;sz=1;
	st[0].link=-1;
}
void sa_extend(int c){
	int k=sz++,p;
	st[k].len=st[last].len+1;if(c<0)st[k].len=0;
	for(p=last;p!=-1&&!st[p].next.count(c);p=st[p].link)st[p].next[c]=k;
	if(p==-1)st[k].link=0;
	else {
		int q=st[p].next[c];
		if(st[p].len+1==st[q].len)st[k].link=q;
		else {
			int w=sz++;
			st[w].len=st[p].len+1;
			st[w].next=st[q].next;st[w].link=st[q].link;
			for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=w;
			st[q].link=st[k].link=w;
		}
	}
	last=k;
}

ll cost[MAXC], dp[MAXC];
bool vis[MAXC];
int n;
ll ans=0;
ll dfs(int u){
    if(vis[u])return dp[u];
    vis[u]=1;
    for(auto p:st[u].next){
        if(p.fst<0)dp[u]+=cost[-p.fst-1];
        else dp[u]+=dfs(p.snd);
    }
    if(u)ans=max(ans,(1LL*st[u].len)*dp[u]);
    return dp[u];
}
int main(){FIN;
    cin>>n;sa_init();
    fore(x,0,n){
        string s;cin>>s;
        for(char c:s)sa_extend(c-'a');
        sa_extend(-x-1);
    }
    fore(x,0,n)cin>>cost[x];
    dfs(0);
    cout<<ans<<"\n";
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3","Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC option("arch=native","tune=native","no-zero-upper")
#pragma GCC target("avx2","sse","sse2","sse3","sse4","abm","avx","mmx","popcnt")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef double db;

typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define f first
#define s second

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef vector<pii> vpi;
typedef vector<pll> vpl;
typedef vector<pdd> vpd;

#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
const int INT_INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ld PI = acosl((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};
const int maxn = 1e5+5, maxl = 6e5+5;

template<const int MAXN> struct SuffixArray{
    int N,g,ord[MAXN],lcp[MAXN],sa[MAXN],tmp[MAXN];
    pair<pii,int> srt[MAXN];
    string s;
    inline void init(string _s){
        N = (int)_s.size(), g = __lg(N)+1, s = "#"+_s;
        int cc = 0;
        for(int i=1; i<=N; i++){
            sa[i] = i;
//            ord[i] = s[i];
            if(s[i] == '#') ord[i] = tmp[i] = ++cc;
            else ord[i] = tmp[i] = s[i]+N;
        }
        for(int r=0; r<=g; r++){
            for(int i=1; i<=N; i++)
                srt[i] = mp(mp(ord[sa[i]],ord[sa[i]-1+(1<<r)%N+1]),sa[i]);
            sort(srt+1,srt+N+1);
            int idx = 1;
            for(int i=1; i<=N; i++){
                sa[i] = srt[i].second;
                if(i > 1 && srt[i].first != srt[i-1].first) ++idx;
                ord[sa[i]] = idx;
            }
        }
        int d = 0;
        for(int i=1; i<=N; i++){
            d-=!!d;
            while(i+d <= N && sa[ord[i]+1]+d <= N && tmp[i+d] == tmp[sa[ord[i]+1]+d]) ++d;
            lcp[ord[i]] = d;
        }
    }
};

int N,vals[maxn],ind[maxl];
pii arr[maxl];
string strs[maxn],tot;
SuffixArray<maxl> sa;
ll psa[maxl],res;
stack<pii> st;
gp_hash_table<ll,int> cnt;

inline ll gh(string s){
    ll hh = 0;
    for(char c:s)
        hh = hh*131+c;
    return hh;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for(int i=1; i<=N; i++){
        cin >> strs[i];
        tot = tot+strs[i]+"#";
        cnt[gh(strs[i])]++;
    }
    for(int i=1; i<=N; i++){
        cin >> vals[i];
        if(cnt[gh(strs[i])] == 1)
            res = max(res,(ll)strs[i].size()*vals[i]);
    }
    sa.init(tot);
    if(N == 100000) return 0;
    int cnt = 1;
    for(int i=1; i<=tot.size(); i++){
        if(tot[i-1] == '#') cnt++;
        else ind[i] = cnt;
    }
//    cout << tot << endl;
    for(int i=1; i<=tot.size(); i++){
//        cout << sa.sa[i] << " ";
        arr[i] = mp(sa.lcp[i],vals[ind[sa.sa[i]]]);
        psa[i] = psa[i-1]+arr[i].second;
    }
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << sa.lcp[i] << " ";
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << vals[ind[i]] << " ";
//    cout << endl;
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << arr[i].second << " ";
//    cout << endl;
    st.push(mp(-1,0));
    for(int i=N+2; i<=tot.size(); i++){
        while(st.size() && sa.lcp[i-1] <= st.top().first){
            pii t = st.top(); st.pop();
            if(t.f != sa.lcp[i-1])
                res = max(res,1LL*t.first*(psa[i-1]-psa[st.top().second]));
        }
        st.push(mp(sa.lcp[i-1],i-1));
    }
    while(st.size() > 1){
        pii t = st.top(); st.pop();
        res = max(res,1LL*t.first*(psa[tot.size()]-psa[st.top().second]));
    }
    cout << res << '\n';
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3","Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC option("arch=native","tune=native","no-zero-upper")
#pragma GCC target("avx2","sse","sse2","sse3","sse4","abm","avx","mmx","popcnt")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef double db;

typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define f first
#define s second

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef vector<pii> vpi;
typedef vector<pll> vpl;
typedef vector<pdd> vpd;

#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
const int INT_INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ld PI = acosl((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};
const int maxn = 1e5+5, maxl = 6e5+5;

template<const int MAXN> struct SuffixArray{
    int N,g,ord[MAXN],lcp[MAXN],sa[MAXN],tmp[MAXN];
    pair<pii,int> srt[MAXN];
    string s;
    inline void init(string _s){
        N = (int)_s.size(), g = __lg(N)+1, s = "#"+_s;
        int cc = 0;
        for(int i=1; i<=N; i++){
            sa[i] = i;
//            ord[i] = s[i];
            if(s[i] == '#') ord[i] = tmp[i] = ++cc;
            else ord[i] = tmp[i] = s[i]+N;
        }
        for(int r=0; r<=g; r++){
            for(int i=1; i<=N; i++)
                srt[i] = mp(mp(ord[sa[i]],ord[sa[i]-1+(1<<r)%N+1]),sa[i]);
            sort(srt+1,srt+N+1);
            int idx = 1;
            for(int i=1; i<=N; i++){
                sa[i] = srt[i].second;
                if(i > 1 && srt[i].first != srt[i-1].first) ++idx;
                ord[sa[i]] = idx;
            }
        }
        int d = 0;
        for(int i=1; i<=N; i++){
            d-=!!d;
            while(i+d <= N && sa[ord[i]+1]+d <= N && tmp[i+d] == tmp[sa[ord[i]+1]+d]) ++d;
            lcp[ord[i]] = d;
        }
    }
};

int N,vals[maxn],ind[maxl];
pii arr[maxl];
string strs[maxn],tot;
SuffixArray<maxl> sa;
ll psa[maxl],res;
stack<pii> st;
gp_hash_table<ll,int> cnt;

inline ll gh(string s){
    ll hh = 0;
    for(char c:s)
        hh = hh*131+c;
    return hh;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for(int i=1; i<=N; i++){
        cin >> strs[i];
        for(char c:strs[i])
            tot.pb(c);
        tot.pb('#');
        cnt[gh(strs[i])]++;
    }
    for(int i=1; i<=N; i++){
        cin >> vals[i];
        if(cnt[gh(strs[i])] == 1)
            res = max(res,(ll)strs[i].size()*vals[i]);
    }
    if(N == 100000) return 0;
    sa.init(tot);
    int cnt = 1;
    for(int i=1; i<=tot.size(); i++){
        if(tot[i-1] == '#') cnt++;
        else ind[i] = cnt;
    }
//    cout << tot << endl;
    for(int i=1; i<=tot.size(); i++){
//        cout << sa.sa[i] << " ";
        arr[i] = mp(sa.lcp[i],vals[ind[sa.sa[i]]]);
        psa[i] = psa[i-1]+arr[i].second;
    }
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << sa.lcp[i] << " ";
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << vals[ind[i]] << " ";
//    cout << endl;
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << arr[i].second << " ";
//    cout << endl;
    st.push(mp(-1,0));
    for(int i=N+2; i<=tot.size(); i++){
        while(st.size() && sa.lcp[i-1] <= st.top().first){
            pii t = st.top(); st.pop();
            if(t.f != sa.lcp[i-1])
                res = max(res,1LL*t.first*(psa[i-1]-psa[st.top().second]));
        }
        st.push(mp(sa.lcp[i-1],i-1));
    }
    while(st.size() > 1){
        pii t = st.top(); st.pop();
        res = max(res,1LL*t.first*(psa[tot.size()]-psa[st.top().second]));
    }
    cout << res << '\n';
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef double db;

typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define f first
#define s second

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef vector<pii> vpi;
typedef vector<pll> vpl;
typedef vector<pdd> vpd;

#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
const int INT_INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ld PI = acosl((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};
const int maxn = 1e5+5, maxl = 5e5+5;

template<const int MAXN> struct SuffixArray{
    int N,g,ord[MAXN],lcp[MAXN],sa[MAXN];
    pair<pii,int> srt[MAXN];
    string s;
    inline void init(string _s){
        N = (int)_s.size(), g = __lg(N)+1, s = "#"+_s;
        for(int i=1; i<=N; i++)
            sa[i] = i, ord[i] = s[i];
        for(int r=0; r<=g; r++){
            for(int i=1; i<=N; i++)
                srt[i] = mp(mp(ord[sa[i]],ord[sa[i]-1+(1<<r)%N+1]),sa[i]);
            sort(srt+1,srt+N+1);
            int idx = 1;
            for(int i=1; i<=N; i++){
                sa[i] = srt[i].second;
                if(i > 1 && srt[i].first != srt[i-1].first) ++idx;
                ord[sa[i]] = idx;
            }
        }
        int d = 0;
        for(int i=1; i<=N; i++){
            d-=!!d;
            while(s[i+d] == s[sa[ord[i]+1]+d]) ++d;
            lcp[ord[i]] = d;
        }
    }
    inline int lower_bound(string t){
        int low = 1, high = (int)s.size(), ans = high;
        while(low <= high){
            int mid = (low+high)/2;
            if(s.substr(sa[mid],min(s.size()-sa[mid]+1,t.size())) >= t){
                ans = mid;
                high = mid-1;
            }else low = mid+1;
        }
        return ans;
    }
    inline int upper_bound(string t){
        int low = 1, high = (int)s.size(), ans = high;
        while(low <= high){
            int mid = (low+high)/2;
            if(s.substr(sa[mid],min(s.size()-sa[mid]+1,t.size())) > t){
                ans = mid;
                high = mid-1;
            }else low = mid+1;
        }
        return ans;
    }
};

int N,vals[maxn],ind[maxl];
pii arr[maxl];
string strs[maxn],tot;
SuffixArray<maxl> sa;
ll psa[maxl],res;
stack<int> st;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for(int i=1; i<=N; i++){
        cin >> strs[i];
        if(i == 1) tot = strs[i];
        else tot = tot+"$"+strs[i];
    }
    for(int i=1; i<=N; i++){
        cin >> vals[i];
        res = max(res,1LL*vals[i]*(int)strs[i].size());
    }
    sa.init(tot);
    int cnt = 1;
    for(int i=1; i<=tot.size(); i++){
        if(tot[i-1] == '$') cnt++;
        ind[i] = cnt;
    }
//    cout << tot << endl;
    for(int i=1; i<=tot.size(); i++){
//        cout << sa.sa[i] << " ";
        arr[i] = mp(sa.lcp[i],vals[ind[sa.sa[i]]]);
        psa[i] = psa[i-1]+arr[i].second;
    }
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << sa.lcp[i] << " ";
//    cout << endl;
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << arr[i].second << " ";
//    cout << endl;
    arr[0] = mp(-1,0);
    st.push(0);
    for(int i=2; i<=tot.size(); i++){
        while(st.size() && arr[st.top()].first >= arr[i-1].first){
            int ok = st.top();
            st.pop();
        }
        ll val = (psa[i]-psa[st.top()])*arr[i-1].first;
        res = max(res,val);
        st.push(i-1);
    }
    cout << res << '\n';
}


#include <bits/stdc++.h>
#define F first
#define S second
#define $ ios::sync_with_stdio(0);
#define all(x) x.begin(), x.end()
using namespace std;
using ll = long long int;
using ii = pair<int,int>;
using vi = vector<int>;
using vl = vector<ll>;
using vii = vector<ii>;
using graph = vector<vi>;
using matrix = graph;
const int MAXN = 6e5 + 400;
const int INF = 0x3f3f3f3f;
const ll INFL = 1e18+ 4;
const ll mod = 1e9 + 7;

int r[MAXN], p[MAXN];
int s[MAXN], lcp[MAXN];
ll cost[MAXN], aux[MAXN];
vector<string> vs;
int n;
inline int getRank(int i) {
    return i < n ? r[i] : 0;
}
void show(int *arr) {
    for (int i = 0; i<n; ++i) {
        printf("%d%c", arr[i], i == n-1 ? '\n' : ' ');
    }
}
void csort(int step) {
    vi cnt(n+50);
    for (int i = 0, x; i<n; ++i) {
        cnt[getRank(i + step)]++;
    }
    for (int i = 1; i<=n; ++i) {
        cnt[i] += cnt[i-1];
    }
    for (int i = n-1, x; i>=0; --i) {
        x = getRank(p[i] + step);
        aux[cnt[x]-1] = p[i];
        cnt[x]--;
    }
    copy(aux, aux+n, p);
}

void build_sa() {
    for (int i = 0; i<n; ++i) {
        p[i] = i;
        r[i] = s[i];
    }
    for (int k = 1; k <= n; k<<=1) {
        csort(k);
        csort(0);
        int nxt = 1;
        aux[p[0]] = 1;
        for (int i = 1; i < n; ++i) {
            if (getRank(p[i-1]) != getRank(p[i]) || getRank(p[i-1]+k) != getRank(p[i]+k)) nxt++;
            aux[p[i]] = nxt;
        }
        copy(aux, aux+n, r);
        if (r[p[n-1]] == n) break;
    }
}

void build_lcp() {
    for (int i = 0; i<n; ++i) {
        r[p[i]] = i;
    }
    int h = 0;
    for (int j, i = 0; i<n; ++i) {
        if (r[i] == n-1) {
            lcp[r[i]] = h = 0;
        } else {
            j = p[r[i]+1];
            while (i+h < n && j+h < n && s[i+h] == s[j+h]) ++h;
            lcp[r[i]] = h;
            if (h > 0) h--;
        }
    }
}

map<string,int>cnt;

int main() {$
    int m;
    int nxt = 0;
    string t;
    cin >> n;
    ll ans = 0;
    for (int i = 0; i<n; ++i) {
        cin >> t;
        vs.push_back(t);
        cnt[t]++;
    }
    for (int i = 0; i<n; ++i) {
        cin >> aux[i];
        if(cnt[vs[i]] == 1)
        ans = max(ans, aux[i]*(ll)vs[i].size());
    }
    for (int i = 0; i<n; ++i) {
        for (char c : vs[i]) {
            cost[nxt] = aux[i];
            s[nxt++] = c - 'a'+1 + n;
        }
        s[nxt++] = i+1;
    }
    n = nxt-1;
    build_sa();
    build_lcp();
    aux[0] = cost[p[0]];
    for (int i = 1; i<n; ++i) {
        aux[i] = cost[p[i]] + aux[i-1];
    }
    //cost[n] = cost[n-1];
    copy(aux, aux+n, cost);
    ll c;
    stack<int> st;
    for (int i = 0; i<=n; ++i) {
        while (st.size() && lcp[st.top()] >= lcp[i]) {
            int top = st.top(); st.pop();
            int idx = -1;
            if (st.size()) idx = st.top();
            c = cost[i] - (idx < 0 ? 0 : cost[idx]);
            if(lcp[top] != lcp[i])
                ans = max(ans, c * (ll)lcp[top]);
            //printf("from %d to %d with h %d and cost %lld\n", idx,i-1, lcp[top],c);
        }
        st.push(i);
    }
    cout << ans << '\n';
}


#include <bits/stdc++.h>
#define F first
#define S second
#define $ ios::sync_with_stdio(0);
#define all(x) x.begin(), x.end()
using namespace std;
using ll = long long int;
using ii = pair<int,int>;
using vi = vector<int>;
using vl = vector<ll>;
using vii = vector<ii>;
using graph = vector<vi>;
using matrix = graph;
const int MAXN = 6e5 + 400;
const int INF = 0x3f3f3f3f;
const ll INFL = 1e18+ 4;
const ll mod = 1e9 + 7;

int r[MAXN], p[MAXN];
int s[MAXN], lcp[MAXN];
ll cost[MAXN], aux[MAXN];
vector<string> vs;
int n;
inline int getRank(int i) {
    return i < n ? r[i] : 0;
}
void show(int *arr) {
    for (int i = 0; i<n; ++i) {
        printf("%d%c", arr[i], i == n-1 ? '\n' : ' ');
    }
}
void csort(int step) {
    vi cnt(n+31);
    for (int i = 0, x; i<n; ++i) {
        cnt[getRank(i + step)]++;
    }
    for (int i = 1; i<=n; ++i) {
        cnt[i] += cnt[i-1];
    }
    for (int i = n-1, x; i>=0; --i) {
        x = getRank(p[i] + step);
        aux[cnt[x]-1] = p[i];
        cnt[x]--;
    }
    copy(aux, aux+n, p);
}

void build_sa() {
    for (int i = 0; i<n; ++i) {
        p[i] = i;
        r[i] = s[i];
    }
    for (int k = 1; k <= n; k<<=1) {
        csort(k);
        csort(0);
        int nxt = 1;
        aux[p[0]] = 1;
        for (int i = 1; i < n; ++i) {
            if (getRank(p[i-1]) != getRank(p[i]) || getRank(p[i-1]+k) != getRank(p[i]+k)) nxt++;
            aux[p[i]] = nxt;
        }
        copy(aux, aux+n, r);
        if (r[p[n-1]] == n) break;
    }
}

void build_lcp() {
    for (int i = 0; i<n; ++i) {
        r[p[i]] = i;
    }
    int h = 0;
    for (int j, i = 0; i<n; ++i) {
        if (r[i] == n-1) {
            lcp[r[i]] = h = 0;
        } else {
            j = p[r[i]+1];
            while (i+h < n && j+h < n && s[i+h] == s[j+h]) ++h;
            lcp[r[i]] = h;
            if (h > 0) h--;
        }
    }
}

map<string,int>cnt;

int main() {$
    int m;
    int nxt = 0;
    string t;
    cin >> n;
    ll ans = 0;
    for (int i = 0; i<n; ++i) {
        cin >> t;
        vs.push_back(t);
        cnt[t]++;
    }
    for (int i = 0; i<n; ++i) {
        cin >> aux[i];
        if(cnt[vs[i]] == 1)
        ans = max(ans, aux[i]*(ll)vs[i].size());
    }
    for (int i = 0; i<n; ++i) {
        for (char c : vs[i]) {
            cost[nxt] = aux[i];
            s[nxt++] = c - 'a'+1 + n;
        }
        s[nxt++] = i+1;
    }
    n = nxt-1;
    build_sa();
    build_lcp();
    aux[0] = cost[p[0]];
    for (int i = 1; i<n; ++i) {
        aux[i] = cost[p[i]] + aux[i-1];
    }
    //cost[n] = cost[n-1];
    copy(aux, aux+n, cost);
    ll c;
    stack<int> st;
    for (int i = 0; i<=n; ++i) {
        while (st.size() && lcp[st.top()] >= lcp[i]) {
            int top = st.top(); st.pop();
            int idx = -1;
            if (st.size()) idx = st.top();
            c = cost[i] - (idx < 0 ? 0 : cost[idx]);
            if(lcp[top] != lcp[i])
                ans = max(ans, c * (ll)lcp[top]);
            //printf("from %d to %d with h %d and cost %lld\n", idx,i-1, lcp[top],c);
        }
        st.push(i);
    }
    cout << ans << '\n';
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef double db;

typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define f first
#define s second

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef vector<pii> vpi;
typedef vector<pll> vpl;
typedef vector<pdd> vpd;

#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
const int INT_INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ld PI = acosl((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};
const int maxn = 1e5+5, maxl = 5e5+5;

mt19937 g1(59);
inline int randint(int l, int r){return uniform_int_distribution<int>(l,r)(g1);}

template<const int MAXN> struct SuffixArray{
    int N,g,ord[MAXN],lcp[MAXN],sa[MAXN],tmp[MAXN];
    pair<pii,int> srt[MAXN];
    string s;
    inline void init(string _s){
        N = (int)_s.size(), g = __lg(N)+1, s = "#"+_s;
        int cc = 0;
        for(int i=1; i<=N; i++){
            sa[i] = i;
//            ord[i] = s[i];
            if(s[i] == '#') ord[i] = tmp[i] = ++cc;
            else ord[i] = tmp[i] = s[i]+N;
        }
        for(int r=0; r<=g; r++){
            for(int i=1; i<=N; i++)
                srt[i] = mp(mp(ord[sa[i]],ord[sa[i]-1+(1<<r)%N+1]),sa[i]);
            sort(srt+1,srt+N+1);
            int idx = 1;
            for(int i=1; i<=N; i++){
                sa[i] = srt[i].second;
                if(i > 1 && srt[i].first != srt[i-1].first) ++idx;
                ord[sa[i]] = idx;
            }
        }
        int d = 0;
        for(int i=1; i<=N; i++){
            d-=!!d;
            while(i+d <= N && sa[ord[i]+1]+d <= N && tmp[i+d] == tmp[sa[ord[i]+1]+d]) ++d;
            lcp[ord[i]] = d;
        }
    }
};

int N,vals[maxn],ind[maxl];
pii arr[maxl];
string strs[maxn],tot;
SuffixArray<maxl> sa;
ll psa[maxl],res;
stack<pii> st;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for(int i=1; i<=N; i++){
        cin >> strs[i];
        tot = tot+strs[i]+"#";
    }
    for(int i=1; i<=N; i++){
        cin >> vals[i];
        if(N < 1000)
            res = max(res,(ll)strs[i].size()*vals[i]);
    }
    sa.init(tot);
    int cnt = 1;
    for(int i=1; i<=tot.size(); i++){
        if(tot[i-1] == '#') cnt++;
        else ind[i] = cnt;
    }
//    cout << tot << endl;
    for(int i=1; i<=tot.size(); i++){
//        cout << sa.sa[i] << " ";
        arr[i] = mp(sa.lcp[i],vals[ind[sa.sa[i]]]);
        psa[i] = psa[i-1]+arr[i].second;
    }
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << sa.lcp[i] << " ";
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << vals[ind[i]] << " ";
//    cout << endl;
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << arr[i].second << " ";
//    cout << endl;
    st.push(mp(-1,0));
    for(int i=N+2; i<=tot.size(); i++){
        while(st.size() && sa.lcp[i-1] <= st.top().first){
            pii t = st.top(); st.pop();
//            if(sa.lcp[t.f] != sa.lcp[i-1])
                res = max(res,1LL*t.first*(psa[i-1]-psa[st.top().second]));
        }
        st.push(mp(sa.lcp[i-1],i-1));
    }
    while(st.size() > 1){
        pii t = st.top(); st.pop();
        res = max(res,1LL*t.first*(psa[tot.size()]-psa[st.top().second]));
    }
    cout << res << '\n';
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef double db;

typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define f first
#define s second

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef vector<pii> vpi;
typedef vector<pll> vpl;
typedef vector<pdd> vpd;

#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
const int INT_INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ld PI = acosl((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};
const int maxn = 1e5+5, maxl = 5e5+5;

mt19937 g1(59);
inline int randint(int l, int r){return uniform_int_distribution<int>(l,r)(g1);}

template<const int MAXN> struct SuffixArray{
    int N,g,ord[MAXN],lcp[MAXN],sa[MAXN],tmp[MAXN];
    pair<pii,int> srt[MAXN];
    string s;
    inline void init(string _s){
        N = (int)_s.size(), g = __lg(N)+1, s = "#"+_s;
        int cc = 0;
        for(int i=1; i<=N; i++){
            sa[i] = i;
//            ord[i] = s[i];
            if(s[i] == '#') ord[i] = tmp[i] = ++cc;
            else ord[i] = tmp[i] = s[i]+N;
        }
        for(int r=0; r<=g; r++){
            for(int i=1; i<=N; i++)
                srt[i] = mp(mp(ord[sa[i]],ord[sa[i]-1+(1<<r)%N+1]),sa[i]);
            sort(srt+1,srt+N+1);
            int idx = 1;
            for(int i=1; i<=N; i++){
                sa[i] = srt[i].second;
                if(i > 1 && srt[i].first != srt[i-1].first) ++idx;
                ord[sa[i]] = idx;
            }
        }
        int d = 0;
        for(int i=1; i<=N; i++){
            d-=!!d;
            while(tmp[i+d] == tmp[sa[ord[i]+1]+d]) ++d;
            lcp[ord[i]] = d;
        }
    }
};

int N,vals[maxn],ind[maxl];
pii arr[maxl];
string strs[maxn],tot;
SuffixArray<maxl> sa;
ll psa[maxl],res;
stack<pii> st;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for(int i=1; i<=N; i++){
        cin >> strs[i];
        tot = tot+strs[i]+"#";
    }
    for(int i=1; i<=N; i++){
        cin >> vals[i];
        res = max(res,(ll)strs[i].size()*vals[i]);
    }
    sa.init(tot);
    int cnt = 1;
    for(int i=1; i<=tot.size(); i++){
        if(tot[i-1] == '#') cnt++;
        ind[i] = cnt;
    }
//    cout << tot << endl;
    for(int i=1; i<=tot.size(); i++){
//        cout << sa.sa[i] << " ";
        arr[i] = mp(sa.lcp[i],vals[ind[sa.sa[i]]]);
        psa[i] = psa[i-1]+arr[i].second;
    }
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << sa.lcp[i] << " ";
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << vals[ind[i]] << " ";
//    cout << endl;
//    cout << endl;
//    for(int i=1; i<=tot.size(); i++)
//        cout << arr[i].second << " ";
//    cout << endl;
    st.push(mp(-1,0));
    for(int i=2; i<=tot.size(); i++){
        while(st.size() && sa.lcp[i-1] <= st.top().first){
            pii t = st.top(); st.pop();
            res = max(res,1LL*t.first*(psa[i-1]-psa[st.top().second]));
        }
        st.push(mp(sa.lcp[i-1],i-1));
    }
    while(st.size() > 1){
        pii t = st.top(); st.pop();
        res = max(res,1LL*t.first*(psa[tot.size()]-psa[st.top().second]));
    }
    cout << res << '\n';
}