RT
//#pragma GCC optimize(2)//O2,洛谷要关
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <bits/stdc++.h>
#define str string
#define ll long long
#define db double
using namespace std;
const int N=1e6+10,M=1000,K=1.5e6;
int n;
ll ans;
vector<int>e[N],siz[N],id[N];
int dfn[N],low[N],cnt;//用tarjan找环的尝试
int scc[N];
bool book[N];
vector<int>ring[M];
int m,has[N];
int t[N],nxt[N];
int q[K],head,tail;
ll lenth[N],zhi[N];
ll num[K],sum[K];
void findhuan(int x,int fa)
{
cnt++;
dfn[x]=cnt;
low[x]=cnt;
for(int i=0;i<e[x].size();i++)
{
int y=e[x][i];
int idx=id[x][i];
if(idx==fa)continue;
if(dfn[y])
{
low[x]=min(low[x],dfn[y]);
continue;
}
findhuan(y,idx);
low[x]=min(low[x],low[y]);
}
scc[low[x]]++;
}
void findlen(int x)
{
ll maxn=0,midn=0;
book[x]=1;
for(int i=0;i<e[x].size();i++)
{
int y=e[x][i];
int sz=siz[x][i];
if(book[y])continue;
findlen(y);
zhi[x]=max(zhi[x],zhi[y]);
ll l=lenth[y]+sz;
if(l>maxn)
{
midn=maxn;
maxn=l;
}
else if(l>midn)
{
midn=l;
}
}
zhi[x]=max(zhi[x],maxn+midn);
lenth[x]=maxn;
}
signed main()
{
// freopen("in.in","r",stdin);
// freopen("1.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
for(int u=1;u<=n;u++)
{
int v,w;
cin>>v>>w;
nxt[u]=v;
t[u]=w;
e[u].push_back(v);
e[v].push_back(u);
id[u].push_back(u);
id[v].push_back(u);
siz[u].push_back(w);
siz[v].push_back(w);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
findhuan(i,0);
}
}
// for(int i=1;i<=n;i++)
// {
// cout<<low[i]<<' ';
// }
for(int x=1;x<=n;x++)
{
if(scc[low[x]]==1)continue;
if(has[low[x]]==0)
{
m++;
has[low[x]]=m;
}
book[x]=1;
ring[has[low[x]]].push_back(x);
}
// 前面通过tarjan算法找环+缩点
for(int i=1;i<=m;i++)
{
for(auto x:ring[i])
{
findlen(x);
// cout<<x<<' '<<lenth[x]<<'\n';
}
}
for(int i=1;i<=m;i++)
{
for(int j=0;j<ring[i].size()-1;j++)
{
ring[i][j+1]=nxt[ring[i][j]];
}
}
// for(int i=1;i<=m;i++)
// {
// cout<<i<<':';
// for(auto y:ring[i])
// {
// cout<<y<<' ';
// }
// cout<<'\n';
// }
for(int i=1;i<=m;i++)
{
head=tail=0;
ll res=0;
int s=ring[i].size();
for(int j=0;j<s;j++)
{
num[j+1]=ring[i][j];
num[j+1+s]=ring[i][j];
res=max(res,zhi[num[j+1]]);
}
for(int j=1;j<=2*s;j++)
{
sum[j]=sum[j-1]+t[num[j]];
// cout<<num[j]<<' '<<sum[j]<<'\n';
}
for(int j=1;j<=2*s;j++)
{
if(q[head]+s<=j&&head<tail)head++;
if(head<tail)
res=max(res,lenth[num[q[head]]]+lenth[num[j]]+sum[j-1]-sum[q[head]-1]);
while(head<tail&&lenth[num[q[tail-1]]]-sum[q[tail-1]-1]<lenth[num[j]]-sum[j-1])tail--;
q[tail++]=j;
}
ans+=res;
}
cout<<ans;
return 0;
}
/*
*/