import java.util.*;

/**
 * Created by on 10/06/19.
 */
public class HelloWorld13 {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();
        HashMap<Integer, HashMap<Integer, ArrayList<Long>>> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int k = s.nextInt();
            HashMap<Integer, ArrayList<Long>> map1 = new HashMap<>();
            for (int j = 0; j < k; j++) {
                int cost = s.nextInt();
                long damage = s.nextLong();
                ArrayList<Long> map2 = map1.getOrDefault(cost, new ArrayList<>());
                map2.add(damage);
                map1.put(cost, map2);
            }

            for (int j = 1; j <= 3; j++) {
                ArrayList<Long> list = map1.getOrDefault(j, new ArrayList<>());
                Collections.sort(list, Collections.reverseOrder());
                map1.put(j, list);
            }
            map.put(i, map1);
        }

        long[][] ans = new long[n][10];
        for (int i = 0; i < 10; i++) {
//            ans[i][n - 1] =
            HashMap<Integer, ArrayList<Long>> map1 = map.get(n - 1);

            long max = Long.MIN_VALUE;
            long max3 = Long.MIN_VALUE;
            long max2 = Long.MIN_VALUE;
            long max1 = Long.MIN_VALUE;

            ArrayList<Long> one = map1.getOrDefault(1, new ArrayList<>());
            ArrayList<Long> two = map1.getOrDefault(2, new ArrayList<>());
            ArrayList<Long> three = map1.getOrDefault(3, new ArrayList<>());

            if (one.size() >= 3) {
                if (i % 10 > (i + 3) % 10) {
                    max3 = Math.max(max3, 2 * one.get(0) + one.get(1) + one.get(2));
                } else {
                    max3 = Math.max(max3, one.get(0) + one.get(1) + one.get(2));
                }
            }

            if (one.size() >= 1 && two.size() >= 1) {
                long max12 = Math.max(two.get(0), one.get(0));
                long min12 = Math.min(two.get(0), one.get(0));
                if (i % 10 > (i + 2) % 10) {
                    max2 = Math.max(max2, 2 * max12 + min12);
                } else {
                    max2 = Math.max(max2, max12 + min12);
                }
            }

            if (three.size() >= 1) {
                if (i % 10 > (i + 1) % 10) {
                    max1 = Math.max(max1, 2 * three.get(0));
                } else {
                    max1 = Math.max(max1, three.get(0));
                }
            }

            if (one.size() >= 2) {
                if (i % 10 > (i + 2) % 10) {
                    max2 = Math.max(max2, 2 * one.get(0) + one.get(1));
                } else {
                    max2 = Math.max(max2, one.get(0) + one.get(1));
                }
            }

            if (two.size() >= 1) {
                if (i % 10 > (i + 1) % 10) {
                    max1 = Math.max(max1, 2 * two.get(0));
                } else {
                    max1 = Math.max(max1, two.get(0));
                }
            }

            if(one.size() >= 1) {
                if (i % 10 > (i + 1) % 10) {
                    max1 = Math.max(max1, 2 * one.get(0));
                } else {
                    max1 = Math.max(max1, one.get(0));
                }
            }

            if(max3 != Long.MIN_VALUE) {
                max = Math.max(max, max3);
            }

            if(max2 != Long.MIN_VALUE) {
                max = Math.max(max, max2);
            }

            if(max1 != Long.MIN_VALUE) {
                max = Math.max(max, max1);
            }

            ans[n - 1][i%10] = max;
        }


        for (int i = n - 2; i >= 0; i--) {
            for (int j = 0; j < 10; j++) {
                HashMap<Integer, ArrayList<Long>> map1 = map.get(i);

                long max = Long.MIN_VALUE;
                long max3 = Long.MIN_VALUE;
                long max2 = Long.MIN_VALUE;
                long max1 = Long.MIN_VALUE;

                ArrayList<Long> one = map1.getOrDefault(1, new ArrayList<>());
                ArrayList<Long> two = map1.getOrDefault(2, new ArrayList<>());
                ArrayList<Long> three = map1.getOrDefault(3, new ArrayList<>());

                if (one.size() >= 3) {
                    if (j % 10 > (j + 3) % 10) {
                        max3 = Math.max(max3, 2 * one.get(0) + one.get(1) + one.get(2));
                    } else {
                        max3 = Math.max(max3, one.get(0) + one.get(1) + one.get(2));
                    }
                }

                if (one.size() >= 1 && two.size() >= 1) {
                    long max12 = Math.max(two.get(0), one.get(0));
                    long min12 = Math.min(two.get(0), one.get(0));
                    if (j % 10 > (j + 2) % 10) {
                        max2 = Math.max(max2, 2 * max12 + min12);
                    } else {
                        max2 = Math.max(max2, max12 + min12);
                    }
                }

                if (three.size() >= 1) {
                    if (j % 10 > (j + 1) % 10) {
                        max1 = Math.max(max1, 2 * three.get(0));
                    } else {
                        max1 = Math.max(max1, three.get(0));
                    }
                }

                if (one.size() >= 2) {
                    if (j % 10 > (j + 2) % 10) {
                        max2 = Math.max(max2, 2 * one.get(0) + one.get(1));
                    } else {
                        max2 = Math.max(max2, one.get(0) + one.get(1));
                    }
                }

                if (two.size() >= 1) {
                    if (j % 10 > (j + 1) % 10) {
                        max1 = Math.max(max1, 2 * two.get(0));
                    } else {
                        max1 = Math.max(max1, two.get(0));
                    }
                }

                if(one.size() >= 1) {
                    if (j % 10 > (j + 1) % 10) {
                        max1 = Math.max(max1, 2 * one.get(0));
                    } else {
                        max1 = Math.max(max1, one.get(0));
                    }
                }

                if(max3 != Long.MIN_VALUE) {
                    max = Math.max(max, max3 + ans[i + 1][(j + 3)  % 10]);
                }

                if(max2 != Long.MIN_VALUE) {
                    max = Math.max(max, max2 + ans[i + 1][(j + 2)  % 10]);
                }

                if(max1 != Long.MIN_VALUE) {
                    max = Math.max(max, max1+ ans[i+1][(j + 1) % 10]);
                }

                ans[i][j % 10] = max;
            }
        }

        long max = Long.MIN_VALUE;
        for (int i = 0; i < 10; i++) {
            max = Long.max(max, ans[0][i]);
        }
        System.out.println(max);
    }

    private static long func(int turn, HashMap<Integer, HashMap<Integer, ArrayList<Long>>> map, int num, long[][] ans) {
        if(num > ans[0].length) {
            return 0;
        }

        HashMap<Integer, ArrayList<Long>> map1 = map.get(num);
        if(map1 == null) {
            return 0;
        }

        if(ans[turn % 10][num] != -1) {
            return ans[turn % 10][num];
        }

        long max = Long.MIN_VALUE;
        long max3 = Long.MIN_VALUE;
        long max2 = Long.MIN_VALUE;
        long max1 = Long.MIN_VALUE;

        ArrayList<Long> one = map1.getOrDefault(1, new ArrayList<>());
        ArrayList<Long> two = map1.getOrDefault(2, new ArrayList<>());
        ArrayList<Long> three = map1.getOrDefault(3, new ArrayList<>());

        if (one.size() >= 3) {
            if (turn % 10 > (turn + 3) % 10) {
                max3 = Math.max(max3, 2 * one.get(0) + one.get(1) + one.get(2));
            } else {
                max3 = Math.max(max3, one.get(0) + one.get(1) + one.get(2));
            }
        }

        if (one.size() >= 1 && two.size() >= 1) {
            long max12 = Math.max(two.get(0), one.get(0));
            long min12 = Math.min(two.get(0), one.get(0));
            if (turn % 10 > (turn + 2) % 10) {
                max2 = Math.max(max2, 2 * max12 + min12);
            } else {
                max2 = Math.max(max2, max12 + min12);
            }
        }

        if (three.size() >= 1) {
            if (turn % 10 > (turn + 1) % 10) {
                max1 = Math.max(max1, 2 * three.get(0));
            } else {
                max1 = Math.max(max1, three.get(0));
            }
        }

        if (one.size() >= 2) {
            if (turn % 10 > (turn + 2) % 10) {
                max2 = Math.max(max2, 2 * one.get(0) + one.get(1));
            } else {
                max2 = Math.max(max2, one.get(0) + one.get(1));
            }
        }

        if (two.size() >= 1) {
            if (turn % 10 > (turn + 1) % 10) {
                max1 = Math.max(max1, 2 * two.get(0));
            } else {
                max1 = Math.max(max1, two.get(0));
            }
        }

        if(one.size() >= 1) {
            if (turn % 10 > (turn + 1) % 10) {
                max1 = Math.max(max1, 2 * one.get(0));
            } else {
                max1 = Math.max(max1, one.get(0));
            }
        }

        if(max3 != Long.MIN_VALUE) {
            max = Math.max(max, max3  + func((turn + 3) % 10, map, num + 1, ans));
        }

        if(max2 != Long.MIN_VALUE) {
            max = Math.max(max, max2  + func((turn + 2) % 10, map, num + 1, ans));
        }

        if(max1 != Long.MIN_VALUE) {
            max = Math.max(max, max1 + func((turn + 1) % 10, map, num + 1, ans));
        }

        return ans[turn % 10][num] = max;


    }


    private static class pair implements Comparable<pair> {
        int cost;
        int damage;

        public pair(int cost, int damage) {
            this.cost = cost;
            this.damage = damage;
        }


        @Override
        public int compareTo(pair o) {
            if(this.damage == o.damage) {
                return Integer.compare(this.cost, o.cost);
            }
            return Integer.compare(o.damage,this.damage);
        }
    }
}
