#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef vector<int> vi;
typedef vector<vi> vii;
typedef pair<int,int> pii;

#define sync ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ld long double
#define sz(a) int((a).size())
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(),(c).end()
#define allr(c) (c).rbegin(),(c).rend()
#define newl '\n'

ll dam[2][200005][4]; // double? turn cards
ll dp[200005][10];

int main(){ sync;
    ll n; cin >> n;

    for(int t=1;t<=n;++t){
        ll k; cin >> k;

        vector<ll> a[4];

        for(int i=0;i<k;++i){
            int c,d; cin >> c >> d;
            a[c].pb(d);
        }
        for(int i=1;i<=3;++i){
                sort(allr(a[i]));
            //    for(int j=0;j<5;++j) a[i].pb(0);
        }

        if(sz(a[1])>=3){
            dam[0][t][3] = a[1][0]+a[1][1]+a[1][2];
            vector<ll> x = {a[1][0],a[1][1],a[1][2]};
            sort(all(x));
            dam[1][t][3] = 2*x[2]+x[1]+x[0];
        }
        if(sz(a[2]) && sz(a[1])){
            dam[0][t][2] = a[2][0]+a[1][0];
            dam[1][t][2] = 2*max(a[2][0],a[1][0]) + min(a[2][0],a[1][0]);
        }
        if(sz(a[1])>=2){
            dam[0][t][2] = max(dam[0][t][2],a[1][0]+a[1][1]);
            dam[1][t][2] = max(dam[1][t][2], 2*max(a[1][0],a[1][1]) + min(a[1][0],a[1][1]));
        }

        if(sz(a[1])) dam[0][t][1] = a[1][0];
        if(sz(a[2])) dam[0][t][1] = max(dam[0][t][1],a[2][0]);
        if(sz(a[3])) dam[0][t][1] = max(dam[0][t][1],a[3][0]);

        dam[1][t][1] = 2*dam[0][t][1];



    }


    for(int i=0;i<10;++i){
        if(i<=3) dp[1][i] = dam[0][1][i];
        if(dp[1][i] == 0 && i>0) dp[1][i] = -1;

    }

    for(int i=2;i<=n;++i){
        for(int j=0;j<10;++j){
            if(dp[i-1][(j-3+10)%10] != -1) dp[i][j] = dp[i-1][(j-3+10)%10] + dam[ (j-3 < 0) ? 1 : 0][i][3];
            if(dp[i-1][(j-2+10)%10] != -1) dp[i][j] = max(dp[i][j],dp[i-1][(j-2+10)%10] + dam[(j-2 < 0) ? 1 : 0][i][2]);
            if(dp[i-1][(j-1+10)%10] != -1) dp[i][j] = max(dp[i][j],dp[i-1][(j-1+10)%10] + dam[(j-1 < 0) ? 1 : 0][i][1]);
            if(dp[i-1][(j-0+10)%10] != -1) dp[i][j] = max(dp[i][j],dp[i-1][(j+10)%10] + dam[0][i][0]);

            if(j > 0 && dp[i][j] == 0) dp[i][j] = -1;
        }


    }

  /*  for(int i=1;i<=n;++i){
        for(int j = 0;j<10;++j) cout << dp[i][j] << " ";
        cout << newl;
    } */
    ll ans = 0;
    for(int i=0;i<10;++i) ans = max(ans,dp[n][i]);
    cout << ans << newl;
    return 0;


}
