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

from collections import deque
h, w = map(int, input().split())
a = [list(input()) for _ in range(h)]
moves = ((1, 0), (-1, 0), (0, 1), (0, -1))
cnt = [[float('inf') for _ in range(w)] for _ in range(h)]
ans = 0
start = []

def bfs(y, x):
  q = deque([(y, x)])
  searched = [[0 for _ in range(w)] for _ in range(h)]
  while q:
    y, x = q.popleft()
    for dy, dx in moves:
      if 0 <= y+dy < h and 0 <= x+dx < w and searched[y+dy][x+dx] == 0 and a[y+dy][x+dx] == '.' and cnt[y+dy][x+dx] > cnt[y][x]+1:
        searched[y+dy][x+dx] = 1
        q.append([y+dy, x+dx])
        cnt[y+dy][x+dx] = cnt[y][x]+1

for i in range(h):
  for j in range(w):
    if a[i][j] == '#':
      start.append([i, j])
      cnt[i][j] = 0
      
for i, j in start:
  bfs(i, j)

for i in range(h):
  for j in range(w):
    ans = max(ans, cnt[i][j])

print(ans)

### FIXED CODE ###

from collections import deque
h, w = map(int, input().split())
a = [list(input()) for _ in range(h)]
moves = ((1, 0), (-1, 0), (0, 1), (0, -1))
cnt = [[float('inf') for _ in range(w)] for _ in range(h)]
ans = 0
searched = [[0 for _ in range(w)] for _ in range(h)]
q = deque([])

def bfs():
  while q:
    y, x = q.popleft()
    for dy, dx in moves:
      next_y = y + dy
      next_x = x + dx 
      if 0 <= next_y < h and 0 <= next_x < w and searched[next_y][next_x] == 0 and a[next_y][next_x] == '.' and cnt[next_y][next_x] > cnt[y][x]+1:
        searched[next_y][next_x] = 1
        q.append([next_y, next_x])
        cnt[next_y][next_x] = cnt[y][x]+1

for i in range(h):
  for j in range(w):
    if a[i][j] == '#':
      cnt[i][j] = 0
      searched[i][j] = 1
      q.append([i, j])

bfs()
for i in range(h):
  for j in range(w):
    ans = max(ans, cnt[i][j])

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

def resolve():
    n=int(input())
    s=list(input())
    l=[]
    ans=0
    for i in range(n-2):
        for j in range(i+1,n-1):
            x=s[i]+s[j]
            if x in l:
                continue
            else:
                l.append(x)
                ans+=len(set(s[j+1:]))
    print(ans)


if __name__ == '__main__':
    resolve()

### FIXED CODE ###

N=int(input())
S=str(input())
X=[0]*1000
cnt=0
for i in range(10):
  a=S.find(str(i))
  if a==-1:
    continue
  else:
    for j in range(10):
      b=S[a+1:].find(str(j))
      if b==-1:
        continue
      else:
        for k in range(10):
          c=S[a+b+2:].find(str(k))
          if c==-1:
            continue
          else:
            cnt+=1
print(cnt)
### BUGGY CODE ###

def f(s):
  m=0
  n=0
  for i in s:
    if i==")":n-=1
    else:n+=1
    m=min(m,n)
  return [m,n]
n=int(input())
s=[input()for _ in range(n)]
mab=[]
pab=[]
for i in range(n):
  ab=f(s[i])
  if sum(ab)>0:pab.append(ab)
  else:mab.append(ab)
pab.sort(reverse=1)
mab.sort(key=lambda x:x[0]-x[1])
#print(pab)
#print(mab)
ab=pab+mab
n=0
for a,b in ab:
  if n+a<0:exit(print("No"))
  n+=b
  if n<0:exit(print("No"))
if n==0:print('Yes')
else:print('No')

### FIXED CODE ###

def f(s):
  m=0
  n=0
  for i in s:
    if i==")":n-=1
    else:n+=1
    m=min(m,n)
  return [m,n]
n=int(input())
s=[input()for _ in range(n)]
mab=[]
pab=[]
for i in range(n):
  ab=f(s[i])
  if sum(ab)>0:pab.append(ab)
  else:mab.append(ab)
pab.sort(reverse=1)
mab.sort(key=lambda x:x[0]-x[1])
#print(pab)
#print(mab)
ab=pab+mab
n=0
for a,b in ab:
  if n+a<0:exit(print("No"))
  n+=b
  if n<0:exit(print("No"))
if n==0:print('Yes')
else:print('No')
### BUGGY CODE ###


import sys
input = sys.stdin.buffer.readline
H, N = map(int, input().split())

INF = 1 << 40
dp = [INF]*(H+1)
dp[H] = 0
for i in range(N):
    a, b = map(int, input().split())
    for j in range(H, -1, -1):
        x = max(0, j-a)
        dp[x] = min(dp[x], dp[j]+b)

print(dp[0])


### FIXED CODE ###

# AtCoder Beginner Contest 153
# E - Crested Ibis vs Monster
# https://atcoder.jp/contests/abc153/tasks/abc153_e
H, N, *A = map(int, open(0).read().split())
*A, = zip(*[iter(A)]*2)

INF = 1 << 30
dp = [INF]*(H+1)
dp[0] = 0
for i, (a, b) in enumerate(A):
    for h in range(H+1):
        mh = min(H, h+a)
        dp[mh] = min(dp[mh], dp[h] + b)
print(dp[H])
### BUGGY CODE ###

s = input()
q = int(input())


inv = False
mae = []
usiro = []

for _ in range(q):
    tmp = list(input().split())
    if tmp == ['1']:
        inv = not inv

    elif tmp[1] == '1' and not inv:
        mae.insert(0,tmp[2])
    elif tmp[1] == '2' and not inv:
        usiro.append(tmp[2])
    elif tmp[1] == '1' and inv:
        usiro.append(tmp[2])
    elif tmp[1] == '2' and inv:
        mae.insert(0,tmp[2])

    # print(mae,s,usiro)

ans = ''.join(mae) + s + ''.join(usiro)

if inv:
    ans = ans[::-1]

print(ans)

### FIXED CODE ###

s = input()
q = int(input())

inv = False
mae = ''
usiro = ''

for _ in range(q):
    tmp = input()
    if tmp[0] == '1':
        inv = not inv

    else:
        _,f,c = tmp.split()

        if f == '1' and not inv:
            mae += c
        elif f == '2' and not inv:
            usiro += c
        elif f == '1' and inv:
            usiro += c
        elif f == '2' and inv:
            mae += c

    # print(mae,s,usiro)

ans = mae[::-1] + s + usiro

if inv:
    ans = ans[::-1]

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

import sys
input = sys.stdin.buffer.readline

def main():
    n = int(input())
    #ビット全探索を行う
    import itertools
    li = list(itertools.product([0, 1], repeat=n)) # ０が不親切もの、１が親切もの

    #dd[i]:人iが人xをy（０なら不親切,１なら親切)だと思っていることを収納
    from collections import deque, defaultdict
    dd = {}
    for i in range(n):
        dd[i] = deque()
    for i in range(n):
        a = int(input())
        for j in range(a):
            x, y = map(int, input().split())
            dd[i].append((x-1, y))


    from copy import deepcopy
    max_sum = 0 #親切者の数の最大値
    for i in li: # i には親切者のタプルが入っている
        ppp = 0
        for ggg in i:
            ppp += ggg
        if ppp <= max_sum:
            continue
        sum_ = 0
        flag = True
        co = deepcopy(dd)
        for k in range(len(i)): #全員の証言が矛盾しないかを考える
            if i[k] == 0: # 不親切ものの場合
                continue
            else: #以下k人目の証言を考える
                sum_ += 1
                length = len(co[k])
                while co[k]:
                    x, y = co[k].popleft()
                    if i[x] != y: #証言と一致していない場合
                        flag = False
                        break
        if flag:
            max_sum = max(max_sum, sum_)

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

### FIXED CODE ###

import sys
input = sys.stdin.buffer.readline

def main():
    n = int(input())
    #ビット全探索を行う
    import itertools
    li = list(itertools.product([0, 1], repeat=n)) # ０が不親切もの、１が親切もの

    #dd[i][x] = y:人iが人xをy（０なら不親切,１なら親切)だと思っていることを収納
    NIL = -1
    dd = [[NIL]*n for _ in range(n)]
    for i in range(n):
        a = int(input())
        for j in range(a):
            x, y = map(int, input().split())
            x = x-1
            dd[i][x] = y


    from copy import deepcopy
    max_sum = 0 #親切者の数の最大値
    for i in li: # i には親切者のタプルが入っている
        ppp = 0
        for ggg in i:
            ppp += ggg
        if ppp <= max_sum:
            continue
        sum_ = 0
        flag = True
        for k in range(len(i)): #全員の証言が矛盾しないかを考える
            if i[k] == 0: # 不親切ものの場合
                continue
            else: #以下k人目の証言を考える
                sum_ += 1
                for l in range(n):
                    if dd[k][l] != NIL and dd[k][l] != i[l]: #証言と一致していない場合
                        flag = False
                        break
        if flag:
            max_sum = max(max_sum, sum_)

    print(max_sum)
            
if __name__ == '__main__':
    main()
### BUGGY CODE ###

n = int(input())
A = list(map(int,input().split()))
answer = 1
for i in range(n):
    answer *= A[i]
if answer > pow(10,18):
    print('-1')
else:
    print(answer)

### FIXED CODE ###

n = int(input())
A = list(map(int,input().split()))
answer = 1
flag = 1
zero = 0
for i in range(n):
    answer *= A[i]
    if answer > pow(10,18):
        flag = 0
        break
if 0 in A:
    print(0)
elif flag ==0:
    print('-1')
else:
    print(answer)
### BUGGY CODE ###

import sys
import math
sys.setrecursionlimit(10**9)

def main():
    A,B,N = map(int,input().split())

    def f(x):
        return math.floor((A*x)/B) - A * math.floor(x/B)

    def bin(a):
        left = 0
        right = min(B-1,N)

        while right-left > 1:
            x = (right+left) // 2
            # print(left,right)
            if f(x) < a:
                left = x
            else:
                right = x

        # print("____")
        # print(right)
        return right


    for _a in range(A+1):
        a = A - _a
        x = bin(a)
        # print(x,a)
        if 0<=x<=N and f(x) == a:
            print(a)
            exit()


if __name__ == "__main__":
  main()


### FIXED CODE ###

import sys
import math
sys.setrecursionlimit(10**9)

def main():
    A,B,N = map(int,input().split())

    def f(x):
        return math.floor((A*x)/B) - A * math.floor(x/B)
	
    print(f(min(B-1,N)))


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

import bisect
n = int(input())
A = tuple(map(int, input().split()))
B = tuple(map(int, input().split()))
ans = 0
for i in range(30):
  t = 1<<i
  cnt = 0
  C = sorted(b%(t*2) for b in B)
  for a in A:
    a %= t*2
    cnt += bisect.bisect_left(C, 2*t-a) - bisect.bisect_left(C, t-a)
    cnt += bisect.bisect_left(C, 4*t-a) - bisect.bisect_left(C, 3*t-a)
    cnt %= 2
  ans |= cnt << i
print(ans)

### FIXED CODE ###

import numpy as np
n = int(input())
A = np.array(list(map(int, input().split())), dtype=np.int64)
B = np.array(list(map(int, input().split())), dtype=np.int64)
ans = 0
for i in range(30):
  t = 1<<i
  C = B.copy()%(2*t)
  E = A.copy()%(2*t)
  C.sort()
  E.sort()
  D = np.searchsorted(C, 2*t-E, side="left")
  D -= np.searchsorted(C, t-E, side="left")
  D += np.searchsorted(C, 4*t-E, side="left")
  D -= np.searchsorted(C, 3*t-E, side="left")
  cnt = D.sum()%2
  ans |= cnt << i
print(ans)
### BUGGY CODE ###

def trans(x1, A):
    if x1 >= A:
        return A
    else:
        return x1
      
N = int(input())
t = []

for i in range(5):
  t.append(int(input()))

 
x1 = N
x2, x3, x4, x5, x6 = 0, 0, 0, 0, 0

time = 0
while True:
    x2add = trans(x1, t[0])
    x3add = trans(x2, t[1])
    x4add = trans(x3, t[2])
    x5add = trans(x4, t[3])
    x6add = trans(x5, t[4])

    x1 -= x2add
    x2 += x2add
    
    x2 -= x3add
    x3 += x3add
    
    x3 -= x4add
    x4 += x4add
    
    x4 -= x5add
    x5 += x5add
    
    x5 -= x6add
    x6 += x6add
    
    time += 1
    if x6 == N:
        break

print(time)

### FIXED CODE ###

import math

N = int(input())
t = []

for i in range(5):
  t.append(int(input()))

print(4 + math.ceil(N/min(t)))
### BUGGY CODE ###

import sys, math

N = int(input())
low = 0
high = N - 1

print(0)
start = input()
tmp = math.ceil((high + low) / 2)
print(tmp)

while True:
    i = input()
    if i == 'Vacant':
        break
        
    else:
        if (tmp % 2 == 0 and i == start) or (tmp_seat % 2 != 0 and i != start):
            low = tmp
        else:
            high = tmp
        
        tmp = math.ceil((high + low) / 2)
        print(tmp)

sys.stdout.flush()

### FIXED CODE ###

import sys, math

N = int(input())
genders = ['Male', 'Female']
low = 0
high = N - 1

tmp_seat = low
print(tmp_seat)

start = input()

tmp_seat = math.ceil((high + low) / 2)
print(tmp_seat)

while True:
    i = input()
    if i == 'Vacant':
        break
    else:
        if (tmp_seat % 2 == 0 and i == start) or (tmp_seat % 2 != 0 and i != start):
            low = tmp_seat   
        else:
            high = tmp_seat
        
        tmp_seat = math.ceil((high + low) / 2)
        print(tmp_seat)
            
sys.stdout.flush()
### BUGGY CODE ###

n=int(input())
s='E'+input()+'W'
ans=n
for i in range(1,n+1):
  tmp=s[:i].count('W')+s[i+1:].count('E')
  ans=min(ans,tmp)
print(ans)

### FIXED CODE ###

n=int(input())
s=input()
ans=s[1:].count('E') #soppo-count
tmp=ans
for i in range(1,n):
  if s[i-1]=='W': tmp+=1
  if s[i]=='E': tmp-=1
  ans=min(ans,tmp)
print(ans)
### BUGGY CODE ###

A,B = map(int,input().split())
ans = A
for i in range(A+1,B+1):
    ans = ans^i
print(ans)

### FIXED CODE ###

def f(a):
    if a % 4 == 1:
        return 1
    elif a % 4 == 2:
        return a + 1
    elif a % 4 == 3 or a == 0:
        return 0
    else:
        return a
a, b = map(int, input().split())
print(f(b) ^ f(a - 1))
### BUGGY CODE ###

from collections import defaultdict
def main():
    def f(n):
        if n == 0:
            return 0
        if d[n] != 0:
            return d[n]
        d[n] = f(n % sum(list(map(int, bin(n)[2:])))) + 1
    def rev(i, j):
        if X[i] == '0':
            print(d[b % (c + 1)] + 1 if (b := m + j) != 0 else 0)
        else:
            print(d[b % (c - 1)] + 1 if (b := m - j) != 0 else 0)

    n = int(input())
    X = list(input())
    d = defaultdict(int)
    d[0] = 0
    for i in range(1, n):
        f(i)
    c = sum(list(map(int, X)))
    m = int(''.join(X), 2)
    j = 1 << n - 1
    for i in range(n):
        rev(i, j)
        j = j >> 1

if __name__ == '__main__':
    main()


### FIXED CODE ###

def main():
    def f(n):
        if n == 0: return 0
        return f(n % bin(n).count('1')) + 1
    n = int(input())
    X = list(input())
    c = sum(list(map(int, X)))
    m = int(''.join(X), 2)
    mp, mm = m % (c + 1), m % (c - 1) if c - 1 != 0 else 0
    jp, jm = 1, 1
    ans = [0] * n
    for i in range(n - 1, -1, -1):
        if X[i] == '0':
            mod = c + 1
            ans[i] = f((mp + jp) % mod) + 1
        else:
            ans[i] = f((mm - jm + mod) % mod) + 1 if (mod := c - 1) != 0 else 0
        jp, jm = (jp << 1) % (c + 1), (jm << 1) % (c - 1) if c - 1 != 0 else 0
    [print(a) for a in ans]
if __name__ == '__main__':
    main()
### BUGGY CODE ###


N = int(input())
myans = [ 0 for n in range(N+1)]
upper = int(N**(2/3))
#print(upper)
for x in range(1, upper):
    for y in range(1, upper):
        for z in range(1, upper):
            v = x**2 + y**2 + z**2 + x*y + y*z + z*x
            if v < N+1:
                myans[v] += 1
#print(myans)
for a,b in enumerate(myans):
    if a != 0:
        print(b)


### FIXED CODE ###


N = int(input())
myans = [ 0 for n in range(N+1)]
upper = int(N**(2/3))
#print(upper)
for x in range(1, 105):
    for y in range(1, 105):
        for z in range(1, 105):
            v = x**2 + y**2 + z**2 + x*y + y*z + z*x
            if v < N+1:
                myans[v] += 1
#print(myans)
for a,b in enumerate(myans):
    if a != 0:
        print(b)
### BUGGY CODE ###

n = int(input())
l = [int(input()) for _ in range(n)]
ans = [x for x in set(l) if l.count(x) % 2 == 1]
print(len(ans))

### FIXED CODE ###

n = int(input())
l = {}
ans = 0
for _ in range(n):
    a = int(input())
    if a in l:
        l[a] += 1
    else:
        l[a] = 1
for v in l.values():
    if v % 2 == 1:
        ans += 1
print(ans)
### BUGGY CODE ###

n = int(input())
S = []
cnt = 0
for i in range(n):
    tmp = "".join(sorted(input()))
    cnt += S.count(tmp)
    S.append(tmp)

print(cnt)

### FIXED CODE ###

import collections
n = int(input())
s = collections.Counter(["".join(sorted(input())) for _ in range(n)]).most_common()
#print(s)
cnt = 0
for i in s:
    for j in range(1, i[1]):
        cnt += j
print(cnt)
### BUGGY CODE ###

def cul(lst, m):
    r = 0
    for i in lst:
        r  += i if i < m else m
    return r

n, k = map(int,input().split())
s = input()
val = []

a = 1
for i in range(1, len(s)):
    if s[i-1] == s[i]:
        a += 1
    else:
        val.append(a)
        a = 1
val.append(a)
ans = []
now = int(s[0])
for i in range(len(s)-k):
    ins = 0
    lst = val[i:i+k*2] if now == 0 else val[i:i+k*2+1]
    ans.append(cul(lst, n))
    now = 1 if now == 0 else 0

print(max(ans) if not len(ans) == 0 else len(s))

### FIXED CODE ###

n, k = map(int,input().split())
s = input()
nums = []

now = 1
cnt = 0
for i in range(len(s)):
    if s[i] == str(now): cnt += 1
    else:
        nums.append(cnt)
        now = 1 - now
        cnt = 1
if not cnt == 0: nums.append(cnt)
if len(nums) % 2 == 0: nums.append(0)

summ = [0]
for i in range(len(nums)):
    summ.append(summ[i]+nums[i])

ans = 0
for i in range(len(nums))[::2]:
    left = i
    right = min(i+k*2+1, len(nums))
    tmp = summ[right] - summ[left]

    ans = max(tmp, ans)


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

import math, string, itertools, fractions, heapq, collections, re,  array, bisect, sys, random, time, copy, functools
sys.setrecursionlimit(10**7)
inf = 10 ** 20
eps = 1.0 / 10**10
mod = 10**9+7
dd = [(-1, 0), (0, 1), (1, 0), (0, -1)]
ddn = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def _I(): return int(sys.stdin.readline())
def _F(): return float(sys.stdin.readline())
def _pf(s): return print(s, flush=True)

#  f = open('C_input_29.txt')
#  lines = f.readlines()
#  f.close()
#  N, M = map(int, lines[0].split())
#  A = []
#  for line in lines[1:]:
#      A.append(int(line))

N, M = LI()
A = []
for i in range(M):
    A.append(_I())

#  if M != 0:
#      # 連続した壊れた段がある場合は0
#      B = [i for i in A]
#      B.remove(B[0])
#      B.append(10**15+100)
#      diffs = [b - a for a, b in zip(A,B)]
#      #  print(diffs)

#      if any(i == 1 for i in diffs):
#          # 隣同士なので0
#          print(0)
#          exit()
#  print('hoge')
"""
考え方
xにたどり着く通りは、x-1とx-2段目にたどり着く通りの合計
dp
3が障害のとき
1へは1通り
2へは0からと1からの2通り
3へは0通り
4へは2からの2通りと、3からの0通りで2通り
5へは3からの0通りと4からの2通りで2通り
6へは4からの2通りと5からの2通りで4通り
"""
#  dp = {}
dp = [0 for i in range(N+1)]
#  print('fua')
dp[0] = 1
dp[1] = 1 if 1 not in A else 0
#  [dp.update({i: (dp[i-1] + dp[i-2])%mod}) if i not in A else dp.update({i: 0}) for i in range(2, N+1)]
for i in range(2, N+1):
    #  print(i)
    # i段目までの通りを計算する
    if i not in A:
        # i段目が障害のときは0になっているので飛ばす
        dp[i] = dp[i-1] + dp[i-2]
        dp[i] %= mod

print(dp[N])


### FIXED CODE ###

# -*- coding: utf-8 -*-
import sys

mod = 10 ** 9 + 7

def get_nums(n):
    res = [0 for _ in range(n)]
    for i in range(n):
        res[i] = int(input())
    return res


def get_numbers():
    return map(int, input().split())


n, m = get_numbers()
a = set(get_nums(m))

dp = [0 for _ in range(n + 1)]
dp[0] = 1
if 1 not in a:
    dp[1] = 1

for i in range(2, n + 1):
    if i not in a:
        dp[i] = dp[i - 1] + dp[i - 2]
        dp[i] %= mod

print(dp[-1])
### BUGGY CODE ###

N = int(input())
A = list(map(int,input().split()))
MOD = 10**9 +7

S = 0
for i in range(len(A)-1):
    for j in range(i+1,len(A)):
        S = (S + A[i]*A[j]%MOD)%MOD

print(S)


### FIXED CODE ###

def main():
    N = int(input())
    A = list(map(int,input().split()))
    MOD = 10**9 +7

    S = 0
    for i in range(len(A)-1):
        tmp = 0
        for j in range(i+1,len(A)):
            tmp+=A[j]
        S+= (tmp%MOD * A[i])%MOD


    print(S%MOD)



from itertools import accumulate

m = 10**9 + 7

N,*A = map(int,open(0).read().split())

result = 0

b = [0]*N
b[0] = A[0]
for i in range(1,N):
    b[i]= b[i-1] + A[i]




for i in range (N-1):
    result += A[i]*(b[N-1]-b[i])
    result %= m
print(result)
### BUGGY CODE ###

# N問出題, M回提出
N, M = map(int, input().split())

p_S_list = []

WA = 'WA'
AC = 'AC'

first_AC_index_list = []
AC_set = set([])

for j in range(M):
    p, S = input().split()
    int_p = int(p)
    p_S_list.append([int_p, S])

    if S == AC and (int_p not in AC_set):
        first_AC_index_list.append([j, int_p])
    
    if S == AC:
        AC_set.add(int_p)

count_AC = len(first_AC_index_list)
count_WA = 0


for i_list in first_AC_index_list:
    count_WA += p_S_list[:i_list[0]].count([i_list[1], WA])

ans = str(count_AC) + ' ' + str(count_WA)

print(ans)

### FIXED CODE ###

# N問出題, M回提出
N, M = map(int, input().split())

p_S_list = []

WA = 'WA'
AC = 'AC'

question_list = [False] * N
WA_count_list = [0] * N

count_AC = 0
count_WA = 0

for i in range(M):
    p, S = input().split()
    int_p = int(p)
    
    if S == WA and question_list[int_p - 1] == False:
        WA_count_list[int_p - 1] += 1

    if S == AC and question_list[int_p - 1] == False:
        count_AC += 1
        count_WA += WA_count_list[int_p - 1]
        question_list[int_p - 1] = True

print(str(count_AC) + ' ' + str(count_WA))








'''
first_AC_index_list = []
AC_set = set([])

for j in range(M):
    p, S = input().split()
    int_p = int(p)
    p_S_list.append([int_p, S])

    if S == AC and (int_p not in AC_set):
        first_AC_index_list.append([j, int_p])
        AC_set.add(int_p)

count_AC = len(first_AC_index_list)
count_WA = 0
# for i in range(1, N + 1):
#     # i問目の問題について考える
#     if [i, AC] in p_S_list:
#         count_AC += 1

#         first_AC_index = p_S_list.index([i, AC])

#         count_WA += p_S_list[:first_AC_index].count([i, WA])

for i_list in first_AC_index_list:
    count_WA += p_S_list[:i_list[0]].count([i_list[1], WA])

ans = str(count_AC) + ' ' + str(count_WA)

print(ans)

'''
### BUGGY CODE ###

from collections import deque
import sys
input = sys.stdin.readline

h,w=map(int, input().split())
a = [input() for i in range(h)]
visited = [[-1]*w for i in range(h)]
black = []
for i,row in enumerate(a):
    for j,c in enumerate(row):
        if c == '#':
            black.append((i,j))
            visited[i][j] = 0

queue = deque(black)

while queue:
    y,x = queue.popleft()
    dydx = [[1,0],[-1,0],[0,1],[0,-1]]
    for j,k in dydx:
        newy,newx = y+j,x+k 
        if newy < 0 or newy >= h:continue 
        if newx < 0 or newx >= w:continue 
        if visited[newy][newx] == -1:
            visited[newy][newx] = visited[y][x] + 1
            queue.append((newy,newx))

ans = 0
for row in visited:
    for j in row:
        ans = max(ans,j)

print(ans)

### FIXED CODE ###

from collections import deque

h,w=map(int, input().split())
a = [input() for i in range(h)]
visited = [[-1]*w for i in range(h)]
black = []
for i in range(h):
    for j in range(w):
        if a[i][j] == '#':
            black.append((i,j))
            visited[i][j] = 0

queue = deque(black)


while queue:
    y,x = queue.popleft()
    dydx = [[1,0],[-1,0],[0,1],[0,-1]]
    for j,k in dydx:
        newy,newx = y+j,x+k 
        if newy < 0 or newy >= h:continue 
        if newx < 0 or newx >= w:continue 
        if visited[newy][newx] == -1:
            visited[newy][newx] = visited[y][x] + 1
            queue.append((newy,newx))

ans = 0
for i in range(h):
    for j in range(w):
        ans = max(ans,visited[i][j])

print(ans)