CodeEff/ECCO huggingface dataset:
# Original solution
from collections import defaultdict
import sys
input = sys.stdin.readline

N = int(eval(input()))
S = [input().rstrip() for _ in range(N)]
S.sort(key=lambda s: -len(s))
dic = [defaultdict(int) for _ in range(26)]
cnt1 = [0] * 26
ans = 0
for s in S:
    if len(s) == 1:
        ans += cnt1[ord(s[0]) - ord('a')]
    else:
        ans += dic[ord(s[0]) - ord('a')][s[1:][::-1]]
    cnt = [0] * 26
    for c in s:
        cnt[ord(c) - ord('a')] += 1
    for c in range(26):
        if cnt[c] > 0:
            cnt1[c] += 1
    t = ''
    for i in range(len(s) - 1, -1, -1):
        t += s[i]
        cnt[ord(s[i]) - ord('a')] -= 1
        for c in range(26):
            if cnt[c] > 0:
                dic[c][t] += 1
print(ans)


# Optimized solution
import sys
input = sys.stdin.readline

base = 1999849216943526259
mod = (1 << 61) - 1

N = int(eval(input()))
S = [input().rstrip()[::-1] for _ in range(N)]
S.sort(key=lambda s: -len(s))
cnt = {}
ans = 0
one = [0] * 26
for s in S:
    n = len(s)
    if n == 1:
        ans += one[ord(s[0]) - ord('a')]
        continue
    hashes = [0] * (n - 1)
    hashes[0] = ord(s[0])
    for i in range(1, n - 1):
        hashes[i] = (hashes[i-1] * base + ord(s[i])) % mod
    if hashes[-1] in cnt:
        ans += cnt[hashes[-1]][ord(s[-1]) - ord('a')]
    found = [0] * 26
    found[ord(s[-1]) - ord('a')] = 1
    for i in range(n - 2, 0, -1):
        found[ord(s[i]) - ord('a')] = 1
        if hashes[i-1] not in cnt:
            cnt[hashes[i-1]] = [0] * 26
        for c in range(26):
            cnt[hashes[i-1]][c] += found[c]
    found[ord(s[0]) - ord('a')] = 1
    for c in range(26):
        one[c] += found[c]
print(ans)
# Original solution
import sys
input = sys.stdin.readline

base = 1000
mod = 10**23 + 117

N = int(eval(input()))
S = [input().rstrip()[::-1] for _ in range(N)]
S.sort(key=lambda s: -len(s))
cnt = {}
ans = 0
one = [0] * 26
for s in S:
    n = len(s)
    if n == 1:
        ans += one[ord(s[0]) - ord('a')]
        continue
    hashes = [0] * (n - 1)
    hashes[0] = ord(s[0])
    for i in range(1, n - 1):
        hashes[i] = (hashes[i-1] * base + ord(s[i])) % mod
    if hashes[-1] in cnt:
        ans += cnt[hashes[-1]][ord(s[-1]) - ord('a')]
    found = [0] * 26
    found[ord(s[-1]) - ord('a')] = 1
    for i in range(n - 2, 0, -1):
        found[ord(s[i]) - ord('a')] = 1
        if hashes[i-1] not in cnt:
            cnt[hashes[i-1]] = [0] * 26
        for c in range(26):
            cnt[hashes[i-1]][c] += found[c]
    found[ord(s[0]) - ord('a')] = 1
    for c in range(26):
        one[c] += found[c]
print(ans)


# Optimized solution
import sys
input = sys.stdin.readline

base = 30
mod = 10**17 + 3

N = int(eval(input()))
S = [input().rstrip()[::-1] for _ in range(N)]
S.sort(key=lambda s: -len(s))
cnt = {}
ans = 0
one = [0] * 26
for s in S:
    n = len(s)
    if n == 1:
        ans += one[ord(s[0]) - ord('a')]
        continue
    hashes = [0] * (n - 1)
    hashes[0] = ord(s[0]) - ord('a') + 1
    for i in range(1, n - 1):
        hashes[i] = (hashes[i-1] * base + ord(s[i]) - ord('a') + 1) % mod
    if hashes[-1] in cnt:
        ans += cnt[hashes[-1]][ord(s[-1]) - ord('a')]
    found = [0] * 26
    found[ord(s[-1]) - ord('a')] = 1
    for i in range(n - 2, 0, -1):
        found[ord(s[i]) - ord('a')] = 1
        if hashes[i-1] not in cnt:
            cnt[hashes[i-1]] = [0] * 26
        for c in range(26):
            cnt[hashes[i-1]][c] += found[c]
    found[ord(s[0]) - ord('a')] = 1
    for c in range(26):
        one[c] += found[c]
print(ans)
# Original solution
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)

def solve():
    ordA = ord('a')

    N = int(eval(input()))
    Sss = [input().rstrip() for _ in range(N)]

    Sss.sort(key=lambda x: len(x))

    fsss = []
    Ass = []
    for Ss in Sss:
        As = [ord(S)-ordA for S in Ss[::-1]]
        Ass.append(As)
        fss = []
        fs = [0] * 26
        for i in reversed(list(range(len(As)))):
            fs[As[i]] = 1
            fss.append(fs[:])
        fsss.append(fss[::-1])

    ans = 0
    nodes = []
    nodes.append([-1]*26)
    nums = []
    nums.append([0]*26)
    numNode = 1
    for As, fss in zip(Ass, fsss):
        lenA = len(As)
        iNode = 0
        for j in range(lenA):
            A = As[j]
            fs = fss[j]
            for c in range(26):
                if fs[c]:
                    ans += nums[iNode][c]

            if nodes[iNode][A] == -1:
                nodes.append([-1]*26)
                nums.append([0]*26)
                nodes[iNode][A] = numNode
                numNode += 1
            else:
                pass

            if j == lenA-1:
                nums[iNode][As[-1]] += 1

            iNode = nodes[iNode][A]

    print(ans)


solve()


# Optimized solution
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)

def solve():
    ordA = ord('a')

    N = int(eval(input()))
    Ass = []
    for _ in range(N):
        Ss = input().rstrip()
        As = [ord(S)-ordA for S in Ss[::-1]]
        Ass.append(As)

    Ass.sort(key=lambda x: len(x))

    fsss = []
    for As in Ass:
        fss = []
        fs = [0] * 26
        for i in reversed(list(range(len(As)))):
            fs[As[i]] = 1
            fss.append(fs[:])
        fsss.append(fss[::-1])

    ans = 0
    nodes = []
    nodes.append([-1]*26)
    nums = []
    nums.append([0]*26)
    numNode = 1
    for As, fss in zip(Ass, fsss):
        lenA = len(As)
        iNode = 0
        for j in range(lenA):
            A = As[j]
            fs = fss[j]
            for c in range(26):
                if fs[c]:
                    ans += nums[iNode][c]

            if nodes[iNode][A] == -1:
                nodes.append([-1]*26)
                nums.append([0]*26)
                nodes[iNode][A] = numNode
                numNode += 1
            else:
                pass

            if j == lenA-1:
                nums[iNode][As[-1]] += 1

            iNode = nodes[iNode][A]

    print(ans)


solve()
# Original solution
# import sys; input = sys.stdin.buffer.readline
# sys.setrecursionlimit(10**7)
# from collections import defaultdict
ALPHABET_SIZE = 26

def getlist():
	return list(map(int, input().split()))

class Node(object):
	def __init__(self, char, ALPHABET_SIZE):
		self.char = char
		self.children = [-1] * ALPHABET_SIZE
		self.flag = [0] * ALPHABET_SIZE

class Trie(object):
	def __init__(self):
		self.root = Node(' ', ALPHABET_SIZE)

	def _convert_char_to_num(self, char):
		return ord(char) - ord('a')

	def insert(self, word, tail):
		res = 0 #合う値
		current = self.root
		currentFlag = [0] * ALPHABET_SIZE

		for char in word:
			char_index = self._convert_char_to_num(char)
			for i in range(ALPHABET_SIZE):
				currentFlag[i] += current.flag[i]
			res += currentFlag[char_index]
			currentFlag[char_index] = 0

			if current.children[char_index] != -1:
				current = current.children[char_index]

			else:
				new_node = Node(char, ALPHABET_SIZE)
				current.children[char_index] = new_node
				current = new_node

		char_index = self._convert_char_to_num(tail)
		res += currentFlag[char_index]

		current.flag[self._convert_char_to_num(tail)] += 1

		return res

#処理内容
def main():
	N = int(eval(input()))
	L = []
	for i in range(N):
		S = input()[::-1]
		L.append([len(S), S])

	L.sort(key = lambda x:x[0])

	ans = 0
	trie = Trie()
	for val, s in L:
		s1 = s[:-1]
		tail = s[-1]
		ans += trie.insert(s1, tail)
		# print(ans)

	print(ans)

if __name__ == '__main__':
	main()


# Optimized solution
# import sys; input = sys.stdin.buffer.readline
# sys.setrecursionlimit(10**7)
# from collections import defaultdict
ALPHABET_SIZE = 26

def getlist():
	return list(map(int, input().split()))

class Node(object):
	def __init__(self, char):
		self.char = char
		self.children = {}
		self.flag = [0] * ALPHABET_SIZE

class Trie(object):
	def __init__(self):
		self.root = Node(' ')

	def _convert_char_to_num(self, char):
		return ord(char) - 97

	def insert(self, word, tail):
		res = 0 #合う値
		current = self.root
		currentFlag = [0] * ALPHABET_SIZE

		for char in word:
			char_index = self._convert_char_to_num(char)
			for i in range(ALPHABET_SIZE):
				currentFlag[i] += current.flag[i]
			res += currentFlag[char_index]
			currentFlag[char_index] = 0

			if char_index in current.children:
				current = current.children[char_index]

			# if current.children[char_index] != -1:
			# 	current = current.children[char_index]
			else:
				new_node = Node(char)
				current.children[char_index] = new_node
				current = new_node

		char_index = self._convert_char_to_num(tail)
		res += currentFlag[char_index]

		current.flag[self._convert_char_to_num(tail)] += 1

		return res

#処理内容
def main():
	N = int(eval(input()))
	L = []
	for i in range(N):
		S = input()[::-1]
		L.append([len(S), S])

	L.sort(key = lambda x:x[0])

	ans = 0
	trie = Trie()
	for val, s in L:
		s1 = s[:-1]
		tail = s[-1]
		ans += trie.insert(s1, tail)
		# print(ans)

	print(ans)

if __name__ == '__main__':
	main()
# Original solution
import sys,queue,math,copy,itertools,bisect,collections,heapq

def main():
    MOD = 2 ** 61 - 1
    NI = lambda : int(sys.stdin.readline())
    SI = lambda : sys.stdin.readline().rstrip()

    N = NI()
    cnt = collections.defaultdict(int)
    ans = 0
    S = [SI() for _ in range(N)]
    for s in S:
        cnt[s[1:]] |= 1<<(ord(s[0])-ord('a'))

    for s in S:
        a = []
        bit = 0
        for x in s:
            x = ord(x) - ord('a')
            bit |= 1 << x
            a.append(bit)
        for i in range(len(s),1,-1):
            if i == len(s):
                d = ''
            else:
                d = s[i:]
            ans += bin(cnt[d] & a[i-1]).count('1')

    print(ans)
if __name__ == '__main__':
    main()

# Optimized solution
import sys,queue,math,copy,itertools,bisect,collections,heapq

def main():
    MOD = 2 ** 61 - 1
    NI = lambda : int(sys.stdin.readline())
    SI = lambda : sys.stdin.readline().rstrip()

    N = NI()
    cnt = collections.defaultdict(int)
    ans = 0
    S = [SI() for _ in range(N)]
    for s in S:
        h = 0
        for i in range(len(s)-1,0,-1):
            h = (h * 27 + ord(s[i]) - ord('a') + 1) % MOD
        cnt[h] |= 1<<(ord(s[0])-ord('a'))

    for s in S:
        a = []
        bit = 0
        for x in s:
            x = ord(x) - ord('a')
            bit |= 1 << x
            a.append(bit)
        h = 0
        for i in range(len(s)-1,0,-1):
            ans += bin(cnt[h] & a[i]).count('1')
            h = (h * 27 + ord(s[i]) - ord('a') + 1) % MOD

    print(ans)
if __name__ == '__main__':
    main()
# Original solution
import sys
input = sys.stdin.readline

N = int(eval(input()))
S = [input().rstrip()[::-1] for i in range(N)]
S.sort(key=lambda x:-len(x))
P = 2**61 - 1

from collections import defaultdict,Counter
D = defaultdict(lambda: Counter())

ans = 0
for s in S:
    sets = [set()]
    for c in s[::-1]:
        i = ord(c) - ord('a')
        sets.append(sets[-1] | {i})
    sets.reverse()
    nxs = []
    a = 0
    for l,(c,st) in enumerate(zip(s,sets)):
        for j in st:
            na = (a*27 + (j+1)) % P
            nxs.append((na,l))
        i = ord(c) - ord('a') + 1
        a *= 27
        a += i
        a %= P
    if a in D[len(s)-1]:
        ans += D[len(s)-1][a]
    for na,l in nxs:
        D[l][na] += 1

print(ans)

# Optimized solution
import sys
input = sys.stdin.readline

N = int(eval(input()))
S = [input().rstrip()[::-1] for i in range(N)]
S.sort(key=len)
P = 2**61 - 1

from collections import defaultdict
D = defaultdict(lambda: [0]*26)

ans = 0
for s in S:
    l = ord(s[-1]) - ord('a')
    a = 0
    tmp = [0] * 26
    for c in s[:-1]:
        i = ord(c) - ord('a')
        if a in D:
            for j in range(26):
                tmp[j] += D[a][j]
        ans += tmp[i]
        tmp[i] = 0
        a = (a*27 + i + 1) % P
    ans += tmp[l]
    D[a][l] += 1

print(ans)
# Original solution
import sys
input = sys.stdin.readline


class RollingHash:
    def __init__(self, string):
        self.n = len(string)
        self.BASE = 1234
        self.MOD = (1 << 61) - 1
        self.hash = [0] * (self.n + 1)
        self.pow = [1] * (self.n + 1)

        for i, char in enumerate(string):
            self.hash[i + 1] = (self.hash[i] + ord(char)) * self.BASE % self.MOD
            self.pow[i + 1] = (self.pow[i] * self.BASE) % self.MOD

    def get_hash(self, l, r):
        """string[l:r]のハッシュ値を返す。O(1)"""
        res = (self.hash[r] - self.hash[l] * self.pow[r - l]) % self.MOD
        return res


n = int(eval(input()))
s = [input()[:-1] for i in range(n)]


s.sort(key=len)
str_set = set()
cnt = 0

for string in s:
    string = string[::-1]
    n = len(string)
    rh = RollingHash(string)

    for r in range(1, n + 1):
        if rh.get_hash(0, r) in str_set:
            cnt += 1

    set_char = set()
    for r in range(1, n + 1)[::-1]:
        set_char.add(string[r - 1])
        for char in set_char:
            if char == string[r - 1]:
                continue
            h = (rh.hash[r - 1] + ord(char)) * rh.BASE % rh.MOD
            if h in str_set:
                cnt += 1
    str_set.add(rh.get_hash(0, n))

print(cnt)

# Optimized solution
import sys
input = sys.stdin.readline


class RollingHash:
    def __init__(self, string):
        self.n = len(string)
        self.BASE = 1234
        self.MOD = (1 << 45) - 1
        self.hash = [0] * (self.n + 1)
        self.pow = [1] * (self.n + 1)

        for i, char in enumerate(string):
            self.hash[i + 1] = (self.hash[i] + ord(char)) * self.BASE % self.MOD
            self.pow[i + 1] = (self.pow[i] * self.BASE) % self.MOD

    def get_hash(self, l, r):
        """string[l:r]のハッシュ値を返す。O(1)"""
        res = (self.hash[r] - self.hash[l] * self.pow[r - l]) % self.MOD
        return res


n = int(eval(input()))
s = [input()[:-1] for i in range(n)]


s.sort(key=len)
str_set = set()
cnt = 0

for string in s:
    string = string[::-1]
    n = len(string)
    rh = RollingHash(string)

    for r in range(1, n + 1):
        if rh.get_hash(0, r) in str_set:
            cnt += 1

    set_char = set()
    for r in range(1, n + 1)[::-1]:
        set_char.add(string[r - 1])
        for char in set_char:
            if char == string[r - 1]:
                continue
            h = (rh.hash[r - 1] + ord(char)) * rh.BASE % rh.MOD
            if h in str_set:
                cnt += 1
    str_set.add(rh.get_hash(0, n))

print(cnt)
# Original solution
import sys
input = sys.stdin.readline


class RollingHash:
    def __init__(self, string):
        self.n = len(string)
        self.BASE = 1234
        self.MOD = (1 << 61) - 1
        self.hash = [0] * (self.n + 1)
        self.pow = [1] * (self.n + 1)

        for i, char in enumerate(string):
            self.hash[i + 1] = (self.hash[i] * self.BASE + ord(char)) % self.MOD
            self.pow[i + 1] = (self.pow[i] * self.BASE) % self.MOD

    def get_hash(self, l, r):
        """string[l:r]のハッシュ値を返す。O(1)"""
        res = (self.hash[r] - self.hash[l] * self.pow[r - l]) % self.MOD
        return res


n = int(eval(input()))
s = [input()[:-1] for i in range(n)]


s.sort(key=len)
str_set = set()
cnt = 0

for string in s:
    string = string[::-1]
    n = len(string)
    rh = RollingHash(string)

    for r in range(1, n + 1):
        if rh.get_hash(0, r) in str_set:
            cnt += 1

    set_char = set()
    for r in range(1, n + 1)[::-1]:
        set_char.add(string[r - 1])
        for char in set_char:
            if char == string[r - 1]:
                continue
            h = (rh.hash[r - 1] * rh.BASE + ord(char)) % rh.MOD
            if h in str_set:
                cnt += 1
    str_set.add(rh.get_hash(0, n))

print(cnt)

# Optimized solution
import sys
input = sys.stdin.readline


class RollingHash:
    def __init__(self, string):
        self.n = len(string)
        self.BASE = 1234
        self.MOD = 92709568269121
        self.hash = [0] * (self.n + 1)
        self.pow = [1] * (self.n + 1)

        for i, char in enumerate(string):
            self.hash[i + 1] = (self.hash[i] * self.BASE + ord(char)) % self.MOD
            self.pow[i + 1] = (self.pow[i] * self.BASE) % self.MOD

    def get_hash(self, l, r):
        """string[l:r]のハッシュ値を返す。O(1)"""
        res = (self.hash[r] - self.hash[l] * self.pow[r - l]) % self.MOD
        return res


n = int(eval(input()))
s = [input()[:-1] for i in range(n)]


s.sort(key=len)
str_set = set()
cnt = 0

for string in s:
    string = string[::-1]
    n = len(string)
    rh = RollingHash(string)

    for r in range(1, n + 1):
        if rh.get_hash(0, r) in str_set:
            cnt += 1

    set_char = set()
    for r in range(1, n + 1)[::-1]:
        set_char.add(string[r - 1])
        for char in set_char:
            if char == string[r - 1]:
                continue
            h = (rh.hash[r - 1] * rh.BASE + ord(char)) % rh.MOD
            if h in str_set:
                cnt += 1
    str_set.add(rh.get_hash(0, n))

print(cnt)
# Original solution
import sys
input = lambda: sys.stdin.readline().rstrip()
P = 10 ** 40 + 121
N = int(eval(input()))
X = sorted([input()[::-1] for _ in range(N)], key = len)

D = {}
ans = 0
for x in X:
    L = [0] * 26
    T, a = x[:-1], ord(x[-1]) - 97
    h = 0
    for t in T:
        if h in D:
            for i in range(26):
                L[i] += D[h][i]
        b = ord(t) - 97
        ans += L[b]
        L[b] = 0
        
        h = (h + b + 135) * 71 % P
    ans += L[a]
    if h in D:
        D[h][a] += 1
    else:
        D[h] = [0] * 26
        D[h][a] = 1
    
print(ans)

# Optimized solution
import sys
input = lambda: sys.stdin.readline().rstrip()
m = 2 ** 150 - 1
N = int(eval(input()))
X = sorted([input()[::-1] for _ in range(N)], key = len)

D = {}
ans = 0
for x in X:
    L = [0] * 26
    T, a = x[:-1], ord(x[-1]) - 97
    h = 0
    for t in T:
        if h in D:
            for i in range(26):
                L[i] += D[h][i]
        b = ord(t) - 97
        ans += L[b]
        L[b] = 0
        
        h = (h * 71 + b + 135) & m
    ans += L[a]
    if h in D:
        D[h][a] += 1
    else:
        D[h] = [0] * 26
        D[h][a] = 1
    
print(ans)
# Original solution
import sys;input=sys.stdin.readline
from collections import defaultdict
N, = list(map(int, input().split()))
S = []
for _ in range(N):
    s = input().strip()
    S.append(s)
S.sort(key=lambda x:len(x))
D = defaultdict(set)
R = 0
for s in S:
    l = len(s)
    d = defaultdict(int)
    for c in D[""]:
        d[c] += 1
    for i in range(l-1, -1, -1):
        R += d[s[i]]
        d[s[i]] = 0
        for c in D[s[i:]]:
            d[c] += 1
    D[s[1:]].add(s[0])
print(R)


# Optimized solution
import sys;input=sys.stdin.readline
N, = list(map(int, input().split()))
S = []
for _ in range(N):
    s = input().strip()
    S.append(s)
S.sort(key=lambda x:len(x))
D = dict()
dd = set()
R = 0
for s in S:
    l = len(s)
    d = [0]*26
    for c in dd:
        d[c] += 1
    mm = 0
    for i in range(l-1, -1, -1):
        cc = ord(s[i]) - 97
        R += d[cc]
        d[cc] = 0
        if s[i:] in D:
            for c in D[s[i:]]:
                d[c] += 1
        if i == 0:
            f = cc
        mm += 1
    if l != 1:
        if s[1:] not in D:
            D[s[1:]] = set()
        D[s[1:]].add(f)
    else:
        dd.add(f)
print(R)
# Original solution
# Acceptance of input

import sys

f_i = sys.stdin

n = int(f_i.readline())

edges = [[None] * n for i in range(n)]

for l_i in f_i:
    s, t, w = list(map(int, l_i.split()))
    edges[s][t] = w
    edges[t][s] = w

# dfs tree walk 1

import collections

path = collections.deque()
path.append(0)

distance = 0
max_distance = 0

end_point = 0

unvisited = [False] + [True] * (n - 1)

while True:
    u = path[-1]
    adj_e = edges[u]
    for v, e in enumerate(adj_e):
        if unvisited[v] and e != None:
            path.append(v)
            distance += e
            unvisited[v] = False
            if max_distance < distance:
                max_distance = distance
                end_point = v
            break
    if u == path[-1]:
        path.pop()
        if path:
            distance -= edges[u][path[-1]]
        else:
            break

# Measurement of diameter(dfs tree walk 2)

path.append(end_point)

distance = 0
diameter = 0

unvisited = [True] * n
unvisited[end_point] = False

while True:
    u = path[-1]
    adj_e = edges[u]
    for v, e in enumerate(adj_e):
        if unvisited[v] and e != None:
            path.append(v)
            distance += e
            unvisited[v] = False
            if diameter < distance:
                diameter = distance
                end_point = v
            break
    if u == path[-1]:
        path.pop()
        if path:
            distance -= edges[u][path[-1]]
        else:
            break

# output

print(diameter)

# Optimized solution
# Acceptance of input

import sys

f_i = sys.stdin

n = int(f_i.readline())

edges = [[] for i in range(n)]

for l_i in f_i:
    s, t, w = list(map(int, l_i.split()))
    edges[s].append((t, w))
    edges[t].append((s, w))

# Tree Walk function

import collections

def tree_walk(start, switch = 0):
    path = collections.deque()
    path.append(start)

    weight = collections.deque()
    weight.append(0)
    
    unvisited = [True] * n
    unvisited[start] = False
    
    rest = n - 1
    end_point = start
    diameter = 0
    
    while True:
        u = path[-1]
        for v, w in edges[u]:
            if unvisited[v]:
                path.append(v)
                unvisited[v] = False
                rest -= 1
                weight.append(w)
                break

        if u == path[-1]:
            distance = sum(weight)
            if diameter < distance:
                diameter = distance
                end_point = u
            if rest == 0:
                break
            path.pop()
            weight.pop()

    if switch:
        print(diameter)
    else:
        return end_point

# Output

tree_walk(tree_walk(0), 1)
# Original solution
from heapq import heappop, heappush

INF = 10 ** 20

n = int(eval(input()))
edges = [[] for _ in range(n)]
for _ in range(n - 1):
  s, t, w = list(map(int, input().split()))
  edges[s].append((w, t))
  edges[t].append((w, s))

cost = [INF] * n
que = [(0, 0)]
cost[0] = 0

while que:
  acc, num = heappop(que)
  for weight, to in edges[num]:
    if weight + acc < cost[to]:
      cost[to] = weight + acc
      heappush(que, (weight + acc, to))

max_ind = cost.index(max(cost))
cost = [INF] * n
que = [(0, max_ind)]
cost[max_ind] = 0
while que:
  acc, num = heappop(que)
  for weight, to in edges[num]:
    if weight + acc < cost[to]:
      cost[to] = weight + acc
      heappush(que, (weight + acc, to))

print((max(cost)))


# Optimized solution
from heapq import heappop, heappush

INF = 10 ** 20

def main():
  n = int(eval(input()))
  edges = [[] for _ in range(n)]
  for _ in range(n - 1):
    s, t, w = list(map(int, input().split()))
    edges[s].append((w, t))
    edges[t].append((w, s))
  
  def func(start):
    cost = [INF] * n
    que = [(0, start)]
    cost[start] = 0
    
    while que:
      acc, num = heappop(que)
      for weight, to in edges[num]:
        if weight + acc < cost[to]:
          cost[to] = weight + acc
          heappush(que, (weight + acc, to))
    return cost
  
  cost1 = func(0)
  max_ind = cost1.index(max(cost1))
  cost2 = func(max_ind)
  
  print((max(cost2)))
main()