#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200000 + 10;
const int MAXM = MAXN * 2;
const long long Inf = 100000000000000000LL;
int n;
int A[MAXN], B[MAXN], C[MAXN];
int To[MAXM], Cost[MAXM], Next[MAXM], Node[MAXN], nE;
void InsertEdge(int a, int b, int c) {
  To[nE] = b;
  Cost[nE] = c;
  Next[nE] = Node[a];
  Node[a] = nE++;
}
int InStack[MAXN], Stack[MAXN], StkC[MAXN];
int Cycle[MAXN], nCycle, InCycle[MAXN], CycleLen[MAXN];
int DFS_FindCycle(int i, int Par, int Dep) {
  InStack[i] = 1;
  Stack[Dep] = i;
  for (int p = Node[i]; p != -1; p = Next[p]) {
    int j = To[p];
    if (j == Par) continue;
    if (InStack[j]) {
      nCycle = 0;
      StkC[Dep] = Cost[p];
      for (int k = Dep;; k--) {
        InCycle[Stack[k]] = 1;
        Cycle[nCycle] = Stack[k];
        CycleLen[nCycle] = StkC[k];
        nCycle++;
        if (Stack[k] == j) break;
      }
      int tmp = CycleLen[0];
      for (int k = 0; k < nCycle; k++) CycleLen[k] = CycleLen[k + 1];
      CycleLen[nCycle - 1] = tmp;
      return 1;
    } else {
      StkC[Dep] = Cost[p];
      if (DFS_FindCycle(j, i, Dep + 1)) return 1;
    }
  }
  InStack[i] = 0;
  return 0;
}
long long Deepest[MAXN], Deepest_id[MAXN];
void DFS_Deepest(int i, int Par, int Root, long long Depth) {
  if (Depth > Deepest[Root]) {
    Deepest[Root] = Depth;
    Deepest_id[Root] = i;
  }
  for (int p = Node[i]; p != -1; p = Next[p]) {
    int j = To[p];
    if (j != Root && InCycle[j]) continue;
    if (j == Par) continue;
    DFS_Deepest(j, i, Root, Depth + Cost[p]);
  }
}
long long MaxInTree[MAXN];
void DFS_MaxInTree(int i, int Par, int Root, long long Depth) {
  if (Depth > MaxInTree[Root]) MaxInTree[Root] = Depth;
  for (int p = Node[i]; p != -1; p = Next[p]) {
    int j = To[p];
    if (j != Root && InCycle[j]) continue;
    if (j == Par) continue;
    DFS_MaxInTree(j, i, Root, Depth + Cost[p]);
  }
}
long long Dist[MAXN * 2], DistAndInside[MAXN * 2], Deep[MAXN * 2];
void Work() {
  scanf("%d", &n);
  memset(Node, -1, sizeof(Node));
  nE = 0;
  for (int i = 0; i < n; i++) {
    scanf("%d%d%d", &A[i], &B[i], &C[i]);
    A[i]--;
    B[i]--;
    InsertEdge(A[i], B[i], C[i]);
    InsertEdge(B[i], A[i], C[i]);
  }
  DFS_FindCycle(0, -1, 0);
  long long Ans1 = 0, Ans2 = 0;
  for (int i = 0; i < n; i++)
    if (InCycle[i]) {
      Deepest[i] = -1;
      DFS_Deepest(i, -1, i, 0);
      DFS_MaxInTree(Deepest_id[i], -1, i, 0);
      Ans1 = max(Ans1, MaxInTree[i]);
    }
  Dist[0] = 0;
  Deep[0] = Deepest[Cycle[0]];
  for (int i = 1; i < nCycle * 2; i++) {
    Dist[i] = Dist[i - 1] + CycleLen[(i - 1) % nCycle];
    Deep[i] = Deepest[Cycle[i % nCycle]];
  }
  set<pair<long long, int> > Set1, Set2;
  for (int i = 0; i < nCycle; i++) {
    Set1.insert(make_pair(-(Deep[i] + Dist[i]), i));
    Set2.insert(make_pair(-(Deep[i] - Dist[i]), i));
  }
  Ans2 = 100000000000000000LL;
  for (int i = 0; i < nCycle; i++) {
    auto tmp1 = *Set1.begin();
    Set1.erase(tmp1);
    int s1_1 = tmp1.second;
    int s1_2 = Set1.begin()->second;
    Set1.insert(tmp1);
    auto tmp2 = *Set2.begin();
    Set2.erase(tmp2);
    int s2_1 = tmp2.second;
    int s2_2 = Set2.begin()->second;
    Set2.insert(tmp2);
    long long cur;
    if (s1_1 != s2_1)
      cur = Deep[s1_1] + Dist[s1_1] + Deep[s2_1] - Dist[s2_1];
    else
      cur = max(Deep[s1_1] + Dist[s1_1] + Deep[s2_2] - Dist[s2_2],
                Deep[s1_2] + Dist[s1_2] + Deep[s2_1] - Dist[s2_1]);
    Ans2 = min(Ans2, cur);
    Set1.erase(make_pair(-(Deep[i] + Dist[i]), i));
    Set1.insert(make_pair(-(Deep[i + nCycle] + Dist[i + nCycle]), i + nCycle));
    Set2.erase(make_pair(-(Deep[i] - Dist[i]), i));
    Set2.insert(make_pair(-(Deep[i + nCycle] - Dist[i + nCycle]), i + nCycle));
  }
  printf("%I64d\n", max(Ans1, Ans2));
}
int main() {
  Work();
  return 0;
}
