import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;

class Graph {
    struct Edge {
        int from, to, cost;
    }
    Edge[][] G;
    int N;
    this(int N) {
        this.N = N;
        G = new Edge[][N];
    }
    void addEdge(int from, int to, int cost = 1) {
        G[from] ~= Edge(from, to, cost);
        G[to] ~= Edge(to, from, cost);
    }
    int diameter() {
        auto dist = new int[N];
        dist[] = -1;
        void dfs(int u, int v, int t) {
            assert(dist[v] < 0); // この条件でfailするならループが存在
            dist[v] = t;
            foreach (e; G[v]) {
                if (u == e.to) continue;
                dfs(v, e.to, dist[v] + e.cost);
            }
        }
        dfs(-1, 0, 0);
        int most_distant = cast(int)dist.countUntil(dist.reduce!max);
        dist[] = -1;
        dfs(-1, most_distant, 0);
        return dist.reduce!max;
    }
}

void main() {
    int N; scanf("%d\n", &N);
    auto G = new Graph(N);
    foreach (i; 0 .. N - 1) {
        int s, t, w; scanf("%d %d %d\n", &s, &t, &w);
        G.addEdge(s, t, w);
    }
    writeln(G.diameter);
}