#include<cstdio>
#include<vector>
#include<queue>
#include<utility>
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
using namespace std;
typedef long long lld;
typedef pair<lld, lld> PLL;
typedef pair<int, lld> PIL;
typedef vector<lld> VLL;
typedef vector<PLL> VPLL;
typedef vector<PIL> VPIL;
typedef vector<bool> VB;
VPIL graph[111111];
int main(){
int n; scanf("%d",&n);
for(int i = 0 ; i < n ; i++){
int src; scanf("%d",&src);
while(true){
int dst;
lld cos;
scanf("%d", &dst);
if(dst == -1) break;
scanf("%lld", &cos);
graph[src].pb(mp(dst,cos));
}
} // input end
VB visited(n+1, false);
queue<lld> Q;
VLL cost(n+1, 0);
Q.push(1);
visited[1] = true;
int max_node = 1;
lld max_cost = -1;
while(!Q.empty()){
int here = Q.front(); Q.pop();
for(int i = 0 ; i < graph[here].size() ; i++){
PIL there = graph[here][i];
if(!visited[there.first]){
visited[there.first] = true;
cost[there.first] = cost[here] + there.second; // update
if(max_cost < cost[there.first]){ // update max-node, cost
max_cost = cost[there.first];
max_node = there.first;
}
Q.push(there.first); // push node
}
}
} // 1-BFS : search start node
Q.push(max_node);
max_cost = -1;
cost = VLL(n+1,0);
visited = VB(n+1, false);
visited[max_node] = true;
while(!Q.empty()){
int here = Q.front(); Q.pop();
for(int i = 0 ; i < graph[here].size() ; i++){
PIL there = graph[here][i];
if(!visited[there.first]){
visited[there.first] = true;
cost[there.first] = cost[here] + there.second; // update
if(max_cost < cost[there.first]){ // update max-cost
max_cost = cost[there.first];
}
Q.push(there.first); // push node
}
}
} // 2-BFS : result cost
printf("%lld\n",max_cost);
return 0;
}