#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template<class Key, class Compare = less<Key>>
using indexed_set = tree<Key, null_type, Compare, rb_tree_tag, tree_order_statistics_node_update>;
template<class Key, class Value, class Compare = less<Key>>
using indexed_map = tree<Key, Value, Compare, rb_tree_tag, tree_order_statistics_node_update>;
template<class Key>
using hash_set = gp_hash_table<
Key, null_type, hash<Key>, equal_to<Key>, direct_mask_range_hashing<Key>, linear_probe_fn<>,
hash_standard_resize_policy<hash_exponential_size_policy<>, hash_load_check_resize_trigger<true>, true>>;
template<class Key, class Value>
using hash_map = gp_hash_table<
Key, Value, hash<Key>, equal_to<Key>, direct_mask_range_hashing<Key>, linear_probe_fn<>,
hash_standard_resize_policy<hash_exponential_size_policy<>, hash_load_check_resize_trigger<true>, true>>;
// https://codeforces.com/blog/entry/79148
class Timer: chrono::high_resolution_clock {
const time_point start_time;
public:
Timer(): start_time(now()) {}
rep elapsed_time() const {
return chrono::duration_cast<chrono::milliseconds>(now() - start_time).count();
}
} timer;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n, ans = 0;
cin >> n;
vector<vector<pair<int, int>>> tree(n + 1);
vector<vector<int>> pf_max(n + 1), sf_max(n + 1);
vector<int> dp0(n + 1, 0), dp1(n + 1, 0);
for (int i = 1; i < n; i++) {
int u, v, w;
cin >> u >> v >> w;
tree[u].push_back({v, w});
tree[v].push_back({u, w});
}
auto dfs = [&] (auto self, int u, int p)->void {
int wp;
for (auto &[v, w] : tree[u]) {
if (v != p) {
self(self, v, u);
dp0[u] += max(dp0[v], dp1[v]);
}
else {
wp = w;
}
}
if (p) {
for (auto &[v, w] : tree[u]) {
if (v != p) {
dp1[u] = max(dp1[u], wp + w + dp0[u] - max(dp0[v], dp1[v]) + dp0[v]);
}
}
}
};
// pf/sf_max: w - max(dp0[v], dp1[v]) + dp0[v]
auto reroot = [&] (int u, int pos)->void {
int v = tree[u][pos].first;
dp0[u] -= max(dp0[v], dp1[v]);
dp1[u] = 0;
if (pos) {
dp1[u] = tree[u][pos].second + pf_max[u][pos - 1] + dp0[u];
}
if (pos < int(tree[u].size()) - 1) {
dp1[u] = max(dp1[u], tree[u][pos].second + sf_max[u][pos + 1] + dp0[u]);
}
dp0[v] = 0;
for (auto &[w, _] : tree[v]) {
dp0[v] += max(dp0[w], dp1[w]);
}
dp1[v] = 0;
};
auto dfs2 = [&] (auto self, int u, int p)->void {
ans = max(ans, dp0[u]);
pf_max[u].resize(tree[u].size());
sf_max[u].resize(tree[u].size());
for (int i = 0; i < tree[u].size(); i++) {
auto &[v, w] = tree[u][i];
pf_max[u][i] = sf_max[u][i] = w - max(dp0[v], dp1[v]) + dp0[v];
if (i) {
pf_max[u][i] = max(pf_max[u][i], pf_max[u][i - 1]);
}
}
for (int i = int(tree[u].size()) - 2; i >= 0; i--) {
sf_max[u][i] = max(sf_max[u][i], sf_max[u][i + 1]);
}
int pr;
for (int i = 0; i < tree[u].size(); i++) {
auto &[v, w] = tree[u][i];
if (v != p) {
reroot(u, i);
self(self, v, u);
}
else {
pr = i;
}
}
if (u == 1) {
return;
}
reroot(u, pr);
};
dfs(dfs, 1, 0);
dfs2(dfs2, 1, 0);
cout << ans;
return 0;
}