def dmg(currnr, dmgs):
	if currnr+len(dmgs) < 10:
		return sum(dmgs)
	return max(dmgs)+sum(dmgs)

import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
# input = io.StringIO(os.read(0, os.fstat(0).st_size).decode()).readline
ii=lambda:int(input())
kk=lambda:map(int, input().split())
ll=lambda:list(kk())
turns = ii()
dp = [[-1]*10 for _ in range(turns+1)]
dp[0][0]=0
for t in range(turns):
	nr = ii()
	card = [None, [],[],[]]
	for i in range(nr):
		a,b = kk()
		card[a].append(b)
	card[1].sort(reverse=True)
	card[2].sort(reverse=True)
	card[3].sort(reverse=True)
	s1,s2,s3 = len(card[1]),len(card[2]),len(card[3])
	for cardnr in range(10):
		curr = dp[t][cardnr]
		if curr == -1: continue
		#do nothing
		if dp[t+1][cardnr] < curr: dp[t+1][cardnr] = curr
		#1
		if s1>0 and dp[t+1][(cardnr+1)%10] < curr+card[1][0]: dp[t+1][(cardnr+1)%10] = curr+dmg(cardnr, [card[1][0]])
		#1,1
		if s1>1 and dp[t+1][(cardnr+2)%10] < curr+card[1][0]+card[1][1]: dp[t+1][(cardnr+2)%10] = curr+dmg(cardnr,[card[1][0],card[1][1]])
		#1,1,1
		if s1>2 and dp[t+1][(cardnr+3)%10] < curr+card[1][0]+card[1][1]+card[1][2]: dp[t+1][(cardnr+3)%10] = curr+dmg(cardnr,[card[1][0],card[1][1],card[1][2]])
		#2
		if s2>0 and dp[t+1][(cardnr+1)%10] < curr+card[2][0]: dp[t+1][(cardnr+1)%10] = curr+dmg(cardnr, [card[2][0]])
		#2,1
		if s1>0 and s2>0 and dp[t+1][(cardnr+2)%10] < curr+card[1][0]+card[2][0]: dp[t+1][(cardnr+2)%10] = curr+dmg(cardnr,[card[1][0],card[2][0]])
		#3
		if s3>0 and dp[t+1][(cardnr+1)%10] < curr+card[3][0]: dp[t+1][(cardnr+1)%10]=curr+dmg(cardnr, [card[3][0]])
m=-1
for cardnr in range(10):
	if dp[turns][cardnr] > m: m = dp[turns][cardnr]
print(m)