Harryxun/stf_run huggingface dataset:
N,M = map(int,input().split(" "))

first = []
second = []
flag = 0
end = True

for i in range(M):
  a,b = map(int,input().split(" "))
  if b == N:
    second.append(a)
  if a == 1:
    first.append(b)
    
if len(first) == 0 or len(second) == 0:
  print("IMPOSSIBLE")
else:
  firsti = 0
  secondi = 0
  while(end == True):
    if first[firsti] == second[secondi]:
      print("POSSIBLE")
      break
    elif first[firsti] < second[secondi]:
      firsti += 1
      if firsti > len(first) - 1:
        print("IMPOSSIBLE")
        break
    else:
      second += 1
      if secondi > len(second) - 1:
        print("IMPOSSIBLE")
        break
    

### FIXED CODE ###

N,M = map(int,input().split(" "))

first = []
second = []
flag = 0
end = True

for i in range(M):
  a,b = map(int,input().split(" "))
  if b == N:
    second.append(a)
  if a == 1:
    first.append(b)

first.sort()
second.sort()
    
if len(first) == 0 or len(second) == 0:
  print("IMPOSSIBLE")
else:
  firsti = 0
  secondi = 0
  while(end == True):
    if first[firsti] == second[secondi]:
      print("POSSIBLE")
      break
    elif first[firsti] < second[secondi]:
      firsti += 1
      if firsti > len(first) - 1:
        print("IMPOSSIBLE")
        break
    else:
      secondi += 1
      if secondi > len(second) - 1:
        print("IMPOSSIBLE")
        break
import math
mod =1000000000+7

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

def convcal(a,b):
  kekka = (math.factorial(a) //math.factorial(a-b)  ) // math.factorial(b) 
  return kekka

for i in range(1,k+1):
  #print(i)
  #print(k-1,i-1)
  #print(n-k-1,i)
  print(convcal(k-1,i-1)*convcal(n-k+1,i) % mod)


### FIXED CODE ###

import math
mod =1000000000+7

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

def convcal(a,b):
  kekka = (math.factorial(a) //math.factorial(a-b)  ) // math.factorial(b) 
  return kekka

for i in range(1,k+1):
  #print(i)
  #print(k-1,i-1)
  #print(n-k+1,i)
  if n-k+1-i>=0:
    print(convcal(k-1,i-1)% mod * convcal(n-k+1,i) % mod)
  else:
    print(0)
K,X = 2 900

def solve(K,X):
  if K * 500 >= X:
    print('Yes')
  else:
    print('No')

### FIXED CODE ###

K,X = input().split()

def main(K,X):
  K = int(K)
  X = int(X)
  if K * 500 >= X:
    print('Yes')
  else:
    print('No')
 
if __name__ == '__main__':
  main(K,X)
a = int(input())
b = int(input())
if ( a * b ) % 2 == 0:
    print("Even")
else:
    print("Odd")


### FIXED CODE ###

a, b = (int(x) for x in input().split())
if a*b%2 == 0:
    print('Even')
else:
    print('Odd')
N = int(input())
right_A = 0
left_B = 0
B_to_A = 0
AB_count = 0

for _ in range(N):
    target = input()
    AB_count += target.count('AB')
    if target[0] == 'B' and target[-1] == 'A':
        B_to_A += 1
    elif target[0] == 'B':
        left_B += 1
    elif target[-1] == 'A':
        right_A += 1

def recursive(x, y, z):
    if z == 0:
        return min(x, y)
    elif x == y == 0:
        return z - 1
    else:
        return recursive(x, y, z-1) + 1

print(recursive(right_A, left_B, B_to_A) + AB_count)


### FIXED CODE ###

import sys
sys.setrecursionlimit(10 ** 5)

N = int(input())
right_A = 0
left_B = 0
B_to_A = 0
AB_count = 0

for _ in range(N):
    target = input()
    AB_count += target.count('AB')
    if target[0] == 'B' and target[-1] == 'A':
        B_to_A += 1
    elif target[0] == 'B':
        left_B += 1
    elif target[-1] == 'A':
        right_A += 1

def recursive(x, y, z):
    if z == 0:
        return min(x, y)
    elif x == y == 0:
        return z - 1
    else:
        return recursive(x, y, z-1) + 1

print(recursive(right_A, left_B, B_to_A) + AB_count)
s = input()
t = input()
if (s == t[0:len(s)] && len(s) + 1 == len(t)):
  print('Yes')
else:
  print('No')

### FIXED CODE ###

s = input()
t = input()
if (s == t[0:len(s)] and len(s) + 1 == len(t)):
  print('Yes')
else:
  print('No')
c, r = map(int, input().split())
last_list = [0] * r
for _ in range(c):
    n = 0
    x = input()
    sum_list = list(map(int, x.split()))
    for i in range(r):
        last_list[i] += sum_list[i]
        n += sum_list[i]
    print(x, n)
sum = 0   
for a in last_list:
    sum += a
print(*last_list, sum)

### FIXED CODE ###

r, c = map(int, input().split())
last_list = [0] * (c + 1)
for _ in range(r):
    n = 0
    x = input()
    sum_list = list(map(int, x.split()))
    for i in range(c):
        last_list[i] += sum_list[i]
        n += sum_list[i]
    print(x, n)

last_list[-1] = sum(last_list)
print(*last_list)
print(input().conut('1'))

### FIXED CODE ###

print(input().count('1'))
import numpy as np
n = int(input())
A = list(map(int, input().split()))

lcm = np.lcm.reduce(A)
ans = ((lcm - 1) % A).sum()
print(ans)


### FIXED CODE ###

import numpy as np
n = int(input())
A = np.array(list(map(int, input().split())))

ans = (A-1).sum()
print(ans)
N = int(input())
S, T = input().split()
print(*s+t for s,t in zip(S,T), sep='')

### FIXED CODE ###

N = int(input())
S, T = input().split()
list = []
for i in range(0,N):
    list.append(S[i])
    list.append(T[i])
print(*list, sep='')
N  = (int(i) for i in input().split())
A = list(int(i) for i in range(input().split(),N))

print(max(A) -  min(A))

### FIXED CODE ###

N = int(input())
A = list(map(int, input().split()))

print(max(A) -  min(A))
a,b = map(int, input().split())
i = 0
while i<a:
  turu = 2*(a-i)
  kame = 4*i
  
  amari = b % turu
  if amari == 0:
    print('YES')
    break

  if kame !=0:
    if amari % kame == 0:
      print('YES')
      break
      
  i = i + 1
  
else:
  print('No)
      
      

### FIXED CODE ###

a,b = map(int, input().split())
i = 0
while i<=a:
  turu = 2*(a-i)
  kame = 4*i
  ans = turu + kame
  if ans == b:
    print('Yes')
    break
  i = i + 1
  
else:
  print('No')
import numpy as np  

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

dp = np.array([0] * w+1)

for _ in range(n):
    weight, value = map(int, input().split())

    dp[weight:] = np.maximum(dp[weight:], dp[:-weight] + value) 

print(int(dp[-1]))

### FIXED CODE ###

import sys
import numpy as np
import itertools
import heapq
import bisect
import math
import queue
from operator import itemgetter #sortedの対象を決めたい
from fractions import gcd #最大公約数
from copy import deepcopy #参照で影響されないコピー
from collections import Counter, deque, defaultdict #要素ごとの出現回数、双方向アクセス可能データ型
from functools import reduce
mod = 1000000007
inf = 10**10
sys.setrecursionlimit(1000000)

input = sys.stdin.readline

def sieve_of_eratosthenes(n):
    if not isinstance(n,int):
        raise TypeError("n is not int")
    if n<2:
        raise ValueError("n is not effective")
    prime = [1]*(n+1)
    for i in range(2,int(math.sqrt(n))+1):
        if prime[i] == 1:
            for j in range(2*i,n+1):
                if j%i == 0:
                    prime[j] = 0
    res = []
    for i in range(2,n+1):
        if prime[i] == 1:
            res.append(i)
    return res
 
def factorial(i):
    if i == 1:
        return 1
    else:
        return i*factorial(i-1)
 
class UnionFind:
    def __init__(self,n):
        self.parent = [i for i in range(n+1)]
        self.rank = [0 for i in range(n+1)]
    
    def findroot(self,x):
        if x == self.parent[x]:
            return x
        else:
            y = self.parent[x]
            y = self.findroot(self.parent[x])
            return y
    
    def union(self,x,y):
        px = self.findroot(x)
        py = self.findroot(y)
        if px < py:
            self.parent[py] = px
        else:
            self.parent[px] = py
 
    def same_group_or_no(self,x,y):
        return self.findroot(x) == self.findroot(y)
# template


def main():
    n, w = map(int, input().split())
    wv = [list(map(int, input().split())) for _ in range(n)]

    dp = np.zeros([n+1, w+1])
    
    for i, itm in enumerate(wv):
        dp[i+1, :itm[0]] = dp[i, :itm[0]]
        dp[i+1, itm[0]:] = np.max([dp[i, itm[0]:], dp[i, :w-itm[0]+1] + itm[1]], axis=0)

    print(int(dp[n, w]))


if __name__ == "__main__":
    main()
a,b=int(input().split())
print(max([a+b,a-b,a*b]))

### FIXED CODE ###

a,b=map(int,input().split())
print(max([a+b,a-b,a*b]))
from collections import deque
n,m,k=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
a_stack=deque([])
now=0
mn=0
j=0
for i in a:
  mn+=i
  if mn>k:
    mn-=i
    break
  else:
    now+=1
    a_stack.append(i)
for i in b:
  mn+=i
  if mn>k:
    mn-=i
    break
  else:
    now+=1
    j+=1
ans=now
while a_stack:
  if j>=m:
    break
  else:
    q=a_stack.pop()
    mn-=q
    now-=1
    while k-mn>0:
      mn+=b[j]
      now+=1
      j+=1
      if k-mn<0:
        now-=1
        mn-=b[j]
        j-=1
        break
      if j==m:
        break
    ans=max(now,ans)
print(ans)

### FIXED CODE ###

from collections import deque
n,m,k=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
a_stack=deque([])
now=0
mn=0
j=0
for i in a:
  mn+=i
  if mn>k:
    mn-=i
    break
  else:
    now+=1
    a_stack.append(i)
for i in b:
  mn+=i
  if mn>k:
    mn-=i
    break
  else:
    now+=1
    j+=1
    if j==m:
      print(now)
      exit()
ans=now
while a_stack:
  if j>=m:
    break
  else:
    q=a_stack.pop()
    mn-=q
    now-=1
    while k-mn>0:
      mn+=b[j]
      now+=1
      if k-mn<0:
        now-=1
        mn-=b[j]
        break
      j+=1
      if j==m:
        break
    ans=max(now,ans)
print(ans)
from collections import Counter
a = input()
b = Counter(a)
c = 0

for i in b.values:
  if i%2!=0:
    c = 1
else:
  if c==0:
    print("Yes")
  else:
    print("No")

### FIXED CODE ###

from collections import Counter
a = input()
b = Counter(a)
c = 0

for i in b.values():
  if i%2!=0:
    c = 1
else:
  if c==0:
    print("Yes")
  else:
    print("No")
x, y = [int(n) for n in input().split()]
if (x < y):
    x, y = y, x
while b > 0:
    x, y = x, x % y
print(x)



### FIXED CODE ###

x, y = [int(n) for n in input().split()]
if (x < y):
    x, y = y, x
while y:
    (x, y) = (y, x % y)
print(x)
N = int(input())
A = list(map(int,input().split()))
A.sort()

count = N

for i in range(N):
  if i == 0:
    if A[i] == A[i+1]:
      count -= 1
  else:
    for j in range(1,i+1):
      if A[i]%A[i-j] == 0:
        count -= 1
        print(A[i])
        break
print(count)

### FIXED CODE ###

import numpy as np
N = int(input())
A = list(map(int,input().split())) + [10**6+1]
A.sort()
B = np.zeros(10**6+1)
count = 0
for i in range(N):
  if B[A[i]] == 0:
    B[::A[i]] = 1
    if A[i] != A[i+1]:
      count += 1
print(count)
N, S = map(int, input().split())
A = list(map(int, input().split()))

MOD = 998244353

dp = [0] * (S + 1)
dp[0] = 1

for i in range(N):
    ai = A[i]
    for j in range(S, -1, -1):
        dp[j] = (2 * dp[j] + (j - ai >= 0) * dp[j - ai]) % MOD
 
print(dp[S])


### FIXED CODE ###

N, S = map(int, input().split())
A = list(map(int, input().split()))

MOD = 998244353

dp = [[0] * (S + 1) for _ in range(N + 1)]
dp[0][0] = 1

for i in range(N):
    ai = A[i]
    for j in range(S + 1):
        here = dp[i][j]
        # aiがTに含まれない
        dp[i + 1][j] += here
        # aiがTに含まれるが, Uに含まれない
        dp[i + 1][j] += here

        dp[i + 1][j] %= MOD

        # aiがUに含まれる
        if j + ai <= S:
            dp[i + 1][j + ai] += dp[i][j]
            dp[i + 1][j + ai] %= MOD

print(dp[N][S])
n=input()
x=0
for i in n:
  x+=i
if int(n)%x==0:
  print('Yes')
else:
  print('No')

### FIXED CODE ###

n=int(input())
m=str(n)
x=0
for i in m:
  x+=int(i)
if n%x==0:
  print('Yes')
else:
  print('No')
n = int(input())
t, a = map(int, input().split(" "))


nums = map(int, input().split(" "))

xxx = map(lambda x: abs(a-t-0.006*x), nums)

m = min(xxx)

for i, v in xxx.enumerete:
    if m == v:
        print(i)


### FIXED CODE ###

n = int(input())
t, a = map(int, input().split())
hs = list(map(int, input().split()))

min = 99999
ans = 99999

for i in range(n):
    tmp = t - hs[i] * 0.006
    d = abs(a-tmp)
    if d < min:
        ans = i
        min = d

print(ans+1)
S = list(input())

res_10 = 0
res_01 = 0

for i in range(N):
    if i % 2 == 0:
        if S[i] == "0":
            res_10 += 1
        else:
            res_01 += 1
    else:
        if S[i] == "1":
            res_10 += 1
        else:
            res_01 += 1
print(min(res_10, res_01))

### FIXED CODE ###

S = list(input())
 
res_10 = 0
res_01 = 0
 
for i in range(len(S)):
    if i % 2 == 0:
        if S[i] == "0":
            res_10 += 1
        else:
            res_01 += 1
    else:
        if S[i] == "1":
            res_10 += 1
        else:
            res_01 += 1
print(min(res_10, res_01))
import sys
# input = sys.stdin.readline
inf = 10 ** 18

N, M = map(int, input().split())
XYZ = [list(map(int, input().split())) for _ in range(M)]

grp = [0] * N
moushiokuri = []
idx = 1
for i, (Xi, Yi, Zi) in enumerate(XYZ):
    if grp[Xi - 1] == grp[Yi - 1] == 0:
        grp[Xi - 1] = grp[Yi - 1] = idx
        idx += 1
    elif grp[Xi - 1] == 0:
        grp[Xi - 1] = grp[Yi - i]
    elif grp[Yi - 1] == 0:
        grp[Yi - 1] = grp[Xi - 1]
    else:
        moushiokuri.append((grp[Xi - 1], grp[Yi - 1]))

for src, dst in moushiokuri:
    for i, grpi in enumerate(grp):
        if grpi == src:
            grp[i] = dst

# print("#", grp)

ans = len(set(grp))
if 0 in grp:
    ans -= 1
    ans += grp.count(0)

print(ans)

### FIXED CODE ###

import sys
# input = sys.stdin.readline
inf = 10 ** 18

N, M = map(int, input().split())
XYZ = [list(map(int, input().split())) for _ in range(M)]

# https://qiita.com/maron8676/items/6010128f4ef5c268f719
class UFnode(object):
    def __init__(self, group_id, parent=None, value=None):
        self.group_id_ = group_id
        self.parent_ = parent
        self.value = value
        self.rank_ = 1

    def is_root(self):
        return not self.parent_

    def root(self):
        parent = self
        while not parent.is_root():
            parent = parent.parent_
            self.parent_ = parent
        return parent

    def find(self):
        root = self.root()
        return root.group_id_

    def rank(self):
        root = self.root()
        return root.rank_

    def unite(self, unite_node):
        root = self.root()
        unite_root = unite_node.root()
        if root.group_id_ != unite_root.group_id_:
            if root.rank() > unite_root.rank():
                unite_root.parent_ = root
                root.rank_ = max(root.rank_, unite_root.rank_ + 1)
            else:
                root.parent_ = unite_root
                unite_root.rank_ = max(root.rank_ + 1, unite_root.rank_)

nodes = [UFnode(i) for i in range(N)]

for i, (Xi, Yi, Zi) in enumerate(XYZ):
    nodes[Xi - 1].unite(nodes[Yi - 1])

print(len(set([nodes[i].find() for i in range(N)])))
import math

def make_primes(limit):
    n = 0
    primes = []
    for k in range(2, math.floor(math.sqrt(limit))+1):
        factor = 0

        # 2以外の偶数は素数ではないので無視する
        if k % 2 == 0 and k != 2:
            continue

        # 繰り返しの上限を対象の平方根にする
        for divisor in range(2, math.floor(math.sqrt(k))+1):
            if k % divisor == 0:
                factor += 1

        if factor == 0:
            primes.append(k)
            primes.append(limit // k)

    primes.append(limit)
    return sorted(primes)


def main():
    n = int(input())
    original_n = n

    factors = []
    primes = make_primes(n)

    i = 0
    while True:
        if n == 1:
            break

        if n % primes[i] == 0:
            n //= primes[i]
            factors.append(primes[i])
        else:
            i += 1


    print("{}: {}".format(
        original_n,
        " ".join(list(map(str, factors)))
    ))



main()



### FIXED CODE ###

import math

def make_divisors(n):
    divisors = []
    for k in range(2, math.floor(math.sqrt(n))+1):
        if n % k == 0:
            divisors.append(k)
            divisors.append(n // k)

    divisors.append(n)

    return sorted(divisors)

def main():
    n = int(input())
    original_n = n

    factors = []
    divisors = make_divisors(n)

    i = 0
    while True:
        if n == 1:
            break

        if n % divisors[i] == 0:
            n //= divisors[i]
            factors.append(divisors[i])
        else:
            i += 1

    print("{}: {}".format(
        original_n,
        " ".join(list(map(str, factors)))
    ))

main()
def func(c):
    x = c.count("1")
    if x == 0:
        return 0
    n = 1
    nsum = 0
    for i in reversed(range(len(c))):
        nsum += n * int(c[i])
        if n > x:
            n = n % x
        if n == 0:
            break
        n *= 2
    nsum %= x
    cans = bin(nsum)
    nsum = cans.count("1")
    if nsum == 0:
        return 1
    else:
        return 1 + func(cans[2:])

for i in range(a):
    s = list(b)
    s[i] = "0" if s[i] == "1" else "1"
    print(str(func("".join(s))))

### FIXED CODE ###

from functools import lru_cache


a = int(input())
b = input()
X = b.count("1")
ans1 = []
ans2 = []

@lru_cache(maxsize=None)
def func1(c):
    x = X + 1
    n = 1
    nsum = 0
    for i in reversed(range(len(c))):
        ans1.append(n)
        nsum += n * int(c[i])
        n = n % x if n > x else n
        n *= 2
    return nsum
    
@lru_cache(maxsize=None)
def func2(c):
    x = X - 1
    if x == 0:
        return 0
    n = 1
    nsum = 0
    for i in reversed(range(len(c))):
        ans2.append(n)
        nsum += n * int(c[i])
        n = n % x if n > x else n
        n *= 2
    return nsum    

def func(c):
    x = c.count("1")
    if x == 0:
        return 0
    n = 1
    nsum = 0
    for i in reversed(range(len(c))):
        nsum += n * int(c[i])
        n = n % x if n > x else n
        if n == 0:
            break
        n *= 2
    nsum %= x
    cans = bin(nsum).count("1")
    if cans == 0:
        return 1
    else:
        return 1 + func(bin(nsum)[2:])
    
allans1 = func1(b)
allans2 = func2(b)
ans1 = ans1[::-1]
if allans2 == 0:
    ans2 = [0] * a
else:
    ans2 = ans2[::-1]

c = list(b)
for i in range(a):
    if c[i] == "0":
        ans = (allans1 + ans1[i]) % (X + 1)
        ans = func(bin(ans)[2:]) + 1
        print(str(ans))
    else:
        if allans2 - ans2[i] == 0 and X - 1 == 0:
            print("0")
        else:
            ans = (allans2 - ans2[i]) % (X - 1)
            ans = func(bin(ans)[2:]) + 1
            print(str(ans))
import bisect, collections, copy, heapq, itertools, math, string
import sys
def I(): return int(sys.stdin.readline().rstrip())
def MI(): return map(int, sys.stdin.readline().rstrip().split())
def LI(): return list(map(int, sys.stdin.readline().rstrip().split()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())

def main():
    S_ = S()
    T = S()
    a = len(S_)
    b = len(T)
    cnt_list = []
    
    if a == b:
        cnt = 0
        for i in range(b):
            if S_[i] == T[i]:
                cnt += 1

    else:    
        for i in range(a - b):
            cnt = 0
            S_1 = S_[i:i + b + 1]
            for i in range(b):
                if S_1[i] == T[i]:
                    cnt += 1
            cnt_list.append(cnt)

    ans = b - max(cnt_list)
    print(ans)



if __name__ == "__main__":
    main()



### FIXED CODE ###

import bisect, collections, copy, heapq, itertools, math, string
import sys
def I(): return int(sys.stdin.readline().rstrip())
def MI(): return map(int, sys.stdin.readline().rstrip().split())
def LI(): return list(map(int, sys.stdin.readline().rstrip().split()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())

def main():
    S_ = S()
    T = S()
    a = len(S_)
    b = len(T)
    cnt_list = []

    for i in range(a - b + 1):
        cnt = 0
        S_1 = S_[i:i + b]
        for j in range(b):
            if S_1[j] == T[j]:
                cnt += 1
        cnt_list.append(cnt)

    ans = b - max(cnt_list)
    print(ans)



if __name__ == "__main__":
    main()
import copy
N = int(input())
X = list(map(int,input().split()))
length = len(X)
sortx = sorted(X)
bef = sortx[int(length//2)]
aft = sortx[int(length//2)+1]

for i in range(N):
    if(X[i]<=bef):
        print(bef)
    else:
        print(aft)

### FIXED CODE ###

N = int(input())
X = list(map(int,input().split()))

sortx = sorted(X)
bef = sortx[N//2-1]
aft = sortx[N//2]
for i in X:
        print(aft if i <= bef else bef)
a,b=map(int,input().split())
    print('Possible' if ((a+b)%3==0) or (a%3==0) or(b%3==0) else 'Impossible')

### FIXED CODE ###

a,b=map(int,input().split())
print('Possible' if (((a+b)%3==0)or(a%3==0)or(b%3==0)) else 'Impossible')
a,b = map(int,input().split())

c = 0

def sigma(x):
	if x <= 0:
		return x
	return x + sigma(x-1)
  
for i in range(1,1000):
	c += 1
	if sigma(i) > a:
		break
        
print(sigma(c) - a)

### FIXED CODE ###

a,b = map(int,input().split())


print(int((b-a)*(b-a+1)/2-b))
import sys
sys.setrecursionlimit(1000000)
from collections import deque

def bfs(sx,sy,gx,gy):
    d = [[float("inf")] * w for i in range(h)]
    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    que = deque([])
    que.append((sx, sy))
    d[sx][sy] = 0

    while que:
        p = que.popleft()
        if p[0] == gx and p[1] == gy:
            break
        for i in range(4):
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]
            if 0 <= nx < h and 0 <= ny < w and s[nx][ny] != "#" and d[nx][ny] == float("inf"):
                que.append((nx, ny))
                d[nx][ny] = d[p[0]][p[1]] + 1

    return d[gx][gy]

h,w=map(int,input().split())
s = [list(input()) for i in range(h)]
ans=0
def check(i,j):
    if 1<=j<=w-2:
        if s[0][j-1]=='#' or s[0][j+1]=='#' or s[1][j]=='#':
            return True
    elif 1<=j<=w-2:
        if s[h][j-1]=='#' or s[h][j+1]=='#' or s[h-1][j]=='#':
            return True
    elif 1<=i<=h-2:
        if s[i-1][0]=='#' or s[i+1][0]=='#' or s[i][1]=='#':
            return True
    elif 1<=i<=h-2:
        if s[i-1][w]=='#' or s[i+1][w]=='#' or s[i][w-1]=='#':
            return True
    elif 1<=i<=h-2 and 1<=j<=w-2:
        if s[i][j+1]=='#' or s[i][j-1]=='#' or s[i+1][j]=='#' or s[i-1][j]=='#':
            return 0
    elif i==0 and j==0:
        return True
    elif i==0 and j==w-1:
        return True
    elif i==h-1 and j==0:
        return True
    elif i==h-1 and j==w-1:
        return True
    else:
        return False
for i in range(h):
    for j in range(w):
        if s[i][j]=='.' and check(i,j):
            if j != w:
                for m in range(j+1,w):
                    if s[i][m]=='.' and check(i,m):
                        ans = max(ans,bfs(i,j,i,m))
            for k in range(i+1,h):
                for l in range(w):
                    if s[k][l]=='.' and check(k,l):
                        ans = max(ans,bfs(i,j,k,l))
print(ans)

### FIXED CODE ###

import sys
sys.setrecursionlimit(1000000)
from collections import deque


h,w=map(int,input().split())
s = [list(input()) for i in range(h)]

def bfs(sx,sy):
    dx = [0,1,0,-1]
    dy = [1,0,-1,0]
    d = [[-1]*w for i in range(h)]
    q = deque()
    q.append((sx,sy))
    d[sx][sy] = 0
    while q:
        x,y = q.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if  0<= nx < h and 0 <= ny < w and d[nx][ny]==-1 and s[nx][ny]=='.':
                q.append((nx,ny))
                d[nx][ny] = d[x][y]+1
    return max([max(i) for i in d])

count = 0
for i in range(h):
    for j in range(w):
        if s[i][j] != '#':
            count  = max(count, bfs(i,j))
print(count)