




#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")


#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>


#define F first

#define S second
#define pb push_back

#define ll long long
#define int ll
#define pii pair < ll, ll >
#define ld long double
#define ull unsigned long long

using namespace std;
using namespace __gnu_pbds;


template < typename T > using ordered_set = tree < T, null_type,
                              less < T >, rb_tree_tag, tree_order_statistics_node_update>;

mt19937 gen(time(0));

const int M = 500005;

const ll MOD = 998244353 ;
const int N = 2e5 + 2;
const int inf = 1e15;
const ld eps = 0.000000001;
const ull P = 29;
const ll M1 = 12345678913333333;
const ll M2 = 99999999913333333;

vector < ll > H1[2];
vector < ll > H2[2];
vector < ll > p_pow1 (1, 1), p_pow2 (1, 1);


int dp[N + 2][10];
int z[4][2];
int32_t main ()
{

    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
#else
//    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif // LACOL

     int n;
     cin >> n;

     for (int i = 0; i < N; i++) {
        for (int j = 0; j < 10; j++)
            dp[i][j] = -inf;
     }

     dp[0][0] = 0;

     vector < int > card[N][4];
     for (int i = 0; i < n; i++) {
        int k;
        cin >> k;
        for (int j = 0; j < k; j++) {
            int c, d;
            cin >> c >> d;
            card[i][c].pb (d);
        }
     }
     for (int i = 0; i < n; i++) {
        for (int c = 1; c <= 3; c++)
        {
           sort (card[i][c].begin(), card[i][c].end());
           int sz = (c == 1 ? 3 : 1);
           while (card[i][c].size() > sz)
           card[i][c].pop_back();

        }
     }


     for (int i = 0; i < n; i++) {

        for (int j = 0; j < 4; j++) {
            for (int fl = 0; fl < 2; fl++)
                z[j][fl] = -inf;
        }
        z[0][0] = 0;
        vector < pii > cur;
        for (int j = 1; j <= 3; j++) {
            for (auto to : card[i][j])
            cur.pb ({j, to});
        }
        sort (cur.begin(), cur.end());

       do
               {
                   int cnt = 0, mx = 0, need = 3, w = 0;
                   for (auto to : cur)
                    {
                        if (need < to.F) break;
                        need-=to.F;
                        cnt++;
                        mx = max (mx, to.S);
                        w+=to.S;
                        z[cnt][0] = max (z[cnt][0], w);
                        z[cnt][1] = max (z[cnt][1], w + mx);

                    }
               } while (next_permutation (cur.begin(), cur.end()));

        for (int j = 0; j < 10; j++) {
            for (int k = 1; k <= 3; k++)
            {
                int fl = 0;
                if (j + k >= 10) fl = 1;

                dp[i + 1][(j + k) % 10] = max (dp[i + 1][(j + k) % 10], dp[i][j] + z[k][fl]);

            }
        }

     }
     int ans = 0;
     for (int i = 0; i < 10; i++) {
        ans = max (ans, dp[n][i]);
     }
     cout << ans << '\n';





}


