#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <typename A, typename B>
ostream &operator<<(ostream &out, pair<A, B> p) {
  return out << '(' << p.first << ", " << p.second << ')';
}
template <typename A,
          typename B = typename enable_if<!is_same<A, string>::value,
                                          typename A::value_type>::type>
ostream &operator<<(ostream &out, A vector) {
  out << '{';
  string sep;
  for (B x : vector) out << sep << x, sep = ", ";
  return out << '}';
}
void dbg_print() { cerr << endl; }
template <typename A, typename... B>
void dbg_print(A a, B... b) {
  cerr << ' ' << a;
  dbg_print(b...);
}
const int N = 2e5 + 4;
vector<pair<int, int>> g[N];
int n, par[N], root, where;
array<int, 3> edge;
bool used[N], on_way[N];
ll deapest[N], dp[N];
vector<int> path;
ll at_least, ans, cur_ans;
ll sum_up[N], sum_down[N], suf_max[N], cur_max;
multiset<ll> up, down;
void dfs(int v) {
  used[v] = 1;
  for (auto [u, w] : g[v]) {
    if (u == par[v]) continue;
    if (used[u]) {
      edge = {v, u, w};
      continue;
    }
    par[u] = v;
    dfs(u);
  }
}
inline ll get_down(vector<ll> down) {
  if (((int)((down).size())) == 0) return 0;
  if (((int)((down).size())) == 1) return down[0];
  sort(begin(down), end(down));
  return down.end()[-1] + down.end()[-2];
}
void init(int v) {
  vector<ll> down;
  down.reserve(((int)((g[v]).size())));
  for (auto [u, w] : g[v]) {
    if (u == par[v]) continue;
    par[u] = v;
    init(u);
    dp[v] = max(dp[v], dp[u]);
    deapest[v] = max(deapest[v], deapest[u] + w);
    down.push_back(deapest[u] + w);
  }
  dp[v] = max(dp[v], get_down(down));
}
inline ll get_max(multiset<ll> &st) { return *st.rbegin(); }
int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr);
  cin >> n;
  for (int i = 0; i < n; i++) {
    int v, u, w;
    cin >> v >> u >> w, v--, u--;
    g[v].emplace_back(u, w);
    g[u].emplace_back(v, w);
  }
  dfs(0);
  g[edge[0]].erase(find(begin(g[edge[0]]), end(g[edge[0]]),
                        pair<int, int>{edge[1], edge[2]}));
  g[edge[1]].erase(find(begin(g[edge[1]]), end(g[edge[1]]),
                        pair<int, int>{edge[0], edge[2]}));
  root = edge[0];
  where = edge[1];
  par[root] = -1;
  init(root);
  ans = dp[root];
  for (int i = where; i != -1; i = par[i]) {
    on_way[i] = 1;
    path.push_back(i);
  }
  for (int i = 0; i < n; i++) {
    if (!on_way[i]) at_least = max(at_least, dp[i]);
  }
  for (auto v : path) {
    vector<ll> down;
    deapest[v] = 0;
    for (auto [u, w] : g[v]) {
      if (u == par[v] || on_way[u]) continue;
      down.push_back(deapest[u] + w);
      deapest[v] = max(deapest[v], deapest[u] + w);
    }
    at_least = max(at_least, get_down(down));
  }
  for (int i = ((int)((path).size())) - 2; i >= 0; i--) {
    sum_up[i] = sum_up[i + 1];
    for (auto [u, w] : g[path[i + 1]]) {
      if (on_way[u] && u != par[path[i + 1]]) sum_up[i] += w;
    }
  }
  for (int i = 1; i < ((int)((path).size())); i++) {
    sum_down[i] = sum_down[i - 1];
    for (auto [u, w] : g[path[i]]) {
      if (on_way[u] && u != par[path[i]]) sum_down[i] += w;
    }
  }
  for (int i = ((int)((path).size())) - 1; i >= 0; i--) {
    if (i != ((int)((path).size())) - 1) suf_max[i] = suf_max[i + 1];
    suf_max[i] = max(suf_max[i], cur_max + deapest[path[i]] + sum_up[i]);
    cur_max = max(cur_max, deapest[path[i]] - sum_up[i]);
  }
  for (int i = 0; i < ((int)((path).size())); i++) {
    up.insert(deapest[path[i]] + sum_up[i]);
  }
  cur_ans = at_least;
  for (int i = 0; i < ((int)((path).size())) - 1; i++) {
    up.erase(up.find(deapest[path[i]] + sum_up[i]));
    down.insert(deapest[path[i]] + sum_down[i]);
    cur_ans = max(cur_ans, dp[path[i]]);
    ans = min(ans, max({cur_ans, edge[2] + get_max(up) + get_max(down),
                        suf_max[i + 1]}));
  }
  cout << ans << '\n';
}
