#include <bits/stdc++.h>
using namespace std;
const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const long long INF64 = 0x3f3f3f3f3f3f3f3f;
const int MOD = 9999973;
const long long TARGET = (1LL << 32) - 1LL;
template <typename T>
inline T read() {
  T X = 0, w = 0;
  char ch = 0;
  while (!isdigit(ch)) {
    w |= ch == '-';
    ch = getchar();
  }
  while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
  return w ? -X : X;
}
struct Card {
  int c, d;
  bool operator<(const Card& b) const { return d > b.d; }
};
const int MAXN = 2005;
int n, m, k;
int CASE = 1;
vector<Card> cards[MAXN][3];
long long dp[MAXN][11];
Card best[3];
inline long long doubler(int i, int j) {
  if (i != 1 && !j) return 2;
  return 1;
}
inline long long maxOne(int i, int j) {
  vector<Card> tmp;
  for (auto a : cards[i][0]) {
    tmp.push_back(a);
  }
  for (auto a : cards[i][1]) {
    tmp.push_back(a);
  }
  for (auto a : cards[i][2]) {
    tmp.push_back(a);
  }
  sort(tmp.begin(), tmp.end());
  return tmp[0].d * doubler(i, (j + 1) % 10);
}
inline long long maxTwo(int i, int j) {
  vector<Card> tmp;
  tmp.assign(cards[i][0].begin(), cards[i][0].end());
  for (auto a : cards[i][1]) {
    tmp.push_back(a);
  }
  if (tmp.size() < 2) return -1;
  sort(tmp.begin(), tmp.end());
  long long ans = 0;
  for (int z = 0; z <= 1; z++) {
    ans += tmp[z].d;
    if (i != 1 && (j + i) % 10 == 0) {
      ans += tmp[0].d;
    }
  }
  return ans;
}
inline int maxThree(int i, int j) {
  vector<Card> tmp;
  tmp.assign(cards[i][0].begin(), cards[i][0].end());
  if (tmp.size() < 3) return -1;
  sort(tmp.begin(), tmp.end());
  int ans = 0;
  for (int z = 0; z < 3; z++) {
    ans += tmp[z].d;
    if (i != 1 && (j + i) % 10 == 0) {
      ans += tmp[0].d;
    }
  }
  return ans;
}
int main() {
  int T;
  scanf("%d", &T);
  for (int j = 1; j <= T; j++) {
    scanf("%d", &n);
    Card card;
    for (int i = 0; i < n; i++) {
      scanf("%d %d", &card.c, &card.d);
      cards[j][card.c - 1].push_back(card);
    }
  }
  memset(dp, -0x3f, sizeof(dp));
  dp[0][0] = 0;
  for (int i = 0; i < T; i++) {
    for (int j = 0; j < 10; j++) {
      if (dp[i][j] < 0) continue;
      dp[i + 1][j] = max(dp[i + 1][j], dp[i][j]);
      int m1 = maxOne(i + 1, j);
      if (m1 > 0)
        dp[i + 1][(j + 1) % 10] = max(dp[i + 1][(j + 1) % 10], dp[i][j] + m1);
      int m2 = maxTwo(i + 1, j);
      if (m2 > 0)
        dp[i + 1][(j + 2) % 10] = max(dp[i + 1][(j + 2) % 10], dp[i][j] + m2);
      int m3 = maxThree(i + 1, j);
      if (m3 > 0)
        dp[i + 1][(j + 3) % 10] = max(dp[i + 1][(j + 3) % 10], dp[i][j] + m3);
    }
  }
  long long ans = 0;
  for (int i = 0; i < 10; i++) {
    ans = max(ans, dp[T][i]);
  }
  printf("%lld", ans);
  return 0;
}
