#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <sstream>

using namespace std;

const int INF = 1e9;
const int MOD = 1e9 + 7;

int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	ios::sync_with_stdio(0);
	int n, r, avg;
	cin >> n >> r >> avg;
	vector<pair<int, int> > v;
	long long sum = 0;
	for (int i = 0; i < n; ++i)
	{
		int a, b;
		cin >> a >> b;
		sum += a;
		v.push_back(make_pair(b, a));
	}
	if (sum >= avg * n)
	{
		cout << 0 << endl;
		return 0;
	}
	sort(v.begin(), v.end());
	long long q = 0;
	for (int i = 0; i < n; ++i)
	{
		if (avg * n - sum > (r - v[i].second))
		{
			q += (r - v[i].second) * v[i].first;
			sum += r - v[i].second;
		}
		else
		{
			q += (avg * n - sum) * v[i].first;
			sum += avg * n - sum;
			break;
		}
	}
	cout << q << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
#define vi vector<LL>
#define vs vector<string>
#define vl vector<LL>
#define pb push_back
#define endl "\n"

struct exam
{
   LL a;
   LL b;

   bool operator<(const exam& rhs) const
   {
      return b < rhs.b;
   }
};

LL main()
{
	ios_base::sync_with_stdio(false);
	LL n,r,avg;
	cin >> n >> r >> avg;
	vector<exam> E;
	LL sum = 0;
	for(LL i=0;i<n;i++)
	{
	   LL a,b;
	   cin >> a >> b;
	   exam e;
	   e.a = a;
	   e.b = b;
	   E.pb(e);
	   sum += a;
	}
	sort(E.begin(), E.end());

	LL reqd = LL(avg) * n - sum;

	LL ret = 0;
	LL i=0;
	while (reqd > 0)
	{
	   if (reqd <= r - E[i].a)
	   {
	      ret += reqd * E[i].b;
	      reqd = 0;
	   }
	   else
	   {
	      ret += (r - E[i].a) * E[i].b;
	      reqd -= (r - E[i].a);
	   }
	   ++i;
	}

	cout << ret << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
#define vi vector<int>
#define vs vector<string>
#define vl vector<LL>
#define pb push_back
#define endl "\n"

int main()
{
   std::cout.precision(5);
   int n,l;
   cin >> n >> l;
   vi A;
   int t;
   for(int i=0;i<n;i++)
   {
      cin >> t;
      A.pb(t);
   }
   sort(A.begin(), A.end());

   double d = 0;

   for(int i=0;i<n;++i)
   {
      if (i == 0)
      {
         d = max(d, (double)A[i]);
      }
      else if (i == n-1)
      {
         d = max(d, (double)(l - A[i]));
      }
      else
      {
         d = max(d, double(A[i+1] - A[i]) / 2.0);
      }
   }

   cout << fixed << d << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
#define vi vector<LL>
#define vs vector<string>
#define vl vector<LL>
#define pb push_back
#define endl "\n"

struct exam
{
   LL a;
   LL b;

   bool operator<(const exam& rhs) const
   {
      return b < rhs.b;
   }
};

int main()
{
	ios_base::sync_with_stdio(false);
	LL n,r,avg;
	cin >> n >> r >> avg;
	vector<exam> E;
	LL sum = 0;
	for(LL i=0;i<n;i++)
	{
	   LL a,b;
	   cin >> a >> b;
	   exam e;
	   e.a = a;
	   e.b = b;
	   E.pb(e);
	   sum += a;
	}
	sort(E.begin(), E.end());

	LL reqd = LL(avg) * n - sum;

	LL ret = 0;
	LL i=0;
	while (reqd > 0)
	{
	   if (reqd <= r - E[i].a)
	   {
	      ret += reqd * E[i].b;
	      reqd = 0;
	   }
	   else
	   {
	      ret += (r - E[i].a) * E[i].b;
	      reqd -= (r - E[i].a);
	   }
	   ++i;
	}

	cout << ret << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
#define vi vector<int>
#define vs vector<string>
#define vl vector<LL>
#define pb push_back
#define endl "\n"

struct exam
{
   int a;
   int b;

   bool operator<(const exam& rhs) const
   {
      return b < rhs.b;
   }
};

int main()
{
	ios_base::sync_with_stdio(false);
	int n,r,avg;
	cin >> n >> r >> avg;
	vector<exam> E;
	LL sum = 0;
	for(int i=0;i<n;i++)
	{
	   int a,b;
	   cin >> a >> b;
	   exam e;
	   e.a = a;
	   e.b = b;
	   E.pb(e);
	   sum += a;
	}
	sort(E.begin(), E.end());

	LL reqd = LL(avg) * n - sum;

	LL ret = 0;
	int i=0;
	while (reqd > 0)
	{
	   if (reqd <= r - E[i].a)
	   {
	      ret += reqd * E[i].b;
	      reqd = 0;
	   }
	   else
	   {
	      ret += (r - E[i].a) * E[i].b;
	      reqd -= (r - E[i].a);
	   }
	   ++i;
	}

	cout << ret << endl;

	return 0;
}


#include <set>
#include <map>
#include <unordered_map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <stdexcept>

using namespace std;

std::string num2str( long long n )
{
    std::ostringstream result;
    result << n;
    return result.str();
}

long long str2num( const std::string& s )
{
    long long result;
    std::istringstream ss( s );
    ss >> result;
    if (!ss) throw std::invalid_argument( "StrToInt" );
    return result;
}

struct sort_pred {
    bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
        return left.second < right.second;
    }
};

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    // 280C

    int N, R, AVG, a ,b, sum=0;
    cin >> N >> R >> AVG;
    vector<pair<int, int> > ps(N);
    for (int i = 0; i < N; ++i) {
        cin >> a >> b;
        ps[i] = make_pair(a, b);
        sum += a;
    }
    sort(ps.begin(), ps.end(), sort_pred());

    int res = 0;
    for (int i = 0; sum/N < AVG; ++i) {
        int a = ps[i].first;
        int b = ps[i].second;
        int marks = R-a;
        if ((sum + marks) / N >= AVG) {
            int l = 1, r = R-a, m = 0;
            while (l <= r) {
//                cout << "L: " << l << ", R: " << r << endl;
                int mid = (l+r) / 2;
                int avg = (sum+mid) / N;
                if (avg >= AVG) {
                    m = mid;
                    r = mid-1;
                } else {
                    l = mid+1;
                }
            }
            res += m * b;
//            while (sum / N < AVG) {
//                sum += 1;
//                res += b;
//            }

            break;
        }

        sum += marks;
        res += marks * b;
    }

    cout << res << endl;

    return 0;
}


#include <set>
#include <map>
#include <unordered_map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <stdexcept>

using namespace std;

std::string num2str( long long n )
{
    std::ostringstream result;
    result << n;
    return result.str();
}

long long str2num( const std::string& s )
{
    long long result;
    std::istringstream ss( s );
    ss >> result;
    if (!ss) throw std::invalid_argument( "StrToInt" );
    return result;
}

struct sort_pred {
    bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
        return left.second < right.second;
    }
};

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    // 280C

    int N, R, AVG, a ,b, sum=0;
    cin >> N >> R >> AVG;
    vector<pair<int, int> > ps(N);
    for (int i = 0; i < N; ++i) {
        cin >> a >> b;
        ps[i] = make_pair(a, b);
        sum += a;
    }
    sort(ps.begin(), ps.end(), sort_pred());

    int res = 0;
    for (int i = 0; sum/N < AVG; ++i) {
        int a = ps[i].first;
        int b = ps[i].second;
        int marks = R-a;
        if ((sum + marks) / N >= AVG) {
            int l = 1, r = R-a, m = 0;
/*            while (l <= r) {
//                cout << "L: " << l << ", R: " << r << endl;
                int mid = (l+r) / 2;
                int avg = (sum+mid) / N;
                if (avg >= AVG) {
                    m = mid;
                    r = mid-1;
                } else {
                    l = mid+1;
                }
            }
            res += m * b;*/
            while (sum / N < AVG) {
                sum += 1;
                res += b;
            }

            break;
        }

        sum += marks;
        res += marks * b;
    }

    cout << res << endl;

    return 0;
}


#include <set>
#include <map>
#include <unordered_map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <stdexcept>

using namespace std;

std::string num2str( long long n )
{
    std::ostringstream result;
    result << n;
    return result.str();
}

long long str2num( const std::string& s )
{
    long long result;
    std::istringstream ss( s );
    ss >> result;
    if (!ss) throw std::invalid_argument( "StrToInt" );
    return result;
}

struct sort_pred {
    bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
        return left.second < right.second;
    }
};

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    // C

    int N, R, AVG, a ,b, sum;
    cin >> N >> R >> AVG;
    vector<pair<int, int> > ps(N);
    for (int i = 0; i < N; ++i) {
        cin >> a >> b;
        ps[i] = make_pair(a, b);
        sum += a;
    }
    sort(ps.begin(), ps.end(), sort_pred());

    int res = 0;
    for (int i = 0; sum/N < AVG; ++i) {
        int a = ps[i].first;
        int b = ps[i].second;
        int marks = R-a;
        if ((sum + marks) / N >= AVG) {
            int l = 1, r = R-a, m = 0;
            while (l <= r) {
//                cout << "L: " << l << ", R: " << r << endl;
                int mid = (l+r) / 2;
                int avg = (sum+mid) / N;
                if (avg >= AVG) {
                    m = mid;
                    r = mid-1;
                } else {
                    l = mid+1;
                }
            }
            res += m * b;
            break;
        }

        sum += marks;
        res += marks * b;
    }

    cout << res << endl;

    return 0;
}


#include <set>
#include <map>
#include <unordered_map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <stdexcept>

using namespace std;

std::string num2str( long long n )
{
    std::ostringstream result;
    result << n;
    return result.str();
}

long long str2num( const std::string& s )
{
    long long result;
    std::istringstream ss( s );
    ss >> result;
    if (!ss) throw std::invalid_argument( "StrToInt" );
    return result;
}

struct sort_pred {
    bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
        return left.second < right.second;
    }
};

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    // 280C

    long long N, R, AVG, a ,b, sum=0;
    cin >> N >> R >> AVG;
    vector<pair<long long, long long> > ps(N);
    for (int i = 0; i < N; ++i) {
        cin >> a >> b;
        ps[i] = make_pair(a, b);
        sum += a;
    }
    sort(ps.begin(), ps.end(), sort_pred());

    long long res = 0;
    for (int i = 0; sum/N < AVG; ++i) {
        long long a = ps[i].first;
        long long b = ps[i].second;
        long long marks = R-a;
        if ((sum + marks) / N >= AVG) {
            int l = 1, r = R-a, m = 0;
            while (l <= r) {
//                cout << "L: " << l << ", R: " << r << endl;
                int mid = (l+r) / 2;
                long long avg = (sum+mid) / N;
                if (avg >= AVG) {
                    m = mid;
                    r = mid-1;
                } else {
                    l = mid+1;
                }
            }
            res += m * b;
//            while (sum / N < AVG) {
//                sum += 1;
//                res += b;
//            }

            break;
        }

        sum += marks;
        res += marks * b;
    }

    cout << res << endl;

    return 0;
}


//
//  main.cpp
//  492c
//
//  Created by Angad Pal Singh on 02/12/14.
//  Copyright (c) 2014 abc. All rights reserved.
//
#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <utility>
#include <ctime>

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int, int> PII;

#define REP(i,n) for((i)=0;(i)<(int)(n);++(i))

long n,r,i;
long long avg,sum=0,cnt;
struct ab
{
    long a;
    long b;
};

vector<ab> grades;

bool cmp(ab x,ab y)
{
    return (x.b<y.b)?true:false;
}

long long getmin(long long a,long long b)
{
    return a<b?a:b;
}

int main(int argc, const char * argv[]) {

    cin>>n>>r>>avg;

    while (n--) {
        ab t;
        cin>>t.a>>t.b;
        sum += t.a;
        grades.push_back(t);
    }

    n=grades.size();

    sort(grades.begin(), grades.end(), cmp);

    REP(i,n)
    {
        if(sum>=(long)avg*n)
            break;
        if(grades[i].a<r)
        {
            LL d = getmin(avg*n - sum,(LL)r-grades[i].a);
            sum += d;
            cnt += d*grades[i].b;

        }
    }

    cout<<cnt;
    return 0;
}


//
//  main.cpp
//  492c
//
//  Created by Angad Pal Singh on 02/12/14.
//  Copyright (c) 2014 abc. All rights reserved.
//
#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <utility>
#include <ctime>

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int, int> PII;

#define REP(i,n) for((i)=0;(i)<(int)(n);++(i))

long n,r,avg,i;
long sum=0,cnt;
struct ab
{
    long a;
    long b;
};

vector<ab> grades;

bool cmp(ab x,ab y)
{
    return (x.b<y.b)?true:false;
}

long getmin(long a,long b)
{
    return a<b?a:b;
}

int main(int argc, const char * argv[]) {

    cin>>n>>r>>avg;

    while (n--) {
        ab t;
        cin>>t.a>>t.b;
        sum += t.a;
        grades.push_back(t);
    }

    n=grades.size();

    sort(grades.begin(), grades.end(), cmp);

    REP(i,n)
    {
        if(sum>=(long)avg*n)
            break;
        if(grades[i].a<r)
        {
            long d = getmin(avg*n - sum,r-grades[i].a);
            sum += d;
            cnt += d*grades[i].b;

        }
    }

    cout<<cnt;
    return 0;
}


//
//  main.cpp
//  492c
//
//  Created by Angad Pal Singh on 02/12/14.
//  Copyright (c) 2014 abc. All rights reserved.
//
#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <utility>
#include <ctime>

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int, int> PII;

#define REP(i,n) for((i)=0;(i)<(int)(n);++(i))

LL n,r,i;
long long avg,sum=0,cnt;
struct ab
{
    long a;
    long b;
};

vector<ab> grades;

bool cmp(ab x,ab y)
{
    return (x.b<y.b)?true:false;
}

long long getmin(long long a,long long b)
{
    return a<b?a:b;
}

int main(int argc, const char * argv[]) {

    cin>>n>>r>>avg;

    while (n--) {
        ab t;
        cin>>t.a>>t.b;
        sum += t.a;
        grades.push_back(t);
    }

    n=grades.size();

    sort(grades.begin(), grades.end(), cmp);

    REP(i,n)
    {
        if(sum>=(long)avg*n)
            break;
        if(grades[i].a<r)
        {
            LL d = getmin(avg*n - sum,r-grades[i].a);
            sum += d;
            cnt += d*grades[i].b;

        }
    }

    cout<<cnt;
    return 0;
}


//
//  main.cpp
//  492c
//
//  Created by Angad Pal Singh on 02/12/14.
//  Copyright (c) 2014 abc. All rights reserved.
//
#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <utility>
#include <ctime>

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int, int> PII;

#define REP(i,n) for((i)=0;(i)<(int)(n);++(i))

long n,r,avg,i;
long sum=0,cnt;
struct ab
{
    long a;
    long b;
};

vector<ab> grades;

bool cmp(ab x,ab y)
{
    return (x.b<y.b)?true:false;
}

long getmin(long a,long b)
{
    return a<b?a:b;
}

int main(int argc, const char * argv[]) {

    cin>>n>>r>>avg;

    while (n--) {
        ab t;
        cin>>t.a>>t.b;
        sum += t.a;
        grades.push_back(t);
    }

    n=grades.size();

    sort(grades.begin(), grades.end(), cmp);

    REP(i,n)
    {
        if(sum>=(long)avg*n)
            break;
        if(grades[i].a<r)
        {
            long d = getmin(avg*n - sum,r-grades[i].a);
            sum += d;
            cnt += grades[i].b*d;

        }
    }

    cout<<cnt;
    return 0;
}


//
//  main.cpp
//  492c
//
//  Created by Angad Pal Singh on 02/12/14.
//  Copyright (c) 2014 abc. All rights reserved.
//
#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <utility>
#include <ctime>

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int, int> PII;

#define REP(i,n) for((i)=0;(i)<(int)(n);++(i))

int n,r,avg,i;
long sum=0,cnt;
struct ab
{
    int a;
    int b;
};

vector<ab> grades;

bool cmp(ab x,ab y)
{
    return (x.b<y.b)?true:false;
}

int getmin(int a,int b)
{
    return a<b?a:b;
}

int main(int argc, const char * argv[]) {

    cin>>n>>r>>avg;

    while (n--) {
        ab t;
        cin>>t.a>>t.b;
        sum += t.a;
        grades.push_back(t);
    }

    n=grades.size();

    sort(grades.begin(), grades.end(), cmp);

    REP(i,n)
    {
        if(sum>=(long)avg*n)
            break;
        if(grades[i].a<r)
        {
            int d = getmin((long)avg*n - sum,r-grades[i].a);
            sum += d;
            cnt += grades[i].b*d;

        }
    }

    cout<<cnt;
    return 0;
}


#include <iostream>
#include <algorithm>

using namespace std;
#define MAX_GRADES_NUMBER 100000

struct Degree{
	int degree, essays;
};

long long examsNumber, maxGrade;
double avg;
Degree grades[MAX_GRADES_NUMBER];
long long essaysNumber;
long long sum;
void qSort(long long start, long long end);

int main() {
	cin >> examsNumber >> maxGrade >> avg;
	for (long long i=0; i<examsNumber; i++) {
		cin >> grades[i].degree >> grades[i].essays;
		sum += grades[i].degree;
	}

	qSort(0, examsNumber-1);
	double vanyaAvg = sum / (double)examsNumber;
	double sub = avg - vanyaAvg;
	long long needed = floor(sub*examsNumber + 0.9);
	long long index = 0;
	long long added = 0;
	while (added < needed) {
		if (grades[index].degree < maxGrade) {
			long long num = maxGrade - grades[index].degree;
			if (added + num > needed) {
				num = needed - added;
			}
			essaysNumber += (num * grades[index].essays);
			added+= num;
		}
		index++;
	}

	cout << essaysNumber << endl;
	return 0;
}

void qSort(long long start, long long end) {
	long long pivot = grades[(end+start)/2].essays;
	long long i = start, j = end;

	while (i <= j) {
		while (grades[i].essays < pivot)
			i++;
		while (grades[j].essays > pivot)
			j--;

		if (i <=j) {
			swap(grades[i].essays, grades[j].essays);
			swap(grades[i].degree, grades[j].degree);
			i++; j--;
		}
	}

	if (i < end)
		qSort(i, end);
	if (j > start)
		qSort(start, j);
}


#include <iostream>
#include <algorithm>

using namespace std;
#define MAX_DEGREES_NUMBER 100000

struct Degree {
	long long degree, essays;
};

long long examsNumber, maxGrade;
double avg;
Degree degrees[MAX_DEGREES_NUMBER];
long long essaysNumber;
long long sum;
int compare (const void *a, const void *b){
	return (*(Degree*)a).essays - (*(Degree*)b).essays;
}
int main() {
	cin >> examsNumber >> maxGrade >> avg;
	for (long long i=0; i<examsNumber; i++) {
		cin >> degrees[i].degree >> degrees[i].essays;
		sum += degrees[i].degree;
	}
	qsort(degrees, examsNumber, sizeof(degrees[0]), compare);

	double vanyaAvg = sum / (double)examsNumber;
	double sub = avg - vanyaAvg;
	long long needed = floor(sub*examsNumber + 0.9);
	long long index = 0;
	long long added = 0;
	while (added < needed) {
		if (degrees[index].degree < maxGrade) {
			long long num = maxGrade - degrees[index].degree;
			if (added + num > needed) {
				num = needed - added;
			}
			essaysNumber += (num * degrees[index].essays);
			added+= num;
		}
		index++;
	}

	cout << essaysNumber << endl;
	return 0;
}


#include <iostream>
#include <algorithm>

using namespace std;
#define MAX_GRADES_NUMBER 100000

struct Degree{
	int degree, essays;
};

long long examsNumber, maxGrade;
double avg;
Degree grades[MAX_GRADES_NUMBER];
long long essaysNumber;
long long sum;
void qSort(long long start, long long end);

int main() {
	cin >> examsNumber >> maxGrade >> avg;
	for (long long i=0; i<examsNumber; i++) {
		cin >> grades[i].degree >> grades[i].essays;
		sum += grades[i].degree;
	}

	qSort(0, examsNumber-1);
	double vanyaAvg = sum / (double)examsNumber;
	double sub = avg - vanyaAvg;
	long long needed = floor(sub*examsNumber + 0.9);
	long long index = 0;
	long long added = 0;
	while (added < needed) {
		if (grades[index].degree < maxGrade) {
			long long num = maxGrade - grades[index].degree;
			if (added + num > needed) {
				num = needed - added;
			}
			essaysNumber += (num * grades[index].essays);
			added+= num;
		}
		index++;
	}

	cout << essaysNumber << endl;
	return 0;
}

void qSort(long long start, long long end) {
	long long pivot = grades[(end+start)/2].essays;
	long long i = start, j = end;

	while (i <= j) {
		while (grades[i].essays < pivot)
			i++;
		while (grades[j].essays > pivot)
			j--;

		if (i <=j) {
			if (grades[i].essays != grades[j].essays){
				swap(grades[i].essays, grades[j].essays);
				swap(grades[i].degree, grades[j].degree);
			}
			i++; j--;
		}
	}

	if (i < end)
		qSort(i, end);
	if (j > start)
		qSort(start, j);
}


#include <iostream>
#include <algorithm>

using namespace std;
#define MAX_GRADES_NUMBER 100000

long long examsNumber, maxGrade;
double avg;
long long grades[MAX_GRADES_NUMBER][2];
long long essaysNumber;
long long sum;
void qSort(long long start, long long end);
float nextFloat(double number);
void sort();
int main() {
	cin >> examsNumber >> maxGrade >> avg;
	for (long long i=0; i<examsNumber; i++) {
		cin >> grades[i][0] >> grades[i][1];
		sum += grades[i][0];
	}
	qSort(0, examsNumber-1);
	double vanyaAvg = sum / (double)examsNumber;
	double sub = avg - vanyaAvg;
	long long needed = floor(sub*examsNumber + 0.9);
	long long index = 0;
	long long added = 0;
	while (added < needed) {
		if (grades[index][0] < maxGrade) {
			long long num = maxGrade - grades[index][0];
			if (added + num > needed) {
				num = needed - added;
			}
			essaysNumber += (num * grades[index][1]);
			added+= num;
		}
		index++;
	}

	cout << essaysNumber << endl;
	return 0;
}

void sort() {
	for (int i=0; i<examsNumber-1; i++) {
		for (int j=i+1; j<examsNumber; j++) {
			if (grades[i][1] > grades[j][1]) {
				swap(grades[i][1], grades[j][1]);
				swap(grades[i][0], grades[i][0]);
			}
		}
	}
}

void qSort(long long start, long long end) {
	long long pivot = grades[(end+start)/2][1];
	long long i = start, j = end;

	while (i <= j) {
		while (grades[i][1] < pivot)
			i++;
		while (grades[j][1] > pivot)
			j--;

		if (i <=j) {
			swap(grades[i][0], grades[j][0]);
			swap(grades[i][1], grades[j][1]);
			i++; j--;
		}
	}

	if (i < end)
		qSort(i, end);
	if (j > start)
		qSort(start, j);
}


#include <vector>
#include <list>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <tuple>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#define mp(a,b) make_pair((a), (b))
using namespace std;

int main(){
	long long r, avg, n;
	cin >> n >> r >> avg;
	avg *= n;
	long long sum=0;
	vector<long long> a(n);
	vector<pair<long long,long long>> b(n);
	for(long long i=0; i<n;i++){
		long long bv;
		cin >> a[i] >> bv;
		b[i] = mp(bv, (r-a[i]));
		sum += a[i];
	}
	sort(b.begin(), b.end());
	long long essays=0;
	for(auto p : b){
		if(sum >= avg)
			break;
		long long bv=p.first;
		long long maxk = p.second;
		long long add = min(maxk, avg-sum);
		essays += add*bv;
		sum += add;
	}
	cout << essays << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <tuple>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#define mp(a,b) make_pair((a), (b))
using namespace std;

int main(){
	int n,r;
	long long avg;
	cin >> n >> r >> avg;
	avg *= n;
	long long sum;
	vector<int> a(n);
	vector<pair<int,int>> b(n);
	for(int i=0; i<n;i++){
		int bv;
		cin >> a[i] >> bv;
		b[i] = mp(bv, (r-a[i]));
		sum += a[i];
	}
	sort(b.begin(), b.end());
	int essays=0;
	for(auto p : b){
		if(sum >= avg)
			break;
		int bv=p.first;
		int maxk = p.second;
		for(int i=0; i<maxk && sum < avg;i++){
			sum += 1;
			essays += bv;
		}
	}
	cout << essays << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <tuple>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

int main(){

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = a; i < (b); i++)
#define trav(a, x) for (auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int) (x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;

string s;
vector<vector<ll>> dp;
vector<vector<pair<ll, int>>> pc;
vi pos;

struct AhoCorasick {
	enum { alpha = 14, first = 'a' };

	struct Node {
		int back, next[alpha];
		ll nmatches = 0;
		Node(int v) { memset(next, v, sizeof(next)); }
	};

	vector<Node> N;
	vi backp;

	void insert(string& s, ll score) {
		assert(!s.empty());
		int n = 0;
		trav(c, s) {
			int &m = N[n].next[c - first];
			if (m == -1) {
				n = m = sz(N);
				N.emplace_back(-1);
			} else n = m;
		}

		N[n].nmatches += score;
	}

	AhoCorasick(vector<string>& pat, vector<ll>& scores) {
		N.emplace_back(-1);
		rep(i, 0, sz(pat)) insert(pat[i], scores[i]);
		N[0].back = sz(N);
		N.emplace_back(0);

		rep(i, 0, sz(s)) if (s[i] == '?') pos.push_back(i);

		dp = vector<vector<ll>>(1 << 14, vector<ll>(sz(N), LONG_MIN));
		pc = vector<vector<pair<ll, int>>>(sz(pos),
				vector<pair<ll, int>>(sz(N)));

		queue<int> q;
		for (q.push(0); !q.empty(); q.pop()) {
			int n = q.front(), prev = N[n].back;
			rep(i, 0, alpha) {
				int &ed = N[n].next[i], y = N[prev].next[i];
				if (ed == -1) ed = y;
				else {
					N[ed].back = y;
					N[ed].nmatches += N[y].nmatches;
					q.push(ed);
				}
			}
		}
	}

	void precompute() {
		rep(i, 0, sz(pos)) {
			int start = pos[i];
			rep(j, 0, sz(N)) {
				ll score = 0;
				int cur_pos = start;
				int cur_node = j;

				while (true) {
					score += N[cur_node].nmatches;
					cur_pos++;
					if (cur_pos == sz(s) || s[cur_pos] == '?') break;
					cur_node = N[cur_node].next[s[cur_pos] - first];
				}

				pc[i][j].first = score;
				pc[i][j].second = cur_node;
			}
		}
	}

	ll compute(int c) {
		ll sol = LONG_MIN;
		dp[0][c] = 0;
		queue<pii> q; q.push(pii(c, 0));
		while(!q.empty()) {
			int cur_node = q.front().first, cur_mask = q.front().second;
			q.pop();

			int i = __builtin_popcount(cur_mask);
			rep(j, 0, alpha) if (((cur_mask >> j) & 1) == 0) {
				int nmask = cur_mask ^ (1 << j);
				int next_c = N[cur_node].next[j];
				ll cand_sol = pc[i][next_c].first + dp[cur_mask][cur_node];
				next_c = pc[i][next_c].second;
				if (dp[nmask][next_c] == LONG_MIN && i + 1 < sz(pos))
					q.push(pii(next_c, nmask));
				dp[nmask][next_c] = max(dp[nmask][next_c], cand_sol);
				if (i + 1 == sz(pos)) sol = max(sol, dp[nmask][next_c]);
			}
		}

		return sol;
	}
};

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int k;
	cin >> k;

	vector<string> pat(k);
	vector<ll> scores(k);
	rep(i, 0, k) cin >> pat[i] >> scores[i];
	cin >> s;

	AhoCorasick ac(pat, scores);

	ll score = 0;
	int cur_node = 0, cur_pos = 0;
	while (s[cur_pos] != '?' && cur_pos < sz(s)) {
		cur_node = ac.N[cur_node].next[s[cur_pos] - ac.first];
		score += ac.N[cur_node].nmatches;
		cur_pos++;
	}

	ac.precompute();

	cout << (score  + ac.compute(cur_node)) << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = a; i < (b); i++)
#define trav(a, x) for (auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int) (x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;

string s;
vector<vector<vector<ll>>> dp;
vector<vector<pair<ll, int>>> pc;
vi pos;

struct AhoCorasick {
	enum { alpha = 14, first = 'a' };

	struct Node {
		int back, next[alpha];
		ll nmatches = 0;
		Node(int v) { memset(next, v, sizeof(next)); }
	};

	vector<Node> N;
	vi backp;

	void insert(string& s, ll score) {
		assert(!s.empty());
		int n = 0;
		trav(c, s) {
			int &m = N[n].next[c - first];
			if (m == -1) {
				n = m = sz(N);
				N.emplace_back(-1);
			} else n = m;
		}

		N[n].nmatches += score;
	}

	AhoCorasick(vector<string>& pat, vector<ll>& scores) {
		N.emplace_back(-1);
		rep(i, 0, sz(pat)) insert(pat[i], scores[i]);
		N[0].back = sz(N);
		N.emplace_back(0);
		dp = vector<vector<vector<ll>>>(sz(s));
		pc = vector<vector<pair<ll, int>>>(sz(s));

		rep(i, 0, sz(s)) if (s[i] == '?') {
			pos.push_back(i);
			dp[i] = vector<vector<ll>>(1 << 14, vector<ll>(sz(N), LONG_MIN));
			pc[i] = vector<pair<ll, int>>(sz(N));
		}

		queue<int> q;
		for (q.push(0); !q.empty(); q.pop()) {
			int n = q.front(), prev = N[n].back;
			rep(i, 0, alpha) {
				int &ed = N[n].next[i], y = N[prev].next[i];
				if (ed == -1) ed = y;
				else {
					N[ed].back = y;
					N[ed].nmatches += N[y].nmatches;
					q.push(ed);
				}
			}
		}
	}

	void precompute() {
		trav(start, pos) {
			rep(i, 0, sz(N)) {
				ll score = 0;
				int cur_pos = start;
				int cur_node = i;

				while (true) {
					score += N[cur_node].nmatches;
					cur_pos++;
					if (cur_pos == sz(s) || s[cur_pos] == '?') break;
					cur_node = N[cur_node].next[s[cur_pos] - first];
				}

				pc[start][i].first = score;
				pc[start][i].second = cur_node;
			}
		}
	}

	ll compute(int i, int mask, int c) {
		if (i == sz(pos)) return 0;

		int cur_pos = pos[i];
		if (dp[cur_pos][mask][c] != LONG_MIN) return dp[cur_pos][mask][c];

		ll sol = LONG_MIN;
		rep(j, 0, alpha) if (mask >> j & 1) {
			int next_c = N[c].next[j];
			ll res = compute(i + 1, (mask ^ (1 << j)), pc[cur_pos][next_c].second);
			sol = max(sol, pc[cur_pos][next_c].first + res);
		}

		return dp[cur_pos][mask][c] = sol;
	}
};

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int k;
	cin >> k;

	vector<string> pat(k);
	vector<ll> scores(k);
	rep(i, 0, k) cin >> pat[i] >> scores[i];
	cin >> s;

	AhoCorasick ac(pat, scores);

	ll score = 0;
	int cur_node = 0, cur_pos = 0;
	while (s[cur_pos] != '?' && cur_pos < sz(s)) {
		cur_node = ac.N[cur_node].next[s[cur_pos] - ac.first];
		score += ac.N[cur_node].nmatches;
		cur_pos++;
	}

	ac.precompute();

	cout << (score  + ac.compute(0, (1 << 14) - 1, cur_node)) << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = a; i < (b); i++)
#define trav(a, x) for (auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int) (x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;

string s;
vector<vector<ll>> dp;
vector<vector<pair<ll, int>>> pc;
vi pos;

struct AhoCorasick {
	enum { alpha = 14, first = 'a' };

	struct Node {
		int back, next[alpha];
		ll nmatches = 0;
		Node(int v) { memset(next, v, sizeof(next)); }
	};

	vector<Node> N;
	vi backp;

	void insert(string& s, ll score) {
		assert(!s.empty());
		int n = 0;
		trav(c, s) {
			int &m = N[n].next[c - first];
			if (m == -1) {
				n = m = sz(N);
				N.emplace_back(-1);
			} else n = m;
		}

		N[n].nmatches += score;
	}

	AhoCorasick(vector<string>& pat, vector<ll>& scores) {
		N.emplace_back(-1);
		rep(i, 0, sz(pat)) insert(pat[i], scores[i]);
		N[0].back = sz(N);
		N.emplace_back(0);

		rep(i, 0, sz(s)) if (s[i] == '?') pos.push_back(i);

		dp = vector<vector<ll>>(1 << 14, vector<ll>(sz(N), LONG_MIN));
		pc = vector<vector<pair<ll, int>>>(sz(pos), vector<pair<ll, int>>(sz(N)));

		queue<int> q;
		for (q.push(0); !q.empty(); q.pop()) {
			int n = q.front(), prev = N[n].back;
			N[n].nmatches += N[prev].nmatches;
			rep(i, 0, alpha) {
				int &ed = N[n].next[i], y = N[prev].next[i];
				if (ed == -1) ed = y;
				else {
					N[ed].back = y;
					q.push(ed);
				}
			}
		}
	}

	void precompute() {
		rep(i, 0, sz(pos)) {
			rep(j, 0, sz(N)) {
				ll score = 0;
				int cur_pos = pos[i] + 1;
				int cur_node = j;

				do {
					score += N[cur_node].nmatches;
					if (cur_pos == sz(s) || s[cur_pos] == '?') break;
					cur_node = N[cur_node].next[s[cur_pos++] - first];
				} while (true);

				pc[i][j].first = score;
				pc[i][j].second = cur_node;
			}
		}
	}
};

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	vector<vi> nums(15);
	rep(i, 0, 1 << 14) nums[__builtin_popcount(i)].push_back(i);

	int k;
	cin >> k;

	vector<string> pat(k);
	vector<ll> scores(k);
	rep(i, 0, k) cin >> pat[i] >> scores[i];
	cin >> s;

	AhoCorasick ac(pat, scores);

	ll score = 0;
	int cur_node = 0, cur_pos = 0;
	while (s[cur_pos] != '?' && cur_pos < sz(s)) {
		cur_node = ac.N[cur_node].next[s[cur_pos] - ac.first];
		score += ac.N[cur_node].nmatches;
		cur_pos++;
	}

	ac.precompute();

	for (int i = sz(pos); i >= 0; i--) {
		trav(mask, nums[i]) {
			rep(j, 0, sz(ac.N)) {
				if (i == sz(pos)) {
					dp[mask][j] = 0;
					continue;
				}
				rep(k, 0, ac.alpha) {
					if ((mask >> k) & 1) continue;
					int next_c = ac.N[j].next[k];
					int nmask = mask | (1 << k);
					ll res = pc[i][next_c].first + dp[nmask][pc[i][next_c].second];
					dp[mask][j] = max(dp[mask][j], res);
				}
			}
		}
	}

	cout << (score + dp[0][cur_node]) << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = a; i < (b); i++)
#define trav(a, x) for (auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int) (x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;

string s;
vector<vector<ll>> dp;
vector<vector<pair<ll, int>>> pc;
vi pos;

struct AhoCorasick {
	enum { alpha = 14, first = 'a' };

	struct Node {
		int back, next[alpha];
		ll nmatches = 0;
		Node(int v) { memset(next, v, sizeof(next)); }
	};

	vector<Node> N;
	vi backp;

	void insert(string& s, ll score) {
		assert(!s.empty());
		int n = 0;
		trav(c, s) {
			int &m = N[n].next[c - first];
			if (m == -1) {
				n = m = sz(N);
				N.emplace_back(-1);
			} else n = m;
		}

		N[n].nmatches += score;
	}

	AhoCorasick(vector<string>& pat, vector<ll>& scores) {
		N.emplace_back(-1);
		rep(i, 0, sz(pat)) insert(pat[i], scores[i]);
		N[0].back = sz(N);
		N.emplace_back(0);

		rep(i, 0, sz(s)) if (s[i] == '?') pos.push_back(i);

		dp = vector<vector<ll>>(1 << 14, vector<ll>(sz(N), LONG_MIN));
		pc = vector<vector<pair<ll, int>>>(sz(pos), vector<pair<ll, int>>(sz(N)));

		queue<int> q;
		for (q.push(0); !q.empty(); q.pop()) {
			int n = q.front(), prev = N[n].back;
			rep(i, 0, alpha) {
				int &ed = N[n].next[i], y = N[prev].next[i];
				if (ed == -1) ed = y;
				else {
					N[ed].back = y;
					N[ed].nmatches += N[y].nmatches;
					q.push(ed);
				}
			}
		}
	}

	void precompute() {
		rep(i, 0, sz(pos)) {
			int start = pos[i];
			rep(j, 0, sz(N)) {
				ll score = 0;
				int cur_pos = start;
				int cur_node = j;

				while (true) {
					score += N[cur_node].nmatches;
					cur_pos++;
					if (cur_pos == sz(s) || s[cur_pos] == '?') break;
					cur_node = N[cur_node].next[s[cur_pos] - first];
				}

				pc[i][j].first = score;
				pc[i][j].second = cur_node;
			}
		}
	}

	ll compute(int i, int mask, int c) {
		if (i == sz(pos)) return 0;
		if (dp[mask][c] != LONG_MIN) return dp[mask][c];

		ll sol = LONG_MIN;
		rep(j, 0, alpha) if (mask >> j & 1) {
			int next_c = N[c].next[j];
			ll res = compute(i + 1, (mask ^ (1 << j)), pc[i][next_c].second);
			sol = max(sol, pc[i][next_c].first + res);
		}

		return dp[mask][c] = sol;
	}
};

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	vector<vi> nums(15);
	rep(i, 0, 1 << 14) nums[__builtin_popcount(i)].push_back(i);

	int k;
	cin >> k;

	vector<string> pat(k);
	vector<ll> scores(k);
	rep(i, 0, k) cin >> pat[i] >> scores[i];
	cin >> s;

	AhoCorasick ac(pat, scores);

	ll score = 0;
	int cur_node = 0, cur_pos = 0;
	while (s[cur_pos] != '?' && cur_pos < sz(s)) {
		cur_node = ac.N[cur_node].next[s[cur_pos] - ac.first];
		score += ac.N[cur_node].nmatches;
		cur_pos++;
	}

	ac.precompute();

	for (int i = sz(pos); i >= 0; i--) {
		trav(mask, nums[i]) {
			rep(j, 0, sz(ac.N)) {
				if (i == sz(pos)) {
					dp[mask][j] = 0;
					continue;
				}
				//cout << "start" << endl;
				//cout << mask << " " << j << endl;
				rep(k, 0, ac.alpha) if (((mask >> k) & 1) == 0) {
					int next_c = ac.N[j].next[k];
					int nmask = mask ^ (1 << k);
					//cout << next_c << " " << nmask << endl;
					ll res = pc[i][next_c].first + dp[nmask][pc[i][next_c].second];
					dp[mask][j] = max(dp[mask][j], res);
				}
				//cout << mask << " " << j << " " << dp[mask][j] << endl;
			}
		}
	}

	cout << (score  + dp[0][cur_node]) << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = a; i < (b); i++)
#define trav(a, x) for (auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int) (x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;

string s;
vector<vector<ll>> dp;
vector<vector<pair<ll, int>>> pc;
vi pos;

struct AhoCorasick {
	enum { alpha = 14, first = 'a' };

	struct Node {
		int back, next[alpha];
		ll nmatches = 0;
		Node(int v) { memset(next, v, sizeof(next)); }
	};

	vector<Node> N;
	vi backp;

	void insert(string& s, ll score) {
		assert(!s.empty());
		int n = 0;
		trav(c, s) {
			int &m = N[n].next[c - first];
			if (m == -1) {
				n = m = sz(N);
				N.emplace_back(-1);
			} else n = m;
		}

		N[n].nmatches += score;
	}

	AhoCorasick(vector<string>& pat, vector<ll>& scores) {
		N.emplace_back(-1);
		rep(i, 0, sz(pat)) insert(pat[i], scores[i]);
		N[0].back = sz(N);
		N.emplace_back(0);

		rep(i, 0, sz(s)) if (s[i] == '?') pos.push_back(i);

		dp = vector<vector<ll>>(1 << 14, vector<ll>(sz(N), LLONG_MIN));
		pc = vector<vector<pair<ll, int>>>(sz(pos),
				vector<pair<ll, int>>(sz(N)));

		queue<int> q;
		for (q.push(0); !q.empty(); q.pop()) {
			int n = q.front(), prev = N[n].back;
			rep(i, 0, alpha) {
				int &ed = N[n].next[i], y = N[prev].next[i];
				if (ed == -1) ed = y;
				else {
					N[ed].back = y;
					N[ed].nmatches += N[y].nmatches;
					q.push(ed);
				}
			}
		}
	}

	void precompute() {
		rep(i, 0, sz(pos)) {
			int start = pos[i];
			rep(j, 0, sz(N)) {
				ll score = 0;
				int cur_pos = start;
				int cur_node = j;

				while (true) {
					score += N[cur_node].nmatches;
					cur_pos++;
					if (cur_pos == sz(s) || s[cur_pos] == '?') break;
					cur_node = N[cur_node].next[s[cur_pos] - first];
				}

				pc[i][j].first = score;
				pc[i][j].second = cur_node;
			}
		}
	}

	ll compute(int i, int mask, int c) {
		if (i == sz(pos)) return 0;
		if (dp[mask][c] != LONG_MIN) return dp[mask][c];

		ll sol = LLONG_MIN;
		rep(j, 0, alpha) if (mask >> j & 1) {
			int next_c = N[c].next[j];
			ll res = compute(i + 1, (mask ^ (1 << j)), pc[i][next_c].second);
			sol = max(sol, pc[i][next_c].first + res);
		}

		return dp[mask][c] = sol;
	}
};

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int k;
	cin >> k;

	vector<string> pat(k);
	vector<ll> scores(k);
	rep(i, 0, k) cin >> pat[i] >> scores[i];
	cin >> s;

	AhoCorasick ac(pat, scores);

	ll score = 0;
	int cur_node = 0, cur_pos = 0;
	while (s[cur_pos] != '?' && cur_pos < sz(s)) {
		cur_node = ac.N[cur_node].next[s[cur_pos] - ac.first];
		score += ac.N[cur_node].nmatches;
		cur_pos++;
	}

	ac.precompute();

	cout << (score  + ac.compute(0, (1 << 14) - 1, cur_node)) << endl;

	return 0;
}


#include<bits/stdc++.h>
#define int long long

using namespace std;

const int maxn = 1025;
const int alpha = ('n' - 'a') + 1;

struct Aho_Corasick{
  int count_node;
  int value[maxn];
  int nxt[maxn][alpha];
  int f[maxn];
  int trie[maxn][alpha];

  Aho_Corasick() {
    for(int i = 0; i < alpha; ++i) {
      trie[0][i] = ++count_node;
    }
  }

  void add(string s, int v) {
    int node = 0;
    for(auto c : s) {
      c -= 'a';
      if(trie[node][c] == 0) trie[node][c] = ++count_node;
      node = trie[node][c];
    }
    value[node] += v;
  }

  void process() {
    queue<int> bfs; bfs.push(0);
    while(!bfs.empty()) {
      int v = bfs.front(); bfs.pop();
      for(int i = 0; i < alpha; ++i) {
        int t = trie[v][i];
        if(t == 0) continue;
        bfs.push(t);
        if(v == 0) continue;
        int cur = f[v];
        while(trie[cur][i] == 0) cur = f[cur];
        f[t] = trie[cur][i];
      }
    }

    for(int i = 0; i <= count_node; ++i) {
      for(int j = 0; j < alpha; ++j) {
        if(trie[i][j] == 0) nxt[i][j] = nxt[f[i]][j];
        else nxt[i][j] = trie[i][j];
      }
      value[i] += value[f[i]];
    }
  }

  int go(int i, int j) {
    return nxt[i][j];
  }

  int getVal(int i) {
    return value[i];
  }
}aho;

int n, m;
int valid[maxn];

int cst[maxn][alpha + 5];
int jump[maxn][alpha + 5];

int f[1 << alpha][maxn];

main() {
  ios_base::sync_with_stdio(false); cin.tie(NULL);

  cin >> m;
  while(m--) {
    string s; int v;
    cin >> s >> v;
    aho.add(s, v);
  }

  aho.process();

  string s; cin >> s;
  vector<int> pos;
  for(int i = 0; i < s.size(); ++i) {
    if(s[i] == '?') pos.push_back(i);
  }
  pos.push_back(s.size());

  int n = aho.count_node + 1;
  for(int j = 0; j < n; ++j) {
    int last = 0;
    for(int i = 0; i < pos.size(); ++i) {
      int cur = j, p = pos[i];
      for(int t = last; t < p; ++t) {
        cur = aho.go(cur, s[t] - 'a');
        cst[j][i] += aho.getVal(cur);
      }
      jump[j][i] = cur;
      last = p + 1;
    }
  }

  memset(f, -62, sizeof f);

  f[0][jump[0][0]] = cst[0][0];
  int ans = -1e9;

  int q = pos.size() - 1;
  for(int mask = 0; mask < (1 << alpha); ++mask) {
    int c = __builtin_popcount(mask);
    if(c >= q) {
      for(int node = 0; node < n; ++node) {
        ans = max(ans, f[mask][node]);
      }
      continue;
    }
    for(int i = 0; i < alpha; ++i) {
      if(mask & (1 << i)) continue;
      int newmask = mask ^ (1 << i);
      for(int node = 0; node < n; ++node) {
        int newnode = jump[aho.go(node, i)][c + 1];
        int newcost = f[mask][node] + aho.getVal(aho.go(node, i)) + cst[aho.go(node, i)][c + 1];
        f[newmask][newnode] = max(f[newmask][newnode], newcost);
      }
    }
  }

  cout << ans << endl;

  return 0;
}


#include<bits/stdc++.h>

using namespace std;

const int maxn = 1025;
const int alpha = int('n' - 'a') + 1;

struct Aho_Corasick{
  int count_node;
  int value[maxn];
  int nxt[maxn][alpha];
  int f[maxn];
  int trie[maxn][alpha];

  Aho_Corasick() {
    for(int i = 0; i < alpha; ++i) {
      trie[0][i] = ++count_node;
    }
  }

  void add(string s, int v) {
    int node = 0;
    for(auto c : s) {
      c -= 'a';
      if(trie[node][c] == 0) trie[node][c] = ++count_node;
      node = trie[node][c];
    }
    value[node] += v;
  }

  void process() {
    queue<int> bfs; bfs.push(0);
    while(!bfs.empty()) {
      int v = bfs.front(); bfs.pop();
      for(int i = 0; i < alpha; ++i) {
        int t = trie[v][i];
        if(t == 0) continue;
        bfs.push(t);
        if(v == 0) continue;
        int cur = f[v];
        while(trie[cur][i] == 0) cur = f[cur];
        f[t] = trie[cur][i];
      }
    }

    for(int i = 0; i <= count_node; ++i) {
      for(int j = 0; j < alpha; ++j) {
        if(trie[i][j] == 0) nxt[i][j] = nxt[f[i]][j];
        else nxt[i][j] = trie[i][j];
      }
      value[i] += value[f[i]];
    }
  }

  int go(int i, int j) {
    return nxt[i][j];
  }

  int getVal(int i) {
    return value[i];
  }
}aho;

int n, m;
int valid[maxn];

int cst[maxn][alpha + 5];
int jump[maxn][alpha + 5];

int f[1 << alpha][maxn];

int main() {
  ios_base::sync_with_stdio(false); cin.tie(NULL);

  cin >> m;
  while(m--) {
    string s; int v;
    cin >> s >> v;
    aho.add(s, v);
  }

  aho.process();

  string s; cin >> s;
  vector<int> pos;
  for(int i = 0; i < s.size(); ++i) {
    if(s[i] == '?') pos.push_back(i);
  }
  pos.push_back(s.size());

  int n = aho.count_node + 1;
  for(int j = 0; j < n; ++j) {
    int last = 0;
    for(int i = 0; i < pos.size(); ++i) {
      int cur = j, p = pos[i];
      for(int t = last; t < p; ++t) {
        cur = aho.go(cur, s[t] - 'a');
        cst[j][i] += aho.getVal(cur);
      }
      jump[j][i] = cur;
      last = p + 1;
    }
  }

  memset(f, -62, sizeof f);

  f[0][jump[0][0]] = cst[0][0];
  int ans = -1e9;

  int q = pos.size() - 1;
  for(int mask = 0; mask < (1 << alpha); ++mask) {
    int c = __builtin_popcount(mask);
    if(c >= q) {
      for(int node = 0; node < n; ++node) {
        ans = max(ans, f[mask][node]);
      }
      continue;
    }
    for(int i = 0; i < alpha; ++i) {
      if(mask & (1 << i)) continue;
      int newmask = mask ^ (1 << i);
      for(int node = 0; node < n; ++node) {
        int newnode = jump[aho.go(node, i)][c + 1];
        int newcost = f[mask][node] + aho.getVal(aho.go(node, i)) + cst[aho.go(node, i)][c + 1];
        f[newmask][newnode] = max(f[newmask][newnode], newcost);
      }
    }
  }

  cout << ans << endl;

  return 0;
}


#include<bits/stdc++.h>
#define int long long

using namespace std;

const int maxn = 1025;
const int alpha = ('n' - 'a') + 1;

struct Aho_Corasick{
  int count_node;
  int value[maxn];
  int nxt[maxn][alpha];
  int f[maxn];
  int trie[maxn][alpha];

  Aho_Corasick() {
    for(int i = 0; i < alpha; ++i) {
      trie[0][i] = ++count_node;
    }
  }

  void add(string s, int v) {
    int node = 0;
    for(auto c : s) {
      c -= 'a';
      if(trie[node][c] == 0) trie[node][c] = ++count_node;
      node = trie[node][c];
    }
    value[node] += v;
  }

  void process() {
    queue<int> bfs; bfs.push(0);
    while(!bfs.empty()) {
      int v = bfs.front(); bfs.pop();
      for(int i = 0; i < alpha; ++i) {
        int t = trie[v][i];
        if(t == 0) continue;
        bfs.push(t);
        if(v == 0) continue;
        int cur = f[v];
        while(trie[cur][i] == 0) cur = f[cur];
        f[t] = trie[cur][i];
      }
    }

    for(int i = 0; i <= count_node; ++i) {
      for(int j = 0; j < alpha; ++j) {
        if(trie[i][j] == 0) nxt[i][j] = nxt[f[i]][j];
        else nxt[i][j] = trie[i][j];
      }
      value[i] += value[f[i]];
    }
  }

  int go(int i, int j) {
    return nxt[i][j];
  }

  int getVal(int i) {
    return value[i];
  }
}aho;

int n, m;
int valid[maxn];

int cst[maxn][alpha + 5];
int jump[maxn][alpha + 5];

int f[1 << alpha][maxn];

main() {
  ios_base::sync_with_stdio(false); cin.tie(NULL);

  cin >> m;
  while(m--) {
    string s; int v;
    cin >> s >> v;
    aho.add(s, v);
  }

  aho.process();

  string s; cin >> s;
  vector<int> pos;
  for(int i = 0; i < s.size(); ++i) {
    if(s[i] == '?') pos.push_back(i);
  }
  pos.push_back(s.size());

  int n = aho.count_node + 1;
  for(int j = 0; j < n; ++j) {
    int last = 0;
    for(int i = 0; i < pos.size(); ++i) {
      int cur = j, p = pos[i];
      for(int t = last; t < p; ++t) {
        cur = aho.go(cur, s[t] - 'a');
        cst[j][i] += aho.getVal(cur);
      }
      jump[j][i] = cur;
      last = p + 1;
    }
  }

  memset(f, -62, sizeof f);

  f[0][jump[0][0]] = cst[0][0];
  int ans = -1e18;

  int q = pos.size() - 1;
  for(int mask = 0; mask < (1 << alpha); ++mask) {
    int c = __builtin_popcount(mask);
    if(c >= q) {
      for(int node = 0; node < n; ++node) {
        ans = max(ans, f[mask][node]);
      }
      continue;
    }
    for(int i = 0; i < alpha; ++i) {
      if(mask & (1 << i)) continue;
      int newmask = mask ^ (1 << i);
      for(int node = 0; node < n; ++node) {
        int newnode = jump[aho.go(node, i)][c + 1];
        int newcost = f[mask][node] + aho.getVal(aho.go(node, i)) + cst[aho.go(node, i)][c + 1];
        f[newmask][newnode] = max(f[newmask][newnode], newcost);
      }
    }
  }

  cout << ans << endl;

  return 0;
}


#include<bits/stdc++.h>
#define int long long

using namespace std;

const int maxn = 1025;
const int alpha = int('n' - 'a') + 1;

struct Aho_Corasick{
  int count_node;
  int value[maxn];
  int nxt[maxn][alpha];
  int f[maxn];
  int trie[maxn][alpha];

  Aho_Corasick() {
    for(int i = 0; i < alpha; ++i) {
      trie[0][i] = ++count_node;
    }
  }

  void add(string s, int v) {
    int node = 0;
    for(auto c : s) {
      c -= 'a';
      if(trie[node][c] == 0) trie[node][c] = ++count_node;
      node = trie[node][c];
    }
    value[node] += v;
  }

  void process() {
    queue<int> bfs; bfs.push(0);
    while(!bfs.empty()) {
      int v = bfs.front(); bfs.pop();
      for(int i = 0; i < alpha; ++i) {
        int t = trie[v][i];
        if(t == 0) continue;
        bfs.push(t);
        if(v == 0) continue;
        int cur = f[v];
        while(trie[cur][i] == 0) cur = f[cur];
        f[t] = trie[cur][i];
      }
    }

    for(int i = 0; i <= count_node; ++i) {
      for(int j = 0; j < alpha; ++j) {
        if(trie[i][j] == 0) nxt[i][j] = nxt[f[i]][j];
        else nxt[i][j] = trie[i][j];
      }
      value[i] += value[f[i]];
    }
  }

  int go(int i, int j) {
    return nxt[i][j];
  }

  int getVal(int i) {
    return value[i];
  }
}aho;

int n, m;
int valid[maxn];

int cst[maxn][alpha + 5];
int jump[maxn][alpha + 5];

int f[1 << alpha][maxn];

main() {
  ios_base::sync_with_stdio(false); cin.tie(NULL);

  cin >> m;
  while(m--) {
    string s; int v;
    cin >> s >> v;
    aho.add(s, v);
  }

  aho.process();

  string s; cin >> s;
  vector<int> pos;
  for(int i = 0; i < s.size(); ++i) {
    if(s[i] == '?') pos.push_back(i);
  }
  pos.push_back(s.size());

  int n = aho.count_node + 1;
  for(int j = 0; j < n; ++j) {
    int last = 0;
    for(int i = 0; i < pos.size(); ++i) {
      int cur = j, p = pos[i];
      for(int t = last; t < p; ++t) {
        cur = aho.go(cur, s[t] - 'a');
        cst[j][i] += aho.getVal(cur);
      }
      jump[j][i] = cur;
      last = p + 1;
    }
  }

  memset(f, -62, sizeof f);

  f[0][jump[0][0]] = cst[0][0];
  int ans = -1e9;

  int q = pos.size() - 1;
  for(int mask = 0; mask < (1 << alpha); ++mask) {
    int c = __builtin_popcount(mask);
    if(c >= q) {
      for(int node = 0; node < n; ++node) {
        ans = max(ans, f[mask][node]);
      }
      continue;
    }
    for(int i = 0; i < alpha; ++i) {
      if(mask & (1 << i)) continue;
      int newmask = mask ^ (1 << i);
      for(int node = 0; node < n; ++node) {
        int newnode = jump[aho.go(node, i)][c + 1];
        int newcost = f[mask][node] + aho.getVal(aho.go(node, i)) + cst[aho.go(node, i)][c + 1];
        f[newmask][newnode] = max(f[newmask][newnode], newcost);
      }
    }
  }

  cout << ans << endl;

  return 0;
}


#include<bits/stdc++.h>
#define int long long

using namespace std;

const int maxn = 1025;
const int alpha = ('n' - 'a') + 1;

struct Aho_Corasick{
  int count_node;
  int value[maxn];
  int nxt[maxn][alpha];
  int f[maxn];
  int trie[maxn][alpha];
  vector<int> order;

  Aho_Corasick() {
    for(int i = 0; i < alpha; ++i) {
      trie[0][i] = ++count_node;
    }
  }

  int add(string s, int v) {
    int node = 0;
    for(auto c : s) {
      c -= 'a';
      if(trie[node][c] == 0) trie[node][c] = ++count_node;
      node = trie[node][c];
    }
    value[node] += v;

    return node;
  }

  void process() {
    queue<int> bfs; bfs.push(0);
    while(!bfs.empty()) {
      int v = bfs.front(); bfs.pop();
      order.push_back(v);
      for(int i = 0; i < alpha; ++i) {
        int t = trie[v][i];
        if(t == 0) continue;
        bfs.push(t);
        if(v == 0) continue;
        int cur = f[v];
        while(trie[cur][i] == 0) cur = f[cur];
        f[t] = trie[cur][i];
      }
      for(int j = 0; j < alpha; ++j) {
        if(trie[v][j] == 0) nxt[v][j] = nxt[f[v]][j];
        else nxt[v][j] = trie[v][j];
      }
      value[v] += value[f[v]];
    }
  }

  int go(int i, int j) {
    return nxt[i][j];
  }

  int getVal(int i) {
    return value[i];
  }
}aho;

int n, m;
int f[1 << alpha][maxn];
int cst[maxn][alpha + 5];
int jump[maxn][alpha + 5];

main() {
  ios_base::sync_with_stdio(false); cin.tie(NULL);

  cin >> m;
  while(m--) {
    string s; int v;
    cin >> s >> v;
    aho.add(s, v);
  }

  aho.process();

  string s; cin >> s;
  vector<int> pos;
  for(int i = 0; i < s.size(); ++i) {
    if(s[i] == '?') pos.push_back(i);
  }
  pos.push_back(s.size());

  int n = aho.count_node + 1;
  for(int j = 0; j < n; ++j) {
    int last = 0;
    for(int i = 0; i < pos.size(); ++i) {
      int cur = j, p = pos[i];
      for(int t = last; t < p; ++t) {
        cur = aho.go(cur, s[t] - 'a');
        cst[j][i] += aho.getVal(cur);
      }
      jump[j][i] = cur;
      last = p + 1;
    }
  }

  memset(f, -60, sizeof f);

  f[0][jump[0][0]] = cst[0][0];
  int ans = -1e18;

  int q = pos.size() - 1;
  for(int mask = 0; mask < (1 << alpha); ++mask) {
    int c = __builtin_popcount(mask);
    if(c == q) {
      for(int node = 0; node < n; ++node) {
        ans = max(ans, f[mask][node]);
      }
      continue;
    }
    for(int i = 0; i < alpha; ++i) {
      if(mask & (1 << i)) continue;
      int newmask = mask ^ (1 << i);
      for(int node = 0; node < n; ++node) {
        int newnode = jump[aho.go(node, i)][c + 1];
        int newcost = f[mask][node] + aho.getVal(aho.go(node, i)) + cst[aho.go(node, i)][c + 1];
        f[newmask][newnode] = max(f[newmask][newnode], newcost);
      }
    }
  }

  cout << ans << endl;

  return 0;
}


#include<bits/stdc++.h>
#define int long long

using namespace std;

const int maxn = 1025;
const int alpha = ('n' - 'a') + 1;

struct Aho_Corasick{
  int count_node;
  int value[maxn];
  int nxt[maxn][alpha];
  int f[maxn];
  int trie[maxn][alpha];

  Aho_Corasick() {
    for(int i = 0; i < alpha; ++i) {
      trie[0][i] = ++count_node;
    }
  }

  void add(string s, int v) {
    int node = 0;
    for(auto c : s) {
      c -= 'a';
      if(trie[node][c] == 0) trie[node][c] = ++count_node;
      node = trie[node][c];
    }
    value[node] += v;
  }

  void process() {
    queue<int> bfs; bfs.push(0);
    while(!bfs.empty()) {
      int v = bfs.front(); bfs.pop();
      for(int i = 0; i < alpha; ++i) {
        int t = trie[v][i];
        if(t == 0) continue;
        bfs.push(t);
        if(v == 0) continue;
        int cur = f[v];
        while(trie[cur][i] == 0) cur = f[cur];
        f[t] = trie[cur][i];
      }
    }

    for(int i = 0; i <= count_node; ++i) {
      for(int j = 0; j < alpha; ++j) {
        if(trie[i][j] == 0) nxt[i][j] = nxt[f[i]][j];
        else nxt[i][j] = trie[i][j];
      }
      value[i] += value[f[i]];
    }
  }

  int go(int i, int j) {
    return nxt[i][j];
  }

  int getVal(int i) {
    return value[i];
  }
}aho;

int n, m;
int f[1 << alpha][maxn];
int cst[maxn][alpha + 5];
int jump[maxn][alpha + 5];

main() {
  ios_base::sync_with_stdio(false); cin.tie(NULL);

  cin >> m;
  while(m--) {
    string s; int v;
    cin >> s >> v;
    aho.add(s, v);
  }

  aho.process();

  string s; cin >> s;
  vector<int> pos;
  for(int i = 0; i < s.size(); ++i) {
    if(s[i] == '?') pos.push_back(i);
  }
  pos.push_back(s.size());

  int n = aho.count_node + 1;
  for(int j = 0; j < n; ++j) {
    int last = 0;
    for(int i = 0; i < pos.size(); ++i) {
      int cur = j, p = pos[i];
      for(int t = last; t < p; ++t) {
        cur = aho.go(cur, s[t] - 'a');
        cst[j][i] += aho.getVal(cur);
      }
      jump[j][i] = cur;
      last = p + 1;
    }
  }

  memset(f, -60, sizeof f);

  f[0][jump[0][0]] = cst[0][0];
  int ans = -1e18;

  int q = pos.size() - 1;
  for(int mask = 0; mask < (1 << alpha); ++mask) {
    int c = __builtin_popcount(mask);
    if(c == q) {
      for(int node = 0; node < n; ++node) {
        ans = max(ans, f[mask][node]);
      }
      continue;
    }
    for(int i = 0; i < alpha; ++i) {
      if(mask & (1 << i)) continue;
      int newmask = mask ^ (1 << i);
      for(int node = 0; node < n; ++node) {
        int newnode = jump[aho.go(node, i)][c + 1];
        int newcost = f[mask][node] + aho.getVal(aho.go(node, i)) + cst[aho.go(node, i)][c + 1];
        f[newmask][newnode] = max(f[newmask][newnode], newcost);
      }
    }
  }

  cout << ans << endl;

  return 0;
}


#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <thread>
#include <unordered_set>
#include <vector>
#include <memory.h>
#include <list>
#include <map>
#include <unordered_map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <stdio.h>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <random>
#include <string>
#include <cassert>

#define getcx _getchar_nolock

using namespace std;

namespace std
{
	string to_string(string const& s) { return '"' + s + '"'; }
	string to_string(char c) { return string(1, c); }
	string to_string(const char* s) { return to_string((string)s); }
	string to_string(bool b) { return (b ? "true" : "false"); }

	template <class T1, class T2>
	string to_string(pair<T1, T2> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }

	template <class T>
	string to_string(T c)
	{
		string s = "[";
		for (auto vvv : c) { s += to_string(vvv) + ","; }
		s += "]";
		return s;
	}

	void debug_impl() { cerr << endl; };

	template <typename T1, typename... T2>
	void debug_impl(T1 a, T2 ... b)
	{
		cerr << " " << to_string(a);
		debug_impl(b...);
	}
}

template <typename T>
struct reversion_wrapper
{
	T& iterable;
};

template <typename T>
auto begin(reversion_wrapper<T> w) { return std::rbegin(w.iterable); }

template <typename T>
auto end(reversion_wrapper<T> w) { return std::rend(w.iterable); }

template <typename T>
reversion_wrapper<T> reverse(T&& iterable) { return { iterable }; }

template<class T>T gcd(T a, T b) { while (a && b)if (a > b)a %= b; else b %= a; return a + b; }
template<class T>T powmod(T a, T b, T mod) { if (b == 0)return 1 % mod; T res = powmod(a, b / 2, mod); res *= res; res %= mod; if (b & 1) { res *= a; res %= mod; } return res; }
template<class T>T inv(T a, T mod) { return powmod(a, mod - 2, mod); }

#ifdef __ASD__
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_impl(__VA_ARGS__)
#define endl "\n"
#else
#define dbg(...) ;
#define endl "\n"
#endif

#define lng long long

lng const MOD = 998244353;

int const ALPHA = 14;

vector<vector<int>> go;
vector<vector<int>> go_r;
vector<int> link;
vector<int> word_end;
vector<lng> state_cost;

int trie_sz = 1;
vector<string> word;
vector<lng> cost;
map<int, vector<pair<int,lng>>> skip_letters;

vector<vector<lng>> dp;
vector<vector<lng>> dp2;

void trie_add(string const &s, int idx) {
	int u = 0;
	for(char c:s) {
		int i = c-'a';
		if (go[u][i]==-1) {
			go[u][i] = trie_sz++;
			go.push_back(vector<int>(ALPHA, -1));
			word_end.push_back(-1);
		}

		u = go[u][i];
	}

	word_end[u] = idx;
}

void trie_build_links() {
	link[0] = 0;
	queue<int> q;
	for(int c=0;c<ALPHA;c++) {
		if (go[0][c]==-1)continue;
		link[go[0][c]] = 0;
		q.push(go[0][c]);
	}

	for(int i=0;i<ALPHA;i++)if(go[0][i]==-1)go[0][i]=0;

	while (!q.empty()) {
		int u = q.front();
		q.pop();

		for(int i=0;i<ALPHA;i++) {
			if (go[u][i]==-1)continue;
			int v = go[u][i];
			int w = link[u];
			while (go[w][i]==-1)w=link[w];
			link[v]=go[w][i];
			q.push(v);
		}
	}
}

void calc_state_cost() {
	queue<int> q;
	for(int i=0;i<ALPHA;i++)if(go[0][i])q.push(go[0][i]);

	while (!q.empty()) {
		int u = q.front();
		q.pop();
		state_cost[u] = 0;
		if (word_end[u]!=-1) {
			state_cost[u] = cost[word_end[u]];
		}
		if (link[u] != u) {
			state_cost[u] += state_cost[link[u]];
		}
		for(int i=0;i<ALPHA;i++) {
			if (go[u][i]!=-1) q.push(go[u][i]);
		}
	}
}

void calc(string const &s, int l, int r) {
	if (l>=r) return;

	vector<pair<int, int>> res(trie_sz);

	for(int st=0;st<trie_sz;st++) {

		int v=st;
		lng sum = 0;

		for(int i=l;i<r;i++) {
			int c = s[i]-'a';
			v = go_r[v][c];
			sum += state_cost[v];
		}

		skip_letters[l].emplace_back(v, sum);
	}
}

int bc(int n) {
	if (n==0)return 0;
	return bc(n/2)+n%2;
}

int main()
{
#ifdef __ASD__
	auto start_t = chrono::steady_clock::now();
	freopen("input.txt", "r", stdin);
	//freopen("1nul", "w", stderr);
	//freopen("output.txt", "w", stdout);
#else
	ios_base::sync_with_stdio(false);
#endif

	int n;
	cin >> n;
	map<string,int> word_cost;
	for(int i=0;i<n;i++) {
		string s;
		int c;
		cin >> s >> c;
		word_cost[s]+=c;
	}

	for(auto &p:word_cost) {
		word.push_back(p.first);
		cost.push_back(p.second);
	}

	go.push_back(vector<int>(ALPHA, -1));
	word_end.push_back(-1);

	for(int i=0;i<word.size();i++) trie_add(word[i], i);

	link.resize(trie_sz);
	state_cost.resize(trie_sz);

	trie_build_links();
	calc_state_cost();

	string s;
	cin >> s;

	go_r.resize(trie_sz, vector<int>(ALPHA, -1));

	for(int st=0;st<trie_sz; st++) {
		for(int c=0;c<ALPHA;c++) {
			int u = st;
			while (go[u][c]==-1)u=link[u];
			go_r[st][c] = go[u][c];
		}
	}

	{
		int i = 0;
		while (i<s.length()) {
			if (s[i]=='?') {i++; continue;}
			int j=i;
			while (j<s.length()&&s[j]!='?')j++;

			calc(s, i, j);
			i=j;
		}
	}

	lng const INF = -2e18;

	dp = vector<vector<lng>> (trie_sz, vector<lng> (1<<ALPHA, INF));
	dp[0][0] = 0;

	{
		int i = 0;
		while (i<s.length()) {
			dp2 = vector<vector<lng>> (trie_sz, vector<lng> (1<<ALPHA, INF));

			if (s[i]=='?') {
				for(int st=0;st<trie_sz;st++) {
					for(int msk=0;msk<(1<<ALPHA);msk++) {
						if (dp[st][msk] == INF) continue;

						for(int c=0;c<ALPHA;c++) {
							if (msk & (1<<c)) continue;
							int v = st;
							v = go_r[v][c];
							int new_msk = msk | (1<<c);
							lng new_cost = dp[st][msk] + state_cost[v];
							if (new_cost > dp2[v][new_msk]) {
								dp2[v][new_msk] = new_cost;
							}
						}
					}
				}
				i++;
			} else {
				int j=i;
				while (j<s.length()&&s[j]!='?')j++;
				auto sk = skip_letters[i];
				for(int st=0;st<trie_sz;st++) {
					auto p = sk[st];
					for(int msk=0;msk<(1<<ALPHA);msk++) {
						if (dp[st][msk] == INF) continue;
						int v = p.first;
						lng new_cost = dp[st][msk] + p.second;
						int new_msk = msk;
						if (new_cost > dp2[v][new_msk]) {
							dp2[v][new_msk] = new_cost;
						}
					}
				}

				i = j;
			}
			dp=dp2;
		}
	}

	int q=0;
	for(char c:s)q+=c=='?';

	lng res=INF;

	for(int i=0;i<trie_sz;i++) {
		for(int msk=0;msk<(1<<ALPHA);msk++) {
			if (bc(msk)==q) {
				res = max(res, dp[i][msk]);
			}
		}
	}

	cout << res << endl;

#ifdef __ASD__
	auto finish_t = chrono::steady_clock::now();
	cerr << "Elapsed " << chrono::duration_cast<chrono::milliseconds>(finish_t - start_t).count() << " ms" << endl;
#endif
	return 0;
}


#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <thread>
#include <unordered_set>
#include <vector>
#include <memory.h>
#include <list>
#include <map>
#include <unordered_map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <stdio.h>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <random>
#include <string>
#include <cassert>

#define getcx _getchar_nolock

using namespace std;

namespace std
{
	string to_string(string const& s) { return '"' + s + '"'; }
	string to_string(char c) { return string(1, c); }
	string to_string(const char* s) { return to_string((string)s); }
	string to_string(bool b) { return (b ? "true" : "false"); }

	template <class T1, class T2>
	string to_string(pair<T1, T2> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }

	template <class T>
	string to_string(T c)
	{
		string s = "[";
		for (auto vvv : c) { s += to_string(vvv) + ","; }
		s += "]";
		return s;
	}

	void debug_impl() { cerr << endl; };

	template <typename T1, typename... T2>
	void debug_impl(T1 a, T2 ... b)
	{
		cerr << " " << to_string(a);
		debug_impl(b...);
	}
}

template <typename T>
struct reversion_wrapper
{
	T& iterable;
};

template <typename T>
auto begin(reversion_wrapper<T> w) { return std::rbegin(w.iterable); }

template <typename T>
auto end(reversion_wrapper<T> w) { return std::rend(w.iterable); }

template <typename T>
reversion_wrapper<T> reverse(T&& iterable) { return { iterable }; }

template<class T>T gcd(T a, T b) { while (a && b)if (a > b)a %= b; else b %= a; return a + b; }
template<class T>T powmod(T a, T b, T mod) { if (b == 0)return 1 % mod; T res = powmod(a, b / 2, mod); res *= res; res %= mod; if (b & 1) { res *= a; res %= mod; } return res; }
template<class T>T inv(T a, T mod) { return powmod(a, mod - 2, mod); }

#ifdef __ASD__
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_impl(__VA_ARGS__)
#define endl "\n"
#else
#define dbg(...) ;
#define endl "\n"
#endif

#define lng long long

lng const MOD = 998244353;

int const ALPHA = 14;

vector<vector<int>>  go;
vector<int> link;
vector<int> word_end;
vector<lng> state_cost;

int trie_sz = 1;
vector<string> word;
vector<lng> cost;
map<int, vector<pair<int,lng>>> skip_letters;

vector<vector<lng>> dp;
vector<vector<lng>> dp2;

void trie_add(string const &s, int idx) {
	int u = 0;
	for(char c:s) {
		int i = c-'a';
		if (go[u][i]==-1) {
			go[u][i] = trie_sz++;
			go.push_back(vector<int>(ALPHA, -1));
			word_end.push_back(-1);
		}

		u = go[u][i];
	}

	word_end[u] = idx;
}

void trie_build_links() {
	link[0] = 0;
	queue<int> q;
	for(int c=0;c<ALPHA;c++) {
		if (go[0][c]==-1)continue;
		link[go[0][c]] = 0;
		q.push(go[0][c]);
	}

	for(int i=0;i<ALPHA;i++)if(go[0][i]==-1)go[0][i]=0;

	while (!q.empty()) {
		int u = q.front();
		q.pop();

		for(int i=0;i<ALPHA;i++) {
			if (go[u][i]==-1)continue;
			int v = go[u][i];
			int w = link[u];
			while (go[w][i]==-1)w=link[w];
			link[v]=go[w][i];
			q.push(v);
		}
	}
}

void calc_state_cost() {
	queue<int> q;
	for(int i=0;i<ALPHA;i++)if(go[0][i])q.push(go[0][i]);

	while (!q.empty()) {
		int u = q.front();
		q.pop();
		state_cost[u] = 0;
		if (word_end[u]!=-1) {
			state_cost[u] = cost[word_end[u]];
		}
		if (link[u] != u) {
			state_cost[u] += state_cost[link[u]];
		}
		for(int i=0;i<ALPHA;i++) {
			if (go[u][i]!=-1) q.push(go[u][i]);
		}
	}
}

void calc(string const &s, int l, int r) {
	if (l>=r) return;

	vector<pair<int, int>> res(trie_sz);

	for(int st=0;st<trie_sz;st++) {

		int v=st;
		lng sum = 0;

		for(int i=l;i<r;i++) {
			int c = s[i]-'a';
			while (go[v][c]==-1) v = link[v];
			v = go[v][c];
			sum += state_cost[v];
		}

		skip_letters[l].emplace_back(v, sum);
	}
}

int bc(int n) {
	if (n==0)return 0;
	return bc(n/2)+n%2;
}

int main()
{
#ifdef __ASD__
	auto start_t = chrono::steady_clock::now();
	freopen("input.txt", "r", stdin);
	//freopen("1nul", "w", stderr);
	//freopen("output.txt", "w", stdout);
#else
	ios_base::sync_with_stdio(false);
#endif

	int n;
	cin >> n;
	map<string,int> word_cost;
	for(int i=0;i<n;i++) {
		string s;
		int c;
		cin >> s >> c;
		word_cost[s]+=c;
	}

	for(auto &p:word_cost) {
		word.push_back(p.first);
		cost.push_back(p.second);
	}

	go.push_back(vector<int>(ALPHA, -1));
	word_end.push_back(-1);

	for(int i=0;i<word.size();i++) trie_add(word[i], i);

	link.resize(trie_sz);
	state_cost.resize(trie_sz);

	trie_build_links();
	calc_state_cost();

	string s;
	cin >> s;

	{
		int i = 0;
		while (i<s.length()) {
			if (s[i]=='?') {i++; continue;}
			int j=i;
			while (j<s.length()&&s[j]!='?')j++;

			calc(s, i, j);
			i=j;
		}
	}

	lng const INF = -2e18;

	dp = vector<vector<lng>> (trie_sz, vector<lng> (1<<ALPHA, INF));
	dp[0][0] = 0;

	{
		int i = 0;
		while (i<s.length()) {
			dp2 = vector<vector<lng>> (trie_sz, vector<lng> (1<<ALPHA, INF));

			if (s[i]=='?') {
				for(int st=0;st<trie_sz;st++) {
					for(int msk=0;msk<(1<<ALPHA);msk++) {
						if (dp[st][msk] == INF) continue;

						for(int c=0;c<ALPHA;c++) {
							if (msk & (1<<c)) continue;
							int v = st;
							while (go[v][c]==-1)v = link[v];
							v = go[v][c];
							int new_msk = msk | (1<<c);
							lng new_cost = dp[st][msk] + state_cost[v];
							if (new_cost > dp2[v][new_msk]) {
								dp2[v][new_msk] = new_cost;
							}
						}
					}
				}
				i++;
			} else {
				int j=i;
				while (j<s.length()&&s[j]!='?')j++;
				auto sk = skip_letters[i];
				for(int st=0;st<trie_sz;st++) {
					auto p = sk[st];
					for(int msk=0;msk<(1<<ALPHA);msk++) {
						if (dp[st][msk] == INF) continue;
						int v = p.first;
						lng new_cost = dp[st][msk] + p.second;
						int new_msk = msk;
						if (new_cost > dp2[v][new_msk]) {
							dp2[v][new_msk] = new_cost;
						}
					}
				}

				i = j;
			}
			dp=dp2;
		}
	}

	int q=0;
	for(char c:s)q+=c=='?';

	lng res=INF;

	for(int i=0;i<trie_sz;i++) {
		for(int msk=0;msk<(1<<ALPHA);msk++) {
			if (bc(msk)==q) {
				res = max(res, dp[i][msk]);
			}
		}
	}

	cout << res << endl;

#ifdef __ASD__
	auto finish_t = chrono::steady_clock::now();
	cerr << "Elapsed " << chrono::duration_cast<chrono::milliseconds>(finish_t - start_t).count() << " ms" << endl;
#endif
	return 0;
}


#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <thread>
#include <unordered_set>
#include <vector>
#include <memory.h>
#include <list>
#include <map>
#include <unordered_map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <stdio.h>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <random>
#include <string>
#include <cassert>

#define getcx _getchar_nolock

using namespace std;

namespace std
{
	string to_string(string const& s) { return '"' + s + '"'; }
	string to_string(char c) { return string(1, c); }
	string to_string(const char* s) { return to_string((string)s); }
	string to_string(bool b) { return (b ? "true" : "false"); }

	template <class T1, class T2>
	string to_string(pair<T1, T2> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }

	template <class T>
	string to_string(T c)
	{
		string s = "[";
		for (auto vvv : c) { s += to_string(vvv) + ","; }
		s += "]";
		return s;
	}

	void debug_impl() { cerr << endl; };

	template <typename T1, typename... T2>
	void debug_impl(T1 a, T2 ... b)
	{
		cerr << " " << to_string(a);
		debug_impl(b...);
	}
}

template <typename T>
struct reversion_wrapper
{
	T& iterable;
};

template <typename T>
auto begin(reversion_wrapper<T> w) { return std::rbegin(w.iterable); }

template <typename T>
auto end(reversion_wrapper<T> w) { return std::rend(w.iterable); }

template <typename T>
reversion_wrapper<T> reverse(T&& iterable) { return { iterable }; }

template<class T>T gcd(T a, T b) { while (a && b)if (a > b)a %= b; else b %= a; return a + b; }
template<class T>T powmod(T a, T b, T mod) { if (b == 0)return 1 % mod; T res = powmod(a, b / 2, mod); res *= res; res %= mod; if (b & 1) { res *= a; res %= mod; } return res; }
template<class T>T inv(T a, T mod) { return powmod(a, mod - 2, mod); }

#ifdef __ASD__
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_impl(__VA_ARGS__)
#define endl "\n"
#else
#define dbg(...) ;
#define endl "\n"
#endif

#define lng long long

lng const MOD = 998244353;

int const ALPHA = 14;

vector<vector<int>>  go;
vector<int> link;
vector<int> word_end;
vector<int> state_cost;

int trie_sz = 1;
vector<string> word;
vector<int> cost;
map<int, vector<pair<int,int>>> skip_letters;

vector<vector<int>> dp;
vector<vector<int>> dp2;

void trie_add(string const &s, int idx) {
	int u = 0;
	for(char c:s) {
		int i = c-'a';
		if (go[u][i]==-1) {
			go[u][i] = trie_sz++;
			go.push_back(vector<int>(ALPHA, -1));
			word_end.push_back(-1);
		}

		u = go[u][i];
	}

	word_end[u] = idx;
}

void trie_build_links() {
	link[0] = 0;
	queue<int> q;
	for(int c=0;c<ALPHA;c++) {
		if (go[0][c]==-1)continue;
		link[go[0][c]] = 0;
		q.push(go[0][c]);
	}

	for(int i=0;i<ALPHA;i++)if(go[0][i]==-1)go[0][i]=0;

	while (!q.empty()) {
		int u = q.front();
		q.pop();

		for(int i=0;i<ALPHA;i++) {
			if (go[u][i]==-1)continue;
			int v = go[u][i];
			int w = link[u];
			while (go[w][i]==-1)w=link[w];
			link[v]=go[w][i];
			q.push(v);
		}
	}
}

void calc_state_cost() {
	queue<int> q;
	for(int i=0;i<ALPHA;i++)if(go[0][i])q.push(go[0][i]);

	while (!q.empty()) {
		int u = q.front();
		q.pop();
		state_cost[u] = 0;
		if (word_end[u]!=-1) {
			state_cost[u] = cost[word_end[u]];
		}
		if (link[u] != u) {
			state_cost[u] += state_cost[link[u]];
		}
		for(int i=0;i<ALPHA;i++) {
			if (go[u][i]!=-1) q.push(go[u][i]);
		}
	}
}

void calc(string const &s, int l, int r) {
	if (l>=r) return;

	vector<pair<int, int>> res(trie_sz);

	for(int st=0;st<trie_sz;st++) {

		int v=st;
		int sum = 0;

		for(int i=l;i<r;i++) {
			int c = s[i]-'a';
			while (go[v][c]==-1) v = link[v];
			v = go[v][c];
			sum += state_cost[v];
		}

		skip_letters[l].emplace_back(v, sum);
	}
}

int bc(int n) {
	if (n==0)return 0;
	return bc(n/2)+n%2;
}

int main()
{
#ifdef __ASD__
	auto start_t = chrono::steady_clock::now();
	freopen("input.txt", "r", stdin);
	//freopen("1nul", "w", stderr);
	//freopen("output.txt", "w", stdout);
#else
	ios_base::sync_with_stdio(false);
#endif

	int n;
	cin >> n;
	map<string,int> word_cost;
	for(int i=0;i<n;i++) {
		string s;
		int c;
		cin >> s >> c;
		word_cost[s]+=c;
	}

	for(auto &p:word_cost) {
		word.push_back(p.first);
		cost.push_back(p.second);
	}

	go.push_back(vector<int>(ALPHA, -1));
	word_end.push_back(-1);

	for(int i=0;i<word.size();i++) trie_add(word[i], i);

	link.resize(trie_sz);
	state_cost.resize(trie_sz);

	trie_build_links();
	calc_state_cost();

	string s;
	cin >> s;

	{
		int i = 0;
		while (i<s.length()) {
			if (s[i]=='?') {i++; continue;}
			int j=i;
			while (j<s.length()&&s[j]!='?')j++;

			calc(s, i, j);
			i=j;
		}
	}

	int const INF = -2e9;

	dp = vector<vector<int>> (trie_sz, vector<int> (1<<ALPHA, INF));
	dp[0][0] = 0;

	{
		int i = 0;
		while (i<s.length()) {
			dp2 = vector<vector<int>> (trie_sz, vector<int> (1<<ALPHA, INF));

			if (s[i]=='?') {
				for(int st=0;st<trie_sz;st++) {
					for(int msk=0;msk<(1<<ALPHA);msk++) {
						if (dp[st][msk] == INF) continue;

						for(int c=0;c<ALPHA;c++) {
							if (msk & (1<<c)) continue;
							int v = st;
							while (go[v][c]==-1)v = link[v];
							v = go[v][c];
							int new_msk = msk | (1<<c);
							int new_cost = dp[st][msk] + state_cost[v];
							if (new_cost > dp2[v][new_msk]) {
								dp2[v][new_msk] = new_cost;
							}
						}
					}
				}
				i++;
			} else {
				int j=i;
				while (j<s.length()&&s[j]!='?')j++;
				auto sk = skip_letters[i];
				for(int st=0;st<trie_sz;st++) {
					auto p = sk[st];
					for(int msk=0;msk<(1<<ALPHA);msk++) {
						if (dp[st][msk] == INF) continue;
						int v = p.first;
						int new_cost = dp[st][msk] + p.second;
						int new_msk = msk;
						if (new_cost > dp2[v][new_msk]) {
							dp2[v][new_msk] = new_cost;
						}
					}
				}

				i = j;
			}
			dp=dp2;
		}
	}

	int q=0;
	for(char c:s)q+=c=='?';

	int res=INF;

	for(int i=0;i<trie_sz;i++) {
		for(int msk=0;msk<(1<<ALPHA);msk++) {
			if (bc(msk)==q) {
				res = max(res, dp[i][msk]);
			}
		}
	}

	cout << res << endl;

#ifdef __ASD__
	auto finish_t = chrono::steady_clock::now();
	cerr << "Elapsed " << chrono::duration_cast<chrono::milliseconds>(finish_t - start_t).count() << " ms" << endl;
#endif
	return 0;
}


#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <thread>
#include <unordered_set>
#include <vector>
#include <memory.h>
#include <list>
#include <map>
#include <unordered_map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <stdio.h>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <random>
#include <string>
#include <cassert>

#define getcx _getchar_nolock

using namespace std;

namespace std
{
	string to_string(string const& s) { return '"' + s + '"'; }
	string to_string(char c) { return string(1, c); }
	string to_string(const char* s) { return to_string((string)s); }
	string to_string(bool b) { return (b ? "true" : "false"); }

	template <class T1, class T2>
	string to_string(pair<T1, T2> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }

	template <class T>
	string to_string(T c)
	{
		string s = "[";
		for (auto vvv : c) { s += to_string(vvv) + ","; }
		s += "]";
		return s;
	}

	void debug_impl() { cerr << endl; };

	template <typename T1, typename... T2>
	void debug_impl(T1 a, T2 ... b)
	{
		cerr << " " << to_string(a);
		debug_impl(b...);
	}
}

template <typename T>
struct reversion_wrapper
{
	T& iterable;
};

template <typename T>
auto begin(reversion_wrapper<T> w) { return std::rbegin(w.iterable); }

template <typename T>
auto end(reversion_wrapper<T> w) { return std::rend(w.iterable); }

template <typename T>
reversion_wrapper<T> reverse(T&& iterable) { return { iterable }; }

template<class T>T gcd(T a, T b) { while (a && b)if (a > b)a %= b; else b %= a; return a + b; }
template<class T>T powmod(T a, T b, T mod) { if (b == 0)return 1 % mod; T res = powmod(a, b / 2, mod); res *= res; res %= mod; if (b & 1) { res *= a; res %= mod; } return res; }
template<class T>T inv(T a, T mod) { return powmod(a, mod - 2, mod); }

#ifdef __ASD__
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_impl(__VA_ARGS__)
#define endl "\n"
#else
#define dbg(...) ;
#define endl "\n"
#endif

#define lng long long

lng const MOD = 998244353;

int const ALPHA = 14;

vector<vector<int>> go;
vector<vector<int>> go_r;
vector<int> link;
vector<int> word_end;
vector<lng> state_cost;

int trie_sz = 1;
vector<string> word;
vector<lng> cost;
map<int, vector<pair<int,lng>>> skip_letters;

vector<vector<lng>> dp;
vector<vector<lng>> dp2;

void trie_add(string const &s, int idx) {
	int u = 0;
	for(char c:s) {
		int i = c-'a';
		if (go[u][i]==-1) {
			go[u][i] = trie_sz++;
			go.push_back(vector<int>(ALPHA, -1));
			word_end.push_back(-1);
		}

		u = go[u][i];
	}

	word_end[u] = idx;
}

void trie_build_links() {
	link[0] = 0;
	queue<int> q;
	for(int c=0;c<ALPHA;c++) {
		if (go[0][c]==-1)continue;
		link[go[0][c]] = 0;
		q.push(go[0][c]);
	}

	for(int i=0;i<ALPHA;i++)if(go[0][i]==-1)go[0][i]=0;

	while (!q.empty()) {
		int u = q.front();
		q.pop();

		for(int i=0;i<ALPHA;i++) {
			if (go[u][i]==-1)continue;
			int v = go[u][i];
			int w = link[u];
			while (go[w][i]==-1)w=link[w];
			link[v]=go[w][i];
			q.push(v);
		}
	}
}

void calc_state_cost() {
	queue<int> q;
	for(int i=0;i<ALPHA;i++)if(go[0][i])q.push(go[0][i]);

	while (!q.empty()) {
		int u = q.front();
		q.pop();
		state_cost[u] = 0;
		if (word_end[u]!=-1) {
			state_cost[u] = cost[word_end[u]];
		}
		if (link[u] != u) {
			state_cost[u] += state_cost[link[u]];
		}
		for(int i=0;i<ALPHA;i++) {
			if (go[u][i]!=-1) q.push(go[u][i]);
		}
	}
}

void calc(string const &s, int l, int r) {
	if (l>=r) return;

	vector<pair<int, int>> res(trie_sz);

	for(int st=0;st<trie_sz;st++) {

		int v=st;
		lng sum = 0;

		for(int i=l;i<r;i++) {
			int c = s[i]-'a';
			v = go_r[v][c];
			sum += state_cost[v];
		}

		skip_letters[l].emplace_back(v, sum);
	}
}

int bc[1<<ALPHA];

int main()
{
#ifdef __ASD__
	auto start_t = chrono::steady_clock::now();
	freopen("input.txt", "r", stdin);
	//freopen("1nul", "w", stderr);
	//freopen("output.txt", "w", stdout);
#else
	ios_base::sync_with_stdio(false);
#endif

	for(int i=1;i<(1<<ALPHA);i++)bc[i]=bc[i/2]+i%2;

	int n;
	cin >> n;
	map<string,int> word_cost;
	for(int i=0;i<n;i++) {
		string s;
		int c;
		cin >> s >> c;
		word_cost[s]+=c;
	}

	for(auto &p:word_cost) {
		word.push_back(p.first);
		cost.push_back(p.second);
	}

	go.push_back(vector<int>(ALPHA, -1));
	word_end.push_back(-1);

	for(int i=0;i<word.size();i++) trie_add(word[i], i);

	link.resize(trie_sz);
	state_cost.resize(trie_sz);

	trie_build_links();
	calc_state_cost();

	string s;
	cin >> s;

	go_r.resize(trie_sz, vector<int>(ALPHA, -1));

	for(int st=0;st<trie_sz; st++) {
		for(int c=0;c<ALPHA;c++) {
			int u = st;
			while (go[u][c]==-1)u=link[u];
			go_r[st][c] = go[u][c];
		}
	}

	{
		int i = 0;
		while (i<s.length()) {
			if (s[i]=='?') {i++; continue;}
			int j=i;
			while (j<s.length()&&s[j]!='?')j++;

			calc(s, i, j);
			i=j;
		}
	}

	lng const INF = -2e18;

	dp = vector<vector<lng>> (trie_sz, vector<lng> (1<<ALPHA, INF));
	dp2 = vector<vector<lng>> (trie_sz, vector<lng> (1<<ALPHA, INF));

	dp[0][0] = 0;

	{
		int i = 0;
		while (i<s.length()) {
			if(i)for(int q=0;q<trie_sz;q++)fill(dp2[q].begin(), dp2[q].end(), INF);

			if (s[i]=='?') {
				for(int st=0;st<trie_sz;st++) {
					for(int msk=0;msk<(1<<ALPHA);msk++) {
						if (dp[st][msk] == INF) continue;

						for(int c=0;c<ALPHA;c++) {
							if (msk & (1<<c)) continue;
							int v = st;
							v = go_r[v][c];
							int new_msk = msk | (1<<c);
							lng new_cost = dp[st][msk] + state_cost[v];
							if (new_cost > dp2[v][new_msk]) {
								dp2[v][new_msk] = new_cost;
							}
						}
					}
				}
				i++;
			} else {
				int j=i;
				while (j<s.length()&&s[j]!='?')j++;
				auto sk = skip_letters[i];
				for(int st=0;st<trie_sz;st++) {
					auto p = sk[st];
					for(int msk=0;msk<(1<<ALPHA);msk++) {
						if (dp[st][msk] == INF) continue;
						int v = p.first;
						lng new_cost = dp[st][msk] + p.second;
						int new_msk = msk;
						if (new_cost > dp2[v][new_msk]) {
							dp2[v][new_msk] = new_cost;
						}
					}
				}

				i = j;
			}
			dp=dp2;
		}
	}

	int q=0;
	for(char c:s)q+=c=='?';

	lng res=INF;

	for(int i=0;i<trie_sz;i++) {
		for(int msk=0;msk<(1<<ALPHA);msk++) {
			if (bc[msk]==q) {
				res = max(res, dp[i][msk]);
			}
		}
	}

	cout << res << endl;
#ifdef __ASD__
	auto finish_t = chrono::steady_clock::now();
	cerr << "Elapsed " << chrono::duration_cast<chrono::milliseconds>(finish_t - start_t).count() << " ms" << endl;
#endif
	return 0;
}