Harryxun/sft_time huggingface dataset:
### BUGGY CODE ###

from collections import deque

h, w = map(int, input().split())
maze = [list(input()) for _ in range(h)]
direction = [(1, 0), (0, 1), (-1, 0), (0, -1)]

max_step = 0
for i in range(h):
    for j in range(w):
        largest_step = 0
#        print("start: ", i, j)
        if maze[i][j] == "#":
            continue
        visited = [[False] * w for _ in range(h)]
        plan = deque()
        step = 0
        plan.appendleft((i, j, step))
        while True:
            if len(plan) == 0:
                break
            y, x, step = plan.pop()
#            print(" ", x, y, step)
            visited[y][x] = True
            if step > largest_step:
                largest_step = step
            for next_direction in direction:
                next_y = y + next_direction[0]
                next_x = x + next_direction[1]
                if next_x == -1 or next_x == w or next_y == -1 or next_y == h:
                    continue
                if maze[next_y][next_x] == "#":
                    continue
                # 訪問済みでないかチェック
                if visited[next_y][next_x]:
                    continue
                plan.appendleft((next_y, next_x, step + 1))
#        print(largest_step)
        if largest_step > max_step:
            max_step = largest_step

print(max_step)


### FIXED CODE ###

import sys
import numpy as np
from collections import deque

h, w = map(int, input().split())
maze = [list(input()) for _ in range(h)]
direction = [(1, 0), (0, 1), (-1, 0), (0, -1)]

max_step = 0
for i in range(h):
    for j in range(w):
        largest_step = 0
#        print("start: ", i, j)
        if maze[i][j] == "#":
            continue
        visited = [[False] * w for _ in range(h)]
        distance = [[-1] * w for _ in range(h)]
        plan = deque()
        step = 0
        plan.appendleft((i, j, step))
        distance[i][j] = step
        visited[i][j] = True
        while plan:
            y, x, step = plan.pop()
#            print(" ", x, y, step)
            # if step > largest_step:
            #     largest_step = step
            for next_direction in direction:
                next_y = y + next_direction[0]
                next_x = x + next_direction[1]
                if -1 == next_x or next_x == w or -1 == next_y or next_y == h or maze[next_y][next_x] == "#" or visited[next_y][next_x]:
                    continue
                distance[next_y][next_x] = distance[y][x] + 1
                visited[next_y][next_x] = True
                plan.appendleft((next_y, next_x, step + 1))
#        print(largest_step)
        # if largest_step > max_step:
        #     max_step = largest_step
        max_step = max(max_step, np.max(np.array(distance)))

print(max_step)
### BUGGY CODE ###

class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x, y):
        return - self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}


N, K, L = map(int, input().split())

road = UnionFind(N+1)
railway = UnionFind(N+1)

for _ in range(K):
    p, q = map(int, input().split())
    road.union(p, q)

for _ in range(L):
    p, q = map(int, input().split())
    railway.union(p, q)

ans = []
for i in range(1, N+1):
    ans.append(len(set(road.members(i)) & set(railway.members(i))))
print(" ".join(map(str, ans)))


### FIXED CODE ###

from collections import defaultdict

class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

N, K, L = map(int, input().split())

road = UnionFind(N)
railway = UnionFind(N)

for _ in range(K):
    p, q = map(int, input().split())
    road.union(p-1, q-1)

for _ in range(L):
    p, q = map(int, input().split())
    railway.union(p-1, q-1)

counter = defaultdict(int)
for i in range(N):
    counter[(road.find(i), railway.find(i))] += 1
ans = []
for i in range(N):
    ans.append(counter[(road.find(i), railway.find(i))])

print(*ans)
### BUGGY CODE ###

import math

Num,HP = (map(int,input().split()))
Katanas = [list(map(int,input().split())) for x in range(Num)]

amax = max([x[0] for x in Katanas])
bpower = sorted([x[1] for x in Katanas if x[1] > amax],reverse=True)
bsum = sum(bpower)
if bsum > HP:
    for x in range(len(bpower)):
        if sum(bpower[:x]) > HP:
            print(x+1)
            exit()
attake = math.ceil((HP-bsum)/amax)+len(bpower)
print(attake)

### FIXED CODE ###

import math

Num,HP = (map(int,input().split()))
#Katanas = [list(map(int,input().split())) for _ in range(Num)]

CKatanaMax = 0
katanas = []

for _ in range(Num):
    a,b = map(int,input().split())
    CKatanaMax = max(CKatanaMax,a)
    katanas.append(b)

Tkatanas = sorted([x for x in katanas if x > CKatanaMax],reverse=True)

attake = 0
for Tkatana in Tkatanas:
    HP -= Tkatana
    attake += 1
    if HP <= 0:
        break
else:
    attake += math.ceil(HP/CKatanaMax)
print(attake)
### BUGGY CODE ###

x,y,z,k=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
c=list(map(int,input().split()))

l=[]
for s in a:
    for t in b:
        l.append(s+t)
l.sort(reverse=True)
n=[]
for s in l[:k+1]:
    for t in c:
        n.append(s+t)
n.sort(reverse=True)
for i in range(k):
    print(n[i])

### FIXED CODE ###

x,y,z,k=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
c=list(map(int,input().split()))
a.sort(reverse=True)
b.sort(reverse=True)
c.sort(reverse=True)

l=[]
for s in range(x):
    for t in range(y):
        for u in range(z):
            if (s+1)*(t+1)*(u+1)<= k:
                l.append(a[s]+b[t]+c[u])
            else:
                break
l.sort(reverse=True)
for i in range(k):
    print(l[i])
### BUGGY CODE ###

from collections import deque

n = int(input())
graph = [[0 for _ in range(n)] for _ in range(n)]

for _ in range(n - 1):
    a, b, c = map(int, input().split())
    graph[a - 1][b - 1] = c
    graph[b - 1][a - 1] = c
q, k = map(int, input().split())

distance = [float('inf') for _ in range(n)]
distance[k - 1] = 0

d = deque()
d.append(k - 1)
visited = set({})
while d:
    point = d.popleft()
    for index, value in enumerate(graph[point]):
        if value > 0:
            distance[index] = min(distance[point] + graph[point][index], distance[index])
            if index not in visited:
                d.append(index)
    visited.add(point)
    
for _ in range(q):
    x, y = map(int, input().split())
    print(distance[x - 1] + distance[y - 1])

### FIXED CODE ###

from collections import deque

n = int(input())
graph = [[] for _ in range(n)]

for _ in range(n - 1):
    a, b, c = map(int, input().split())
    graph[a - 1].append((b - 1, c))
    graph[b - 1].append((a - 1, c))
q, k = map(int, input().split())

distance = [float('inf') for _ in range(n)]
distance[k - 1] = 0

d = deque()
d.append(k - 1)
visited = set({})
while d:
    point = d.popleft()
    for index, value in graph[point]:
        distance[index] = min(distance[point] + value, distance[index])
        if index not in visited:
            d.append(index)
    visited.add(point)
    
for _ in range(q):
    x, y = map(int, input().split())
    print(distance[x - 1] + distance[y - 1])
### BUGGY CODE ###

def gcd(s):
    list=[]
    for j in range(len(s)):
        a=0
        b=0
        temp=10000000000000000000
        v=[]
        if len(s)>2:
            for i in range(len(s)):
                if i!=j:
                    x=s[i]
                    v.append(x)
            for i in range(len(v)):
                if i==0:
                    a=v[i]
                    b=v[i+1]
                else:
                    b=v[i]
                if a<b:
                    temp=a
                    a=b
                    b=temp
                while b!=0:
                    temp=a%b
                    a=b
                    b=temp
            list.append(a)
        else:
            list.append(max(s))
    return(max(list))


n=int(input())

v=[]
line=input().split()

for i in range(n):
    v.append(int(line[i]))

print(gcd(v))

### FIXED CODE ###

def gcd(x,y):
    if x<y:
        x,y=y,x
    while x%y!=0:
        x,y=y,x%y
    return(y)

n=int(input())

v=[]
line=input().split()

for i in range(n):
    v.append(int(line[i]))

gcd_l=[]
gcd_r=[]

for i in range(n-1):
    if i==0:
        gcd_l.append(v[i])
    else:
        gcd_l.append(gcd(gcd_l[i-1],v[i]))

for i in range(n-1):
    if i==0:
        gcd_r.append(v[n-1])
    else:
        gcd_r.append(gcd(gcd_r[i-1],v[n-i-1]))

gcd_list=[]

for i in range(n):
    if i==0:
        gcd_list.append(gcd_r[n-2])
    elif i==n-1:
        gcd_list.append(gcd_l[n-2])
    else:
#        print(gcd(gcd_l[i-1],gcd_r[n-i-2]))
        gcd_list.append(gcd(gcd_l[i-1],gcd_r[n-i-2]))

#print(gcd_list)

print(max(gcd_list))
### BUGGY CODE ###

H,W = map(int, input().split())
S = [input() for _ in range(H)]


U = [[0 for _ in range(W)] for _ in range(H)]
D = [[0 for _ in range(W)] for _ in range(H)]
L = [[0 for _ in range(W)] for _ in range(H)]
R = [[0 for _ in range(W)] for _ in range(H)]

#L,U
for i in range(H):
    for j in range(W):
        if S[i][j] != "#":
            if j == 0:
                L[i][j] = 1
            else:
                L[i][j] = L[i][j-1] + 1
        
            if i == 0:
                U[i][j] = 1
            else:
                U[i][j] = U[i-1][j] + 1

#R,D
for i in reversed(range(H)):
    for j in reversed(range(W)):
        if S[i][j] != "#":
            if j == W-1:
                R[i][j] = 1
            else:
                R[i][j] = R[i][j+1] + 1
        
            if i == H-1:
                D[i][j] = 1
            else:
                D[i][j] = D[i+1][j] + 1

    
ans = 0
for i in range(H):
    for j in range(W):
        if S[i][j] == "#":
            continue

        tmp = L[i][j] + R[i][j] + U[i][j] + D[i][j] - 3
        ans = max(ans, tmp)

print(ans)

### FIXED CODE ###

h,w = map(int, input().split())

grid = [input() for i in range(h)]

L = [[0 for i in range(w)] for j in range(h)]
R = [[0 for i in range(w)] for j in range(h)]
D = [[0 for i in range(w)] for j in range(h)]
U = [[0 for i in range(w)] for j in range(h)]

#左上から
for i in range(h):
    for j in range(w):
        if grid[i][j] == "#":
            L[i][j] = 0
            U[i][j] = 0
        else:
            if j == 0:
                L[i][j] = 1
            else:
                L[i][j] = L[i][j-1] + 1
            
            if i == 0:
                U[i][j] = 1
            else:
                U[i][j] = U[i-1][j] + 1

#右下から
for i in reversed(range(h)):
    for j in reversed(range(w)):
        if grid[i][j] == "#":
            R[i][j] = 0
            D[i][j] = 0
        else:
            if j == w-1:
                R[i][j] = 1
            else:
                R[i][j] = R[i][j+1] + 1
                
            if i == h-1:
                D[i][j] = 1
            else:
                D[i][j] = D[i+1][j] + 1


ans = 0
for i in range(h):
    for j in range(w):
        if grid[i][j] == "#":
            continue
        tmp = L[i][j] + R[i][j] + U[i][j] + D[i][j] - 3
        ans = max(ans, tmp)

print(ans)
### BUGGY CODE ###

n = int(input())
table = [[]]
for i in range(n):
  a = list(map(int, input().split()))
  table.append(a)
cursor = [0]*(n+1)
is_matched = set()
d = 0
match = 0
while match < n * (n-1) //2:
  now_match = match
  for i in range(1, n+1):
    if cursor[i] < n-1 and i not in is_matched:
      j = table[i][cursor[i]]
      if table[j][cursor[j]] == i and j not in is_matched:
        match += 1
        cursor[i] += 1
        is_matched.add(i)
        cursor[j] += 1
        is_matched.add(j)
  if now_match == match:
    print(-1)
    exit()
  d += 1
  is_matched.clear()
print(d)

### FIXED CODE ###

n = int(input())
table = [[] for _ in range(n+1)]
for i in range(1, n+1):
  a = list(map(int, input().split()))
  table[i] = a
cursor = [0]*(n+1)
is_matched = set()
d = 0
match = 0
while match < n * (n-1) //2:
  now_match = match
  for i in range(1, n):
    if cursor[i] < n-1 and i not in is_matched:
      j = table[i][cursor[i]]
      if i < j and j not in is_matched and table[j][cursor[j]] == i :
        match += 1
        cursor[i] += 1
        is_matched.add(i)
        cursor[j] += 1
        is_matched.add(j)
  if now_match == match:
    print(-1)
    exit()
  if d > 30000:
    print(499500)
    exit()  
  d += 1
  is_matched.clear()
print(d)
### BUGGY CODE ###

import bisect
N=int(input())

cnt=0
L=[]
for i in range(N):
    n=int(input())
    L.append(n)
#print(L)
Q=[-1,10**10]
for i in range(N):
    if bisect.bisect_left(Q,L[i])==1:
        Q.insert(1,L[i])
    #elif bisect.bisect_left(Q,L[i])==len(Q)-1:
        #Q.insert(len(Q)-1,L[i])
    else:
        Q[bisect.bisect_left(Q,L[i])-1]=L[i]
    #print(Q)
print(len(Q)-2)

### FIXED CODE ###

import bisect
import sys
input=sys.stdin.readline
from collections import deque
N=int(input())

cnt=0
L=[]
for i in range(N):
    n=int(input())
    L.append(n)
#print(L)
Q=[-1,10**10]
Q=deque()
#Q.appendleft(10**10)
#print(Q)
for i in range(N):
    if bisect.bisect_left(Q,L[i])==0:
        Q.appendleft(L[i])
    #elif bisect.bisect_left(Q,L[i])==len(Q)-1:
        #Q.insert(len(Q)-1,L[i])
    else:
        Q[bisect.bisect_left(Q,L[i])-1]=L[i]
#print(Q)
print(len(Q))
### BUGGY CODE ###

n = int(input())
X = list(map(int,input().split()))
for i in range(n):
  x = X.pop(i)
  X1 = sorted(X)
  print(X1[int((len(X)+1)/2)-1])
  X.insert(i,x)

### FIXED CODE ###

n = int(input())
X = list(map(int,input().split()))
X1 = sorted(X)
for i in range(n):
  if X[i] < X1[n//2]:
    print(X1[(n//2)])
  else:
    print(X1[(n//2)-1])
### BUGGY CODE ###

from operator import itemgetter
import bisect


class DualSegmentTree():
 
    def __init__(self, n):
        self.size = 1
        while self.size < n:
            self.size *= 2
        self.node = [0] * (2*self.size - 1)
 
    def update(self, begin, end, val, k=0, l=0, r=-1):
        if 2*self.size - 1 <= k:
            return
        if r < 0:
            r = self.size
        if begin <= l and r <= end:
            self.node[k] = max(val, self.node[k])
        self.update(begin, end, val, 2*k+1, l, (l+r)//2)
        self.update(begin, end, val, 2*k+2, (l+r)//2, r)

    def get_val(self, i):
        i += (self.size - 1)
        val = self.node[i]
        while i > 0:
            i = (i - 1) // 2
            val = max(val, self.node[i])
        return val


#座標圧縮したリストを返す
def compress(list1):
    list2 = sorted(set(list1))
    memo = {value : index for index, value in enumerate(list2)}
    return list2, memo, len(list2)


n, q = map(int, input().split())
info = [list(map(int, input().split())) for i in range(n)]
info = sorted(info, key = itemgetter(2), reverse = True)
d = [int(input()) for i in range(q)]

coord_li = [info[i][0] - info[i][2] for i in range(n)] + [info[i][1] - info[i][2] for i in range(n)]
list1, compressed_memo, len_memo = compress(coord_li)

#番兵を置くために+1しておく
st = DualSegmentTree(len_memo + 1)

for i in range(n):
    a, b = info[i][0] - info[i][2], info[i][1] - info[i][2]
    st.update(compressed_memo[a], compressed_memo[b], i+1)

for i in range(q):
    num = bisect.bisect_right(list1, d[i])
    tmp = st.get_val(num-1)
    if tmp == 0:
        print(-1)
    else:
        print(info[tmp-1][2])

### FIXED CODE ###

import sys
import bisect


class DualSegmentTree():

    def __init__(self, n):
        INF = float("inf")
        self.size = 1
        while self.size < n:
            self.size *= 2
        self.node = [INF] * (2*self.size - 1)

    def update(self, begin, end, val):
        begin += (self.size - 1)
        end += (self.size - 1)
        while begin < end:
            if (end - 1) & 1:
                end -= 1
                self.node[end] = min(val, self.node[end])
            if (begin - 1) & 1:
                self.node[begin] = min(val, self.node[begin])
                begin += 1
            begin = (begin - 1) // 2
            end = (end - 1) // 2

    def get_val(self, i):
        i += (self.size - 1)
        val = self.node[i]
        while i > 0:
            i = (i - 1) // 2
            val = min(val, self.node[i])
        return val

n, q = map(int, input().split())
info = [list(map(int, sys.stdin.readline().split())) for i in range(n)]
d = [int(sys.stdin.readline()) for i in range(q)]
INF = float("inf")

st = DualSegmentTree(len(d)+1)

for i in range(n):
    a, b = info[i][0] - info[i][2], info[i][1] - info[i][2]  
    l = bisect.bisect_left(d, a)
    r = bisect.bisect_left(d, b)
    st.update(l, r, info[i][2])

for i in range(q):
    tmp = st.get_val(i)
    if tmp == float("inf"):
        print(-1)
    else:
        print(tmp)
### BUGGY CODE ###

N,M=map(int,input().split())
X=list(map(int,input().split()))
if(N>=M):
    print(0)
else:
    X.sort()
    b=[]
    for i in range(M-1):
        b.append(X[i+1]-X[i])
    for i in range(N-1):
        b.remove(max(b))
    print(sum(b))


### FIXED CODE ###

N,M=map(int,input().split())
X=list(map(int,input().split()))
if(N>=M):
    print(0)
else:
    X.sort()
    b=[]
    for i in range(M-1):
        b.append(X[i+1]-X[i])
    b.sort()
    for _ in range(N-1):
        b.pop()
    print(sum(b))
### BUGGY CODE ###

l=[1,-2]

#for i in range(2,100):
for i in range(2,50):
    l.append(l[-1]*-2)
#print(l)
n=int(input())
for i in range(1000000):
    t=(bin(i)[2:])[::-1]
    chk=0
#    print(t)
    for j,k in enumerate(t):
#        print(k)
        if k=='1':
            chk+=l[j]
        if chk==n:
            print(t[::-1])
            exit()


### FIXED CODE ###

n=int(input())
ans=""
while n!=0:
    if n%2!=0:
        n-=1
        ans="1"+ans
    else:
        ans="0"+ans
    n//=-2
print(ans if ans!="" else 0)
### BUGGY CODE ###

import collections

N = int(input())
A = input().split()

A_set = set(A)

#ボールに書かれている 数字の内訳を辞書に登録
A_dic = collections.Counter(A)

#すべてのボールから同じボールを取り出す方法数
all_count = 0

for a in A_dic.keys():
    count_a = A.count(a)
    all_count += (count_a * (count_a - 1) // 2)

#n個あるボールから 1個取り除いた場合の方法数
#すべてのボールから取り出す方法数 - (n-1)通り

for i in range(N):
    print(all_count - A_dic.get(A[i])+1)
    

### FIXED CODE ###

import collections

N = int(input())
A = input().split()

#A_set = set(A)

#ボールに書かれている 数字の内訳を辞書に登録
A_dic = collections.Counter(A)

#すべてのボールから同じボールを取り出す方法数
all_count = 0

for a in A_dic.keys():
    count_a = A_dic.get(a)
    all_count += (count_a * (count_a - 1) // 2)

#n個あるボールから 1個取り除いた場合の方法数
#すべてのボールから取り出す方法数 - (n-1)通り

for i in range(N):
    print(all_count - A_dic.get(A[i])+1)
### BUGGY CODE ###

# -*- coding: utf-8 -*-
# 整数の入力


def main():
    # a, b
    n = int(input())
    s = []
    for _ in range(n):
        s.append(input())
    print(process(n, s))


def process(n, s):
    count = 0
    for i in range(0, n):
        for k in range(i, n):
            if i == k:
                continue

            first = s[i]
            second = s[k]
            if anagram(first, second) == True:
                count += 1
    return count


# def anagram(a, b):
#     for i in a:
#         if i in b:
#             a.replace(i, '')
#         else:
#             return False
#     return True

def anagram(a, b):
    a = ''.join(sorted(a))
    b = ''.join(sorted(b))
    return a == b


if __name__ == "__main__":
    main()


### FIXED CODE ###

# -*- coding: utf-8 -*-
# 整数の入力


def main():
    # a, b
    n = int(input())
    s = []
    for _ in range(n):
        s.append(input())
    print(process(n, s))


def process(n, s):
    s = list(map(lambda s: ''.join(sorted(s)), s))
    hash = {}

    count = 0
    for i in range(0, n):
        if s[i] in hash:
            hash[s[i]] += 1
        else:
            hash[s[i]] = 1
        count += hash[s[i]] - 1
    return count


if __name__ == "__main__":
    main()
### BUGGY CODE ###

s=list(input())
n=len(s)
for i in range(len(s)//2+1):
    t=''.join(s)
    if t.count('01')>0:
        del s[t.index('01'):t.index('01')+2]
    elif t.count('10')>0:
        del s[t.index('10'):t.index('10')+2]
    else:
        break
print(n-len(s))


### FIXED CODE ###

s=list(input())
print(len(s)-(max(s.count('0'),s.count('1'))-min(s.count('0'),s.count('1'))))
### BUGGY CODE ###

import sys
sys.setrecursionlimit(10**6)

n = int(input())
a = list(map(int,input().split()))
cnt = 0
s = 0

def ers(a,cnt,s):
    if len(a) == 0:
        cnt = -1
        return cnt
    for i in range(s,len(a)):
        if i+1 != a[i]:
            a.pop(i)
            cnt+=1
            if cnt > n-1:
                cnt = -1
                return cnt
            return ers(a,cnt,s)
        else:
            s += 1
    return cnt

res = ers(a,cnt,s)

print(str(res))

### FIXED CODE ###

N = int(input())
A = list(map(int, input().split()))
cnt = 0
for i in range(N):
    if A[i] != i+1-cnt:
        cnt += 1
if cnt == N:
    print(-1)
else:
    print(cnt)
### BUGGY CODE ###

import itertools
n, k = map(int, input().split())
a = []
x = k/2
while x <= n:
    if x % 1 == 0:
        a.append(int(x))
    x += k/2
ori_list = list(itertools.product(a, repeat=3))
for i in range(len(ori_list)):
    if (ori_list[i][0] + ori_list[i][1]) % k != 0:
        ori_list[i] = 'none'
    elif (ori_list[i][1] + ori_list[i][2]) % k != 0:
        ori_list[i] = 'none'
    elif (ori_list[i][0] + ori_list[i][2]) % k != 0:
        ori_list[i] = 'none'

while 'none' in ori_list:
    ori_list.remove('none')

print(len(ori_list))

### FIXED CODE ###

n, k = map(int, input().split())
cnt = 0

if k % 2 == 1:
    for i in range(1, n+1):
        if i % k == 0:
            cnt += 1
    ans = cnt ** 3
elif k % 2 == 0:
    cnt1 = 0
    cnt2 = 0
    for i in range(1, n+1):
        if i % k == 0:
            cnt1 += 1
        elif i % k == k/2:
            cnt2 += 1
    ans = cnt1 ** 3 + cnt2 ** 3
print(ans)
### BUGGY CODE ###

from functools import reduce
n=int(input())
def sqdivlist(n):
    lista=[]
    for i in range(1,int((n**0.5)//1)+1):
        if n%i==0:
            lista.append(str(i))
    return (lista)
lista2=[]
ans=[]
for j in range(len(sqdivlist(n))):
    lista2.append(int(n/int((sqdivlist(n))[j])))
    ans.append(max(len(str(sqdivlist(n)[j])),(len(str(lista2[j])))))
print(min(ans))


### FIXED CODE ###

from functools import reduce
n=int(input())
def sqdivlist(n):
    lista=[]
    for i in range(1,int((n**0.5)//1)+1):
        if n%i==0:
            lista.append(str(i))
    return (lista)
t=len(sqdivlist(n))
u=(sqdivlist(n))
lista2=[]
ans=[]
for j in range(t):
    lista2.append(int(n/int(u[j])))
    ans.append(max(len(str(u[j])),(len(str(lista2[j])))))
print(min(ans))