CodeEff/ECCO huggingface dataset:
# Original solution
import sys
sys.setrecursionlimit(10**8)

def find_path(now, par):
    if now == n - 1:
        path.append(n - 1)
        return True
    for to in g[now]:
        if to == par: continue
        if find_path(to, now):
            path.append(now)
            return True
    return False

def dfs1(now, par, color):
    color[now] = "b"
    for to in g[now]:
        if to == par: continue
        if color[to] == "w": continue
        dfs1(to, now, color)

def dfs2(now, par, color):
    color[now] = "w"
    for to in g[now]:
        if to == par: continue
        if color[to] == "b": continue
        dfs2(to, now, color)

n = int(input())
g = [[] for _ in range(n)]
for i in range(n - 1):
    a, b = list(map(int, input().split()))
    a -= 1; b -=1
    g[a].append(b)
    g[b].append(a)
path = []
find_path(0, -1)
path.reverse()
color = ["bl"] * n
color[0] = "b"
color[n - 1] = "w"
j = 1
k = len(path) - 2
for i in range(1, len(path) - 1):
    if i % 2 == 1:
        v = path[j]
        color[v] = "b"
        j += 1
    else:
        v = path[k]
        color[v] = "w"
        k -= 1
dfs1(0, -1, color)
dfs2(n - 1, -1, color)
cntf = 0
cnts = 0
for i in range(n):
    if color[i] == "b":
        cntf += 1
    else:
        cnts += 1
if cntf > cnts:
    print("Fennec")
else:
    print("Snuke")


# Optimized solution
import sys
sys.setrecursionlimit(10**8)

def find_path(now, par):
    if now == n - 1:
        path.append(n - 1)
        return True
    for to in g[now]:
        if to == par: continue
        if find_path(to, now):
            path.append(now)
            return True
    return False

def dfs(now, par, color):
    color[now] = 'b'
    for to in g[now]:
        if to == par: continue
        if color[to] == "w": continue
        dfs(to, now, color)

n = int(input())
g = [[] for _ in range(n)]
for i in range(n - 1):
    a, b = list(map(int, input().split()))
    a -= 1; b -=1
    g[a].append(b)
    g[b].append(a)
path = []
find_path(0, -1)
path.reverse()
color = ["bl"] * n
color[0] = "b"
color[n - 1] = "w"
j = 1
k = len(path) - 2
for i in range(1, len(path) - 1):
    if i % 2 == 1:
        v = path[j]
        color[v] = "b"
        j += 1
    else:
        v = path[k]
        color[v] = "w"
        k -= 1
dfs(0, -1, color)
cnt = 0
for i in range(n):
    if color[i] == "b":
        cnt += 1
if cnt > n - cnt:
    print("Fennec")
else:
    print("Snuke")
# Original solution

def read_data():
    N = int(eval(input()))
    Es = [[] for i in range(N)]
    for i in range(N - 1):
        a, b = list(map(int, input().split()))
        Es[a - 1].append(b - 1)
        Es[b - 1].append(a - 1)
    return N, Es

def solve(N, Es):
    if N == 2:
        return "Snuke"
    path = find_path(N, 0, N - 1, Es)
    len_path = len(path)
    a = (len_path - 1)// 2
    b = a + 1
    p1 = path[a]
    p2 = path[b]
    e1 = count_edges(N, p1, p2, Es)
    e2 = N - e1
    if e1 > e2:
        return "Fennec"
    else:
        return "Snuke"

def find_path(N, s, g, Es):
    stack = [(s, 0)]
    path = []
    visited = [False] * N
    visited[s] = True
    while True:
        v, d = stack[-1]
        if (path and path[-1][0] == v):
            stack.pop()
            path.pop()
            continue
        if (path and path[-1][1] >= d):
            path.pop()
        path.append((v, d))
        for u in Es[v]:
            if visited[u]:
                continue
            stack.append((u, d + 1))
            visited[u] = True;
            if u == g:
                path = [p for p, depth in path] + [g]
                return path

def count_edges(N, p1, p2, Es):
    stack = [p1]
    visited = [False] * N
    visited[p1] = True
    visited[p2] = True
    count = 0
    while stack:
        v = stack.pop()
        count += 1
        for u in Es[v]:
            if visited[u]:
                continue
            stack.append(u)
            visited[u] = True
    return count


N, Es = read_data()
print((solve(N, Es)))
    

# Optimized solution
def read_data():
    N = int(eval(input()))
    Es = [[] for i in range(N)]
    for i in range(N - 1):
        a, b = list(map(int, input().split()))
        Es[a - 1].append(b - 1)
        Es[b - 1].append(a - 1)
    return N, Es

def solve(N, Es):
    if N == 2:
        return "Snuke"
    visited = [0] * N
    f1 = [0]
    fN = [N - 1]
    visited[0] = 1
    visited[N - 1] = -1
    while (f1 or fN):
        new_f1 = []
        for v in f1:
            for u in Es[v]:
                if visited[u]: continue
                visited[u] = 1
                new_f1.append(u)
        f1 = new_f1
        new_fN = []
        for v in fN:
            for u in Es[v]:
                if visited[u]: continue
                visited[u] = -1
                new_fN.append(u)
        fN = new_fN
    if sum(visited) > 0:
        return "Fennec"
    else:
        return "Snuke"

N, Es = read_data()
print((solve(N, Es)))
# Original solution

import sys

p = []
path = [ 0 for i in range(10**5+1)]
def main():

    sys.setrecursionlimit(1000000)

    N = int(eval(input()))

    e = [ [] for i in range(N)]
    for i in range(N-1):
        a,b = list(map(int,input().split()))
        a-=1
        b-=1
        e[a].append(b)
        e[b].append(a)

    col = [ -1 for i in range(N)]
    col[0] = 0
    
    def dfs(n,c):
        global p
        if n == N - 1:
            p = path
        path[c] = n
        for v in e[n]:
            if col[v] == -1:
                col[v] = c + 1
                dfs(v,c+1)
                if p:
                    return
    dfs(0,0)

    t = col[N-1] + 1
    if t % 2 ==0:
        sn = p[t//2]
    else:
        sn = p[t//2+1]


    colfn = [ -1 for i in range(N)]
    colfn[0] = 0
    def dfs2(n,c):

        for v in e[n]:
            if v == sn:
                continue
            elif colfn[v] == -1:
                colfn[v] = c + 1
                dfs2(v,c+1)

    dfs2(0,0)

    fennec = -1
    for i in range(N):
        if colfn[i] != -1:
            fennec += 1

    snuke = N - fennec - 2
    if fennec > snuke:
        print("Fennec")
    else:
        print("Snuke")



if __name__ == '__main__':
    main()



# Optimized solution

import sys
sys.setrecursionlimit(1000000)

N = int(eval(input()))

e = [ [] for i in range(N)]
for i in range(N-1):
    a,b = list(map(int,input().split()))
    a-=1
    b-=1
    e[a].append(b)
    e[b].append(a)

col = [ -1 for i in range(N)]
col[0] = 0

p = []
path = [ 0 for i in range(10**5+1)]
def dfs(n,c):
    global p
    if n == N - 1:
        p = path
    path[c] = n
    for v in e[n]:
        if col[v] == -1:
            col[v] = c + 1
            dfs(v,c+1)
            if p:
                return
dfs(0,0)

t = col[N-1] + 1
if t % 2 ==0:
    sn = p[t//2]
else:
    sn = p[t//2+1]


colfn = [ -1 for i in range(N)]
colfn[0] = 0
def dfs2(n,c):

    for v in e[n]:
        if v == sn:
            continue
        elif colfn[v] == -1:
            colfn[v] = c + 1
            dfs2(v,c+1)

dfs2(0,0)

fennec = -1
for i in range(N):
    if colfn[i] != -1:
        fennec += 1

snuke = N - fennec - 2
if fennec > snuke:
    print("Fennec")
else:
    print("Snuke")
# Original solution
n = int(input())
d = {}
for _ in range(n-1):
  v,u = list(map(int, input().split()))
  if v in d:
    d[v].append(u)
  else:
    d[v] = [u]

  if u in d:
    d[u].append(v)
  else:
    d[u] = [v]

visited = [False] * (n+1)
# 0 == fennec, 1 == sunuke
q = [(1,1,0), (n,n,1)]

count_f = 0
count_s = 0

while len(q) > 0:
  cur, prev, sunuke = q.pop(0)
  # print cur,prev,sunuke

  if visited[cur]:
    continue

  visited[cur] = True
  if sunuke:
    count_s += 1
  else:
    count_f += 1

  for v in d[cur]:
    q.append([v, cur, sunuke])

if count_f > count_s:
  print('Fennec')
else:
  print('Snuke')

# Optimized solution
n = int(input())
d = {}
for _ in range(n-1):
  v,u = list(map(int, input().split()))
  if v in d:
    d[v].append(u)
  else:
    d[v] = [u]

  if u in d:
    d[u].append(v)
  else:
    d[u] = [v]

# -1: not yet, 0: fennec, 1: sunuke
visited = [-1] * (n+1)
visited[1] = 0
visited[n] = 1

# 0 == fennec, 1 == sunuke
q = [(1,1), (n,n)]

# 0: fennec
# 1: sunuke
count = [1,1]

while len(q) > 0:
  cur, prev = q.pop(0)

  for v in d[cur]:
    if v == prev: continue
    if visited[v] != -1: continue

    chara = visited[prev]
    visited[v] = chara
    count[chara] += 1

    q.append([v, cur])


if count[0] > count[1]:
  print('Fennec')
else:
  print('Snuke')

# TLE
# while len(q) > 0:
#   cur, prev, sunuke = q.pop(0)
#   # print cur,prev,sunuke

#   if visited[cur]:
#     continue

#   visited[cur] = True
#   if sunuke:
#     count_s += 1
#   else:
#     count_f += 1

#   for v in d[cur]:
#     q.append([v, cur, sunuke])

# if count_f > count_s:
#   print 'Fennec'
# else:
#   print 'Snuke'
# Original solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 5
0 1 1
0 2 2
0 3 3
1 1 2
1 2 2

output:
3
2
"""

import sys


class BinaryIndexedTree(object):
    __slots__ = ('length', 'dat')

    def __init__(self, n):
        """
        Init a BIT with update and find for range sum queries.
        """
        self.length = int(n)
        self.dat = [0] * (self.length + 1)

    # sum(A[1] ... A[i])
    def __init_sum(self, i):
        _sum = 0
        while i > 0:
            _sum += self.dat[i]
            i -= i & (-i)
        return _sum

    def get_sum(self, s, t):
        return self.__init_sum(t) - self.__init_sum(s - 1)

    # A[i] += x
    def get_add(self, i, x):
        while i <= self.length:
            self.dat[i] += x
            i += i & (-i)
        return self.dat


def action(cmd_list):
    for query in cmd_list:
        cmd, ele_1, ele_2 = list(map(int, query))
        if cmd == 0:
            case.get_add(ele_1, ele_2)
        elif cmd == 1:
            res = case.get_sum(ele_1, ele_2)
            print(res)

    return case


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    n_num, q_num = list(map(int, _input[0].split()))
    q_list = [x.split() for x in _input[1:]]

    case = BinaryIndexedTree(n_num)
    ans = action(q_list)

# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 5
0 1 1
0 2 2
0 3 3
1 1 2
1 2 2

output:
3
2
"""

import sys


class BinaryIndexedTree(object):
    __slots__ = ('length', 'dat')

    def __init__(self, n):
        """
        Init a BIT with update and find for range sum queries.
        """
        self.length = int(n)
        self.dat = [0] * (self.length + 1)

    # sum(A[1] ... A[i])
    def __init_sum(self, i):
        _sum = 0
        while i > 0:
            _sum += self.dat[i]
            i -= i & (-i)
        return _sum

    def get_sum(self, s, t):
        return self.__init_sum(t) - self.__init_sum(s - 1)

    # A[i] += x
    def get_add(self, i, x):
        while i <= self.length:
            self.dat[i] += x
            i += i & (-i)
        return None


def action(cmd_list):
    case = BinaryIndexedTree(n_num)
    
    for query in cmd_list:
        cmd, ele_1, ele_2 = list(map(int, query))
        if cmd == 0:
            case.get_add(ele_1, ele_2)
        elif cmd == 1:
            res = case.get_sum(ele_1, ele_2)
            print(res)

    return case


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    n_num, q_num = list(map(int, _input[0].split()))
    q_list = [x.split() for x in _input[1:]]

    ans = action(q_list)
# Original solution
import math


class SegmentTree:
    __slots__ = ["elem_size", "tree_size", "tree"]

    def __init__(self, a: list, default: int):
        real_size = len(a)
        self.elem_size = 1 << math.ceil(math.log2(real_size))
        self.tree_size = 2 * self.elem_size + 1
        self.tree = [default] * (self.elem_size - 1) + a + [default] * (self.elem_size - real_size)

    def get_range_index(self, x, y, k=0, l_end=0, r_end=None):
        '''[x, y], tree[k], [l_end, r_end)'''
        default, tree = 0, self.tree
        if r_end is None:
            r_end = self.elem_size

        if l_end == x and y == r_end-1:
            return tree[k]

        mid = (l_end + r_end) // 2
        left_y = y if y < mid-1 else mid-1
        right_x = x if x > mid else mid

        left = self.get_range_index(x, left_y, 2*k+1, l_end, mid) if x <= left_y else default
        right = self.get_range_index(right_x, y, 2*k+2, mid, r_end) if right_x <= y else default
        return left + right

    def get_value(self, x, y):
        tree = self.tree
        return self.get_range_index(x, y)

        # return sum(tree[n] for n in index_list)

    def update_tree(self, k: int):
        tree = self.tree

        while k > 0:
            k = (k-1) // 2
            left, right = tree[2*k+1], tree[2*k+2]
            tree[k] = left + right

    def set_value(self, i: int, value: int, op: str):
        k = self.elem_size - 1 + i
        if op == "=":
            self.tree[k] = value
        elif op == "+":
            self.tree[k] += value
        self.update_tree(k)


n, q = list(map(int, input().split()))
rsq = SegmentTree([0]*n, 0)
ans = []
for _ in [0]*q:
    c, x, y = list(map(int, input().split()))
    if c == 0:
        rsq.set_value(x-1, y, "+")
    else:
        ans.append(rsq.get_value(x-1, y-1))
print(("\n".join([str(n) for n in ans])))

# Optimized solution
import sys


class BinaryIndexedTree(object):
    __slots__ = ["tree"]

    def __init__(self, size: int):
        self.tree = [0]*(size+1)

    def add(self, index: int, value: int) -> None:
        tree = self.tree
        next_index = index + 1

        while next_index < len(tree):
            tree[next_index] += value
            next_index += next_index & -next_index

    def sum(self, index: int):
        tree, result = self.tree, 0
        next_index = index + 1

        while next_index:
            result += tree[next_index]
            next_index -= next_index & -next_index

        return result


if __name__ == "__main__":
    n, q = map(int, input().split())
    bit = BinaryIndexedTree(n)
    result = []
    for com, x, y in (map(int, l.split()) for l in sys.stdin):
        if not com:
            bit.add(x-1, y)
        else:
            result.append(bit.sum(y-1) - bit.sum(x-2))

    print(*result, sep="\n")
# Original solution
import math
class FenwickTree:
    """
    FenwickTree(Binary Indexed Tree)
    total number: n
    queries:
    1. add(i, val): add val to i-th value 
    2. sum(n): sum(bit[0] + ... + bit[n-1])
    complexity: O(log n)

    Self-balancing binary search tree or Segment Tree can do the same, it takes longer to program and complexity also increases.
    Thanks: http://hos.ac/slides/20140319_bit.pdf
    
    used in ARC031 C, indeednow finalB E
    """
    def __init__(self, a_list):
        # 0-indexed
        self.N = len(a_list)
        self.bit = a_list[:]
        for _ in range(N, 1<<(math.ceil(math.log(N, 2)))): self.bit.append(0)
        for i in range(self.N-1):
            self.bit[i | (i+1)] += self.bit[i]

    def add(self, i, val):
        while i < self.N:
            self.bit[i] += val
            i |= i + 1

    def sum(self, n):
        ret = 0
        while n >= 0:
            ret += self.bit[n]
            n = (n & (n + 1)) - 1
        return ret

N, Q = list(map(int, input().split()))
bit = FenwickTree([0]*N)
for _ in range(Q):
    com, x, y = list(map(int, input().split()))
    if com == 0:
        bit.add(x-1, y)
    elif com == 1:
        print((bit.sum(y-1) - bit.sum(x-2)))

# Optimized solution
class FenwickTree:
    """FenwickTree (Binary Indexed Tree, 0-index)

    Queries:
        1. add(i, val): add val to i-th value
        2. sum(n): sum(bit[0] + ... + bit[n-1])

    complexity: O(log n)

    See: http://hos.ac/slides/20140319_bit.pdf
    """

    def __init__(self, a_list):
        self.N = len(a_list)
        self.bit = a_list[:]
        for _ in range(self.N, 1 << (self.N - 1).bit_length()):
            self.bit.append(0)
        for i in range(self.N-1):
            self.bit[i | (i+1)] += self.bit[i]

    def add(self, i, val):
        while i < self.N:
            self.bit[i] += val
            i |= i + 1

    def sum(self, n):
        ret = 0
        while n >= 0:
            ret += self.bit[n]
            n = (n & (n + 1)) - 1
        return ret

    def query(self, low, high):
        return self.sum(high) - self.sum(low)


def yosupo():
    # https://judge.yosupo.jp/problem/point_add_range_sum
    N, Q = list(map(int, input().split()))
    fwt = FenwickTree([int(x) for x in input().split()])
    for _ in range(Q):
        type_, l, r = list(map(int, input().split()))
        print([fwt.sum(i) for i in range(N+1)])
        if type_ == 0:
            fwt.add(l, r)
        else:
            print((fwt.query(l, r)))


def aoj():
    # https://onlinejudge.u-aizu.ac.jp/courses/library/3/DSL/2/DSL_2_B
    N, Q = list(map(int, input().split()))
    fwt = FenwickTree([0] * N)
    for _ in range(Q):
        type_, l, r = list(map(int, input().split()))
        if type_ == 0:
            fwt.add(l-1, r)
        else:
            print((fwt.query(l-2, r-1)))


if __name__ == "__main__":
    # yosupo()
    aoj()
# Original solution
#!/usr/bin/env python3
import sys

#count '<'
def count_S(S, N):
    ret=S.find('>')
    #print("<",S,N,ret)
    if ret==-1:
        ret=N
    return ret

#count '>'
def count_L(S, N):
    ret=S.find('<')
    if ret==-1:
        ret=N
    #print(">",S,N,ret)
    return ret

def count_L_slow(S, N):
    ret=0
    for i in range(N):
        if S[i:i+1]=='>':
            ret+=1
        else:
            break
    return ret

def solve(S: str):
    answer=0

    cnt_l=count_L(S,len(S))
    answer+=int((cnt_l+1)*cnt_l/2)
    i=cnt_l
    while i<len(S):
        cnt_s=count_S(S[i:],len(S[i:]))
        cnt_l=count_L(S[i+cnt_s:],len(S[i+cnt_s:]))
        answer+=int((cnt_s+1)*cnt_s/2)
        answer+=int((cnt_l+1)*cnt_l/2)
        if cnt_l>cnt_s:
           answer-=cnt_s
        else:
           answer-=cnt_l
        #answer+=(cnt_l+1)*cnt_l//2
        #print("cnt_s,cnt_l",cnt_s, cnt_l,answer)
        i+=cnt_s+cnt_l

    print(answer)
    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    S = next(tokens)  # type: str
    solve(S)

if __name__ == '__main__':
    main()

# Optimized solution
#!/usr/bin/env python3
import sys

#count '<'
def count_S(S, N):
    ret=S.find('>')
    #print("<",S,N,ret)
    if ret==-1:
        ret=N
    return ret

#count '>'
def count_L(S, N):
    ret=S.find('<')
    if ret==-1:
        ret=N
    #print(">",S,N,ret)
    return ret

def count_S_slow(S, ns, N):
    ret=0
    for i in range(ns,N):
        if S[i:i+1]=='<':
            ret+=1
        else:
            break
    return ret

def count_L_slow(S, ns, N):
    ret=0
    for i in range(ns,N):
        if S[i:i+1]=='>':
            ret+=1
        else:
            break
    return ret

def solve(S: str):
    answer=0
    
    numS=len(S)
    cnt_l=count_L(S,len(S))
    answer+=(cnt_l+1)*cnt_l//2
    i=cnt_l
    while i<len(S):
        cnt_s=count_S_slow(S,i,numS)
        cnt_l=count_L_slow(S,i+cnt_s,numS)
        answer+=(cnt_s+1)*cnt_s//2
        answer+=(cnt_l+1)*cnt_l//2
        if cnt_l>cnt_s:
           answer-=cnt_s
        else:
           answer-=cnt_l
        #answer+=(cnt_l+1)*cnt_l//2
        #print("cnt_s,cnt_l",cnt_s, cnt_l,answer)
        i+=cnt_s+cnt_l

    print(answer)
    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    S = next(tokens)  # type: str
    solve(S)

if __name__ == '__main__':
    main()
# Original solution
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

S = readline().rstrip().decode('utf-8')

N = len(S)+1

from_left = [0]*N
from_right = [0]*N

for i,s in enumerate(S,1):
    if s == '>':
        from_left[i] = 0
    else:
        from_left[i] = from_left[i-1]+1

for i,s in enumerate(S[::-1]):
    i = N-2-i
    if s == '<':
        from_right[i] = 0
    else:
        from_right[i] = from_right[i+1]+1

seq = [x if x>y else y for x,y in zip(from_left,from_right)]

answer = sum(seq)
print(answer)

# Optimized solution
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

S = read().rstrip().decode('utf-8')

S = S.replace('><','>,<').split(',')

answer = 0
for T in S:
    # <<<< >>>> の形
    a = T.count('<')
    b = T.count('>')
    x = a * (a-1) // 2 + b * (b-1) // 2 + max(a,b)
    answer += x

print(answer)
# Original solution
#AGC040A
import sys
s = sys.stdin.readline().rstrip()
n = len(s)
L = [0 for i in range(n+1)]
f = False
while (f==False):
    f = True
    for i in range(n):
        if s[i] =='<' and not L[i+1] >L[i]:
            L[i+1] = L[i]+1
            f = False
        elif s[i] == '>' and not L[i] > L[i+1]:
            L[i] = L[i+1] +1
            f = False
#print(*L)
print((sum(L)))


# Optimized solution
#AGC040
import sys
s = sys.stdin.readline().rstrip()
n = len(s)
L = [0 for _ in range(n+1)]

for i in range(n):
    if s[i] == '<':
        L[i+1] = L[i] +1

#print(L)

for i in range(n-1,-1,-1):
    if s[i] == '>':
        L[i] = max(L[i], L[i+1]+1)

#print(L)

print((sum(L)))
# Original solution
import itertools,sys
def S(): return sys.stdin.readline().rstrip()
S = S()
groupby_S = itertools.groupby(S)
ans = 0
rangeN = [i for i in range(len(S)+1)]
rangeN_accumulate = list(itertools.accumulate(rangeN))
group = []
temp = []
for k,g in groupby_S:
    if k=='<':
        temp.append(len(list(g)))
    else:
        temp.append(len(list(g)))
        group.append(temp)
        temp = []
group.append(temp)
for x in group:
    if len(x)==0:
        continue
    elif len(x)==1:
        ans += rangeN_accumulate[x[0]]
    else:
        a,b = max(x),min(x)-1
        ans += rangeN_accumulate[a]
        ans += rangeN_accumulate[b]
print(ans)


# Optimized solution
import sys
def S(): return sys.stdin.readline().rstrip()
S = S()
seq = [0]*(len(S)+1)
for i in range(len(S)):
    if S[i]=='<':
        seq[i+1] = seq[i]+1
for j in range(len(S))[::-1]:
    if S[j]=='>':
        seq[j] = max(seq[j],seq[j+1]+1)
print((sum(seq)))
# Original solution
import sys
def S(): return sys.stdin.readline().rstrip()
S = S()
seq = [0]*(len(S)+1)
for i in range(len(S)):
    if S[i]=='<':
        seq[i+1] = seq[i]+1
for j in range(len(S))[::-1]:
    if S[j]=='>':
        seq[j] = max(seq[j],seq[j+1]+1)
print((sum(seq)))


# Optimized solution
import sys
def S(): return sys.stdin.readline().rstrip()
S = S()
seq = [0]*(len(S)+1)
for i in range(len(S)):
    if S[i]=='<':
        seq[i+1] = seq[i]+1
for j in range(len(S)-1,-1,-1):
    if S[j]=='>':
        seq[j] = max(seq[j],seq[j+1]+1)
print((sum(seq)))