
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N=2e6+5;
inline int read(){
int x=0,f=0;char c=getchar();
while(c<48||c>57){if(c=='-')f=1;c=getchar();}
while(c>=48&&c<=57){x=(x<<1)+(x<<3)+c-48;c=getchar();}
return f?(~x)+1:x;
}
int n,top,cnt,ql,qr,Q[N*2],p[N*2];
struct edge{
int u,v,w,id;
friend bool operator ==(edge a,edge b){
return a.u==b.u&&a.v==b.v&&a.w==b.w&&a.id==b.id;
}
}st[N],Kobe_Bryant_Cox=edge{1978,0,8,24};
vector<edge>R,G[N];
bool fl,ring[N],vis[N];
ll ans,mx,w,dp[N][2],d[N*2];
void dfs(int u,edge fa){
vis[u]=1;
for(edge j:G[u]){
if(j.id!=fa.id){
if(!vis[j.v]){
st[++top]=j;
dfs(j.v,j);
if(st[top]==j)--top;
if(fl)return;
}else{
st[++top]=j;
do{
ring[st[top].v]=1;
R.insert(R.begin(),st[top--]);
}while(st[top].v!=j.v&&top);
fl=1;
return;
}
}
}
}
void calc(int u,edge fa){
vis[u]=1;
ll aw;
for(edge j:G[u]){
if(ring[j.v]||j.id==fa.id)continue;
calc(j.v,j);
aw=j.w*1ll+dp[j.v][0];
if(aw>dp[u][0])dp[u][1]=dp[u][0],dp[u][0]=aw;
else if(aw>dp[u][1])dp[u][1]=aw;
}
mx=max(mx,dp[u][0]+dp[u][1]);
}
int main(){
n=read();
for(int v,w,u=1;u<=n;++u){
v=read(),w=read();
G[u].push_back(edge{u,v,w,u});
G[v].push_back(edge{v,u,w,u});
}
for(int u=1;u<=n;++u){
if(!vis[u]){
while(!R.empty())R.pop_back();
fl=0,top=0;
dfs(u,Kobe_Bryant_Cox);
mx=cnt=0;
for(edge j:R){
calc(j.u,Kobe_Bryant_Cox);
p[++cnt]=j.u;
d[cnt+1]=d[cnt]+1ll*j.w;
}
for(int j=1;j<cnt;++j)
p[cnt+j]=p[j],d[j+cnt+1]=d[j+cnt]+d[j+1]-d[j];
p[cnt*2]=p[cnt];
ql=1,qr=0,Q[++qr]=1;
for(int i=2,nw;i<=cnt*2;++i){
while(ql<=qr&&i-Q[ql]>=cnt)++ql;
nw=Q[ql];
w=dp[p[nw]][0]-d[nw]+d[i]+dp[p[i]][0];
mx=max(mx,w);
while(ql<=qr){
nw=Q[qr];
if(dp[p[nw]][0]-d[nw]<=dp[p[i]][0]-d[i])--qr;
else break;
}
Q[++qr]=i;
}
ans+=mx;
}
}
printf("%lld\n",ans);
return 0;
}