//#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define int int64_t
#define double long double
#define pii pair<int, int>
#define pdd pair<double, double>
#define F first
#define S second
#define pb push_back
#define endl "\n"
using namespace std;
using namespace __gnu_pbds;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> orset;
const int N = 234567;
const int INF = 1e17;

int dp[N][10][4];

int32_t main(){
   ios_base :: sync_with_stdio(0);
   cin.tie(0); cout.tie(0);
   int n; cin >> n;
//   for(int i = 0; i <= n; i ++)
//      for(int j = 0; j <= 9; j ++)
//         for(int k = 0; k <= 3; k ++)
//            dp[i][j][k] = -INF;
//   dp[0][0][0] = 0;
   vector<vector<vector<int>>> k(n, vector<vector<int>>(3));
   for(int i = 0; i < n; i ++){
      int t; cin >> t;
      for(int j = 0; j < t; j ++){
         int c, d;
         cin >> c >> d;
         k[i][c - 1].pb(d);
      }
      sort(k[i][0].rbegin(), k[i][0].rend());
      sort(k[i][1].rbegin(), k[i][1].rend());
      sort(k[i][2].rbegin(), k[i][2].rend());
      while(k[i][0].size() > 3)
         k[i][0].pop_back();
      while(k[i][1].size() > 1)
         k[i][1].pop_back();
      while(k[i][2].size() > 1)
         k[i][2].pop_back();
   }
   for(int i = 0; i < n; i ++){
      for(int j = 0; j <= 9; j ++){
         for(int o = 0; o <= 3; o ++){
            if(dp[i][j][o] <= -INF)
               continue;
            vector<pii> go;
            for(int x : k[i][0])
               go.pb({1, x});
            for(int x : k[i][1])
               go.pb({2, x});
            for(int x : k[i][2])
               go.pb({3, x});
            sort(go.begin(), go.end(), [&](pii a, pii b){
                  return a.S > b.S;
                 });
            for(int p = 0; p < (1LL << ((int)go.size())); p ++){
               int jj = j, sum = 0, take = dp[i][j][o];
               for(int u = 0; u < go.size(); u ++){
                  if((1LL << u) & p){
                     sum += go[u].F;
                     if(jj == 9)
                        take += go[u].S * 2;
                     else
                        take += go[u].S;
                     jj = (jj + 1) % 10;
                  }
               }
               if(sum > 3)
                  continue;
               int bits = __builtin_popcount(p);
               dp[i + 1][jj][bits] = max(dp[i + 1][jj][bits], take);
            }
         }
      }
   }
   int ans = 0;
   for(int i = 0; i <= 9; i ++)
      for(int k = 0; k <= 3; k ++)
      ans = max(ans, dp[n][i][k]);
   cout << ans;
}
