#include <bits/stdc++.h>
#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("fast-math")
using namespace std;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
pair<long long, long long> f(long long x) { return {x, x * 2}; }
pair<long long, long long> f(long long x, long long y) {
  return {x + y, max(x, y) * 2 + min(x, y)};
}
pair<long long, long long> f(long long x, long long y, long long z) {
  return {x + y + z, max(max(x, y), z) + x + y + z};
}
int main() {
  cin.tie(0);
  cout.tie(0);
  cin.sync_with_stdio(0);
  cout.sync_with_stdio(0);
  ;
  int a;
  cin >> a;
  vector<long long> dp(250000);
  int ps = 0;
  for (int q = 0; q < a; q++) {
    long long k;
    cin >> k;
    long long d3 = -1, d2 = -1;
    deque<long long> d1;
    for (; k; k--) {
      long long c, d;
      cin >> c >> d;
      if (c == 3)
        d3 = max(d3, d);
      else if (c == 2)
        d2 = max(d2, d);
      else {
        d1.push_back(d);
        sort(d1.begin(), d1.end());
        if (d1.size() > 3) d1.pop_front();
      }
    }
    vector<pair<pair<long long, long long>, long long>> m;
    if (d3 != -1) m.push_back({f(d3), 1});
    if (d2 != -1) {
      m.push_back({f(d2), 1});
      if (d1.size() > 0) m.push_back({f(d2, d1.back()), 2});
    }
    if (d1.size() > 0) m.push_back({f(d1.back()), 1});
    if (d1.size() > 1) m.push_back({f(d1.back(), d1[d1.size() - 2]), 2});
    if (d1.size() > 2) m.push_back({f(d1[0], d1[1], d1[2]), 3});
    long long mx = 0;
    for (auto u : m) mx = max(mx, u.second);
    for (int q = ps, i = 0; q >= 0 && i < 100; q--, i++) {
      for (auto j : m) {
        long long x = j.first.first, y = j.first.second, z = j.second;
        if ((q % 10) + (z % 10) >= 10)
          dp[q + z] = max(dp[q + z], dp[q] + y);
        else
          dp[q + z] = max(dp[q + z], dp[q] + x);
      }
    }
    ps += mx;
  }
  long long o = 0;
  for (long long i : dp) o = max(o, i);
  cout << o;
}
