#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 1;
int n;
bool able[N][4];
long long mem[N][10];
pair<int, int> best[N][4];
long long go(int idx, int mod) {
  if (idx == n + 1) return 0;
  if (mem[idx][mod] != -1) return mem[idx][mod];
  long long sofar = 0;
  for (int i = 0; i <= 3; i++) {
    if (!able[idx][i]) continue;
    if (mod + i <= 9) {
      sofar = max(sofar, go(idx + 1, (mod + i) % 10) + best[idx][i].first);
    } else {
      long long doble = best[idx][i].second;
      sofar =
          max(sofar, go(idx + 1, (mod + i) % 10) + best[idx][i].first + doble);
    }
  }
  return mem[idx][mod] = sofar;
}
int main() {
  memset(mem, -1, sizeof mem);
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    vector<int> cards[4];
    while (x--) {
      int d, c;
      scanf("%d%d", &c, &d);
      cards[c].push_back(d);
    }
    sort(cards[1].rbegin(), cards[1].rend());
    sort(cards[2].rbegin(), cards[2].rend());
    sort(cards[3].rbegin(), cards[3].rend());
    int mx1card = 0, mx2cards = 0, mx2 = 0;
    if (cards[1].size() >= 1) {
      able[i][1] = 1;
      mx1card = cards[1][0];
      if (cards[1].size() >= 2) {
        able[i][2] = 1;
        mx2cards = cards[1][0] + cards[1][1];
      }
      mx2 = cards[1][0];
    }
    if (cards[2].size() >= 1) {
      able[i][1] = 1;
      mx1card = max(mx1card, cards[2][0]);
      if (cards[1].size() >= 1) {
        able[i][2] = 1;
        mx2cards = max(mx2cards, cards[1][0] + cards[2][0]);
      }
      mx2 = max(mx2, cards[2][0]);
    }
    if (cards[3].size() >= 1) {
      able[i][1] = 1;
      mx1card = max(mx1card, cards[3][0]);
    }
    best[i][1] = {mx1card, mx1card};
    best[i][2] = {mx2cards, mx2};
    if (cards[1].size() >= 3) {
      able[i][3] = 1;
      best[i][3] = {cards[1][0] + cards[1][1] + cards[1][2], cards[1][0]};
    }
    able[i][0] = 1;
  }
  printf("%lld\n", go(1, 0));
  return 0;
}
