CodeEff/ECCO huggingface dataset:
# Original solution
import sys
read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines

def main():
    H,W,K = list(map(int, readline().split()))
    S = [readline().strip() for j in range(H)]

    white = []
    for line in S:
        white.append(line.count("1"))
    white_total = sum(white)

    if white_total <= K:
        print((0))
        exit()

    # 横線の決め方を全探索
    ans = 10**5
    for pattern in range(2**(H-1)):
        # 初期化
        impossible = False
        x = 0
        ly = bin(pattern).count("1")
        y = [[0]*W]*(ly + 1)
        line = 0
        for i in range(H):
            y[line] = [y[line][j] + int(S[i][j]) for j in range(W)]
            if (pattern >> i) & 1:
                line += 1

        # 各列の値を加算していく
        count = [0]*(ly + 1) 
        for col in zip(*y):
            # Kより大きい値を加算する場合は不成立
            if any(a > K for a in col):
                impossible = True
                break
            for i, a in enumerate(col):
                count[i] += a
                # 和がKより大きければカット数を増やす
                if count[i] > K:
                    x += 1
                    count = list(col) 
                    break
            if x + ly > ans:
                impossible = True
                break
        if impossible:
            x = 10**6

        ans = min(ans, x + ly)

    print(ans)


if __name__ == "__main__":
    main()


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

def main():
    H,W,K = list(map(int, readline().split()))
    S = [list(map(int, readline().strip())) for j in range(H)]

    white = 0
    for line in S:
        white += sum(line)

    if white <= K:
        print((0))
        exit()

    # 横線の決め方を全探索
    ans = 10**5
    for pattern in range(2**(H-1)):
        # 初期化
        impossible = False
        x = 0
        ly = bin(pattern).count("1")
        y = [[0]*W]*(ly + 1)
        line = 0
        for i in range(H):
            y[line] = [y[line][j] + S[i][j] for j in range(W)]
            if (pattern >> i) & 1:
                line += 1

        # 各列の値を加算していく
        count = [0]*(ly + 1) 
        for col in zip(*y):
            # Kより大きい値を加算する場合は不成立
            if any(a > K for a in col):
                impossible = True
                break
            for i, a in enumerate(col):
                count[i] += a
                # 和がKより大きければカット数を増やす
                if count[i] > K:
                    x += 1
                    count = list(col) 
                    break
            if x + ly > ans:
                impossible = True
                break
        if impossible:
            x = 10**6

        ans = min(ans, x + ly)

    print(ans)


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

def main():
    H,W,K = list(map(int, readline().split()))
    S = [list(map(int, readline().strip())) for j in range(H)]

    white = 0
    for line in S:
        white += sum(line)

    if white <= K:
        print((0))
        exit()

    # 横線の決め方を全探索
    ans = 10**5
    for pattern in range(2**(H-1)):
        # 初期化
        impossible = False
        x = 0
        ly = bin(pattern).count("1")
        y = [[0]*W]*(ly + 1)
        line = 0
        for i in range(H):
            y[line] = [y[line][j] + S[i][j] for j in range(W)]
            if (pattern >> i) & 1:
                line += 1

        # 各列の値を加算していく
        count = [0]*(ly + 1) 
        for j in range(W):
            for i in range(line+1):
                if y[i][j] > K :
                    impossible = True
                    break

                count[i] += y[i][j]
                if count[i] > K:
                    x += 1
                    for i in range(line+1):
                        count[i] = y[i][j] 
                    break
            if x + ly > ans or impossible:
                impossible = True
                break
        if impossible:
            x = 10**6

        ans = min(ans, x + ly)

    print(ans)


if __name__ == "__main__":
    main()


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

def main():
    H,W,K = list(map(int, readline().split()))
    S = [list(map(int, readline().strip())) for j in range(H)]

    white = 0
    for line in S:
        white += sum(line)

    if white <= K:
        print((0))
        exit()

    # 横線の決め方を全探索
    ans = 10**5
    for pattern in range(2**(H-1)):
        # 初期化
        impossible = False
        x = 0
        ly = bin(pattern).count("1")
        y = [S[0]]
        line = 0
        for i in range(1,H):
            if (pattern >> i-1) & 1:
                line += 1
                y.append(S[i])
            else:
                y[line] = [y[line][j] + S[i][j] for j in range(W)]

        # 各列の値を加算していく
        count = [0]*(ly + 1) 
        for j in range(W):
            for i in range(line+1):
                if y[i][j] > K :
                    impossible = True
                    break

                count[i] += y[i][j]
                if count[i] > K:
                    x += 1
                    for i in range(line+1):
                        count[i] = y[i][j] 
                    break
            if x + ly > ans or impossible:
                impossible = True
                break
        if impossible:
            x = 10**6

        ans = min(ans, x + ly)

    print(ans)


if __name__ == "__main__":
    main()
# Original solution
import sys
from copy import copy
input = sys.stdin.readline
'''
n, m = map(int, input().split())
n = int(input())
A = list(map(int, input().split()))
S = input().strip()
for test in range(int(input())):
'''
inf = 100000000000000000  # 1e17
mod = 998244353


def two(x):
    return "0" * (w - len(bin(x)[2:])) + bin(x)[2:]


h, w, maxx = list(map(int, input().split()))
A = []
for i in range(h):
    A.append(input().strip())
# for binary in range(1<<(w-1),(1<<(w-1))+1):
ans = inf
for binary in range(1 << (w - 1)):  # every binary
    S = two(binary)
    B = [-1]
    for i in range(len(S)):
        if S[i] == "1":
            B.append(i)
    B.append(len(S) - 1)  # every horizontal cut, contain the head and the tail
#    print(B)
    SUM = [0] * (len(B))
    isok = 1
    cut_vertical = 0
    cut_horizontal = len(B) - 2
    for i in range(h):
        PRE = copy(SUM)  # previous total numbers between every cut
        for j in range(1, len(B)):  # every cut
            for k in range(B[j - 1] + 1, B[j] + 1):
                if A[i][k] == "1":
                    SUM[j] += 1
        flag = 0
        for j in range(1, len(B)):
            if SUM[j] > maxx:
                flag = 1
        if flag:
            for j in range(1, len(B)):
                SUM[j] -= PRE[j]
            cut_vertical += 1
        for j in range(1, len(B)):
            if SUM[j] > maxx:
                isok = 0
        if isok == 0:
            break
    if isok:
        ans = min(ans, cut_vertical + cut_horizontal)
print(ans)


# Optimized solution
import sys
from copy import copy
input = sys.stdin.readline
'''
n, m = map(int, input().split())
n = int(input())
A = list(map(int, input().split()))
S = input().strip()
for test in range(int(input())):
'''
inf = 100000000000000000  # 1e17
mod = 998244353


def two(x):
    return "0" * (h - 1 - len(bin(x)[2:])) + bin(x)[2:]


h, w, k = list(map(int, input().split()))
S = []
ans = inf
for i in range(h):
    S.append(input().strip())
for way_cut in range(1 << (h - 1)):
    way_cut = two(way_cut)
    number_cut_horizontal = way_cut.count("1")
    number_cut_vertical = 0
    CUT = [-1]
    for i in range(len(way_cut)):
        if way_cut[i] == '1':
            CUT.append(i)
    CUT.append(len(way_cut))
    SUM = [0] * (w)
    PRE = [0] * (w)
    for col in range(w):
        for i in range(1, len(CUT)):
            for between in range(CUT[i - 1] + 1, CUT[i] + 1):
                SUM[i] += 1 if S[between][col] == "1" else 0
        isok = True
        for i in range(1, len(CUT)):
            if PRE[i] + SUM[i] > k:
                isok = False
        if not isok:
            number_cut_vertical += 1
            PRE = copy(SUM)
            SUM = [0]*(w)  # leave out
            # recheck
            for i in range(1, len(CUT)):
                if PRE[i] > k:
                    number_cut_vertical = inf
                    break
        else:
            for i in range(1, len(CUT)):
                PRE[i] += SUM[i]
                SUM[i] = 0
    ans = min(ans, number_cut_vertical + number_cut_horizontal)
print(ans)
# Original solution
r=range
h,*s=open(0)
h,w,k=list(map(int,h.split()))
m=9e9
for i in r(1<<h-1):
 t,v,l=[],-1,1
 for j in r(h):z=i>>j&1;t+=[j+1]*z;l+=z
 t+=h,
 c=[0]*l
 for i in r(w):
  b=f=g=0;u=[]
  for j in r(l):d,b=sum(s[j][i]>"0"for j in r(b,t[j])),t[j];u+=d,;g|=d>k;c[j]+=d;f|=c[j]>k
  v+=f
  if f:c=u
 if g<1:m=min(m,v+l)
print(m)

# Optimized solution
r=range
h,*s=open(0)
m=9e9
h,w,k=list(map(int,h.split()))
for i in r(1<<h-1):
 t=[j+1for j in r(h)if i>>j&1]+[h];l=len(t);v=-1;c=[0]*l
 for i in r(w):
  b=f=g=0;u=[]
  for j in r(l):d,b=sum(s[j][i]>"0"for j in r(b,t[j])),t[j];u+=d,;g|=d>k;c[j]+=d;f|=c[j]>k
  v+=f
  if f:c=u
 if g<1:m=min(m,v+l)
print(m)
# Original solution
r=range
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
for i in r(512):
 t=[j+1for j in r(h)if i>>j&1]+[h];l=len(t);v=1;c=[0]*l
 for i in r(w):
  b=f=g=0;u=[]
  for j in r(l):d,b=sum(s[j][i]>"0"for j in r(b,t[j])),t[j];u+=d,;g|=d>k;c[j]+=d;f|=c[j]>k
  v-=f
  if f:c=u
 if g<1:m+=l-v,
print((min(m)))

# Optimized solution
x,*s=open(0)
h,w,k,*m=list(map(int,x.split()))
for b in range(512):
 r=t=j=0;d=[0]*h
 while w-j:
  i=c=0
  while h-i:
   d[c]+=s[i][j]>'0';x=d[c]>k
   if(t<j)&x:r+=1;t=j;d=[0]*h;break
   r+=h*w*x;c+=b>>i&1;i+=1
  else:j+=1
 m+=r+bin(b).count('1'),
print((min(m)))
# Original solution
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
b=512
while b:
 b-=1;r=t=j=0;d=[0]*h
 while w-j:
  i=c=0
  while h-i:
   d[c]+=s[i][j]>'0';f=d[c]>k
   if(t<j)&f:r+=1;t=j;d=[0]*h;break
   r+=h*w*f;c+=b>>i&1;i+=1
  else:j+=1
 m+=r+c,
print((min(m)))

# Optimized solution
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
b=512
while b:
 b-=1;r=t=j=-1;d=[0]*h
 while~j+w:
  j+=1;i=c=0
  while h-i:
   d[c]+=s[i][j]>'0';f=t<j
   if d[c]>k:d=[0]*h;r+=1-h*w*~-f;t=j;j-=f;break
   c+=b>>i&1;i+=1
 m+=r-~c,
print((min(m)))
# Original solution
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
b=w
while b:
 b-=1;r=t=j=-1;d=[0]*h
 while~j+w:
  j+=1;i=c=0
  while h-i:
   d[c]+=s[i][j]>'0';f=t<j
   if d[c]>k:d=[0]*h;r+=1-h*w*~-f;t=j;j-=f;break
   c+=b>>i&1;i+=1
 m+=r-~c,
print((min(m)))

# Optimized solution
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
b=w
while b:
 b-=1;r=t=j=0;d=[0]*h
 while w-j:
  i=c=0;j+=1
  while h-i:
   d[c]+=s[i][~j]>'0'
   if d[c]>k:d=[0]*h;f=t<j;r-=h*w*~-f-1;t=j;j-=f;break
   c+=b>>i&1;i+=1
 m+=r+c,
print((min(m)))
# Original solution
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
b=w
while b:
 b-=1;r=t=j=0;d=[0]*h
 while w-j:
  i=c=0;j+=1
  while h-i:
   d[c]+=s[i][~j]>'0';c+=b>>i&1;i+=1
   if max(d)>k:d=[0]*h;r+=1;j-=1;i=h
 m+=r+c,
print((min(m)))

# Optimized solution
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
b=w
while b:
 b-=1;r=t=j=0;d=[0]*h
 while w-j:
  i=c=0;j+=1
  while h-i:
   d[c]+=s[i][~j]>'0';c+=b>>i&1;i+=1
   if max(d)>k:d=[0]*h;r+=1;t,j=j,j-(t<j);i=h
 m+=r+c,
print((min(m)))
# Original solution
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
b=512
while b:
 b-=1;r=t=j=0;d=[0]*h
 while w-j:
  i=c=0;j+=1
  while h-i:
   d[c]+=s[i][~j]>'0';c+=b>>i&1;i+=1
   if max(d)>k:d=[0]*h;r+=1;j-=t<j;t=j;i=h
 m+=r+c,
print((min(m)))

# Optimized solution
h,*s=open(0)
h,w,k,*m=list(map(int,h.split()))
b=w
while b:
 b-=1;r=0;t=j=w;d=[0]*h
 while j:
  i=c=0;j-=1
  while h-i:
   d[c]+=s[i][j]>'0';c+=b>>i&1;i+=1
   if max(d)>k:d=[0]*h;r+=1;t,j=j,j+(t>j);i=h
 m+=r+c,
print((min(m)))
# Original solution
def main():
    import sys
    input=sys.stdin.readline
    h,w,k=list(map(int,input().split()))
    S=[]
    for _ in range(h):
        s=list(map(int,list(input().rstrip())))
        S.append(s)
    ans=10**5
    for i in range(2**(h-1)):
        l=[0]
        for j in range(h-1):
            if i&1<<j:
                l.append(l[-1]+1)
            else:
                l.append(l[-1]) 
        ans_=l[-1]
        ll=[0]*h
        j=0
        while j<w:
            for p in range(h):
                ll[l[p]]+=S[p][j]
            if max(ll)>k:
                ans_+=1
                ll=[0]*h
            else:
                j+=1
        ans=min(ans,ans_)
    print(ans)
if __name__ == '__main__':
    main()

# Optimized solution
def main():
    import sys
    input=sys.stdin.readline
    h,w,k=list(map(int,input().split()))
    S=[]
    for _ in range(h):
        s=list(map(int,list(input().rstrip())))
        S.append(s)
    ans=10**5
    for i in range(2**(h-1)):
        l=[0]
        for j in range(h-1):
            if i&1<<j:
                l.append(l[-1]+1)
            else:
                l.append(l[-1]) 
        ans_=l[-1]
        ll=[0]*h
        j=0
        flag=0
        while j<w:
            for p in range(h):
                ll[l[p]]+=S[p][j]
            if max(ll)>k and flag==0:
                flag=1
                ans_+=1
                ll=[0]*h
            elif max(ll)>k and flag==1:
                ans_=10**5
                break
            else:
                j+=1
                flag=0
        ans=min(ans,ans_)
    print(ans)
if __name__ == '__main__':
    main()
# Original solution
import sys
from collections import deque
input = sys.stdin.readline

def main():
    H, W, K = list(map(int, input().split()))
    grid = [list(map(int, list(input().strip()))) for _ in range(H)]

    white_count = sum(sum(x) for x in grid)

    # 折れる箇所全部で折った数が最大値
    ans = (H - 1) * (W - 1)

    # 横線で割るパターン全てについて縦線での降り方を考える
    for i in range(2 ** (H - 1)):

        # 横方向に割った後のチョコの状態を生成
        snap = 0
        board = [[grid[0]]]
        for j in range(H-1):
            if ((i >> j) & 1):
                board.append([grid[j + 1]])
                snap += 1
            else:
                board[-1].append(grid[j + 1])

        w_count_board = [[] for _ in board]
        for x in range(W):
            # 縦方向に折るかのフラグ
            snap_flag = False
            for y, hori in enumerate(board):
                # その位置までおらなかった場合のチョコの個数を生成
                w_choco = sum(row[x] for row in hori)
                w_count_board[y].append(w_choco)

                # 上限超えたらおる
                if sum(w_count_board[y]) > K:
                    snap_flag = True

            # フラグがたってたら、x -1 まではおるので無視
            # チョコの個数カウントをx始まりで更新
            if snap_flag:
                w_count_board = [[wcb[-1]] for wcb in w_count_board]
                snap += 1

        ans = min(ans, snap)

    print(ans)


if __name__ == "__main__":
    main()


# Optimized solution
# 足し合わせしすぎてるのでTLE
import sys
input = sys.stdin.readline

def main():
    H, W, K = list(map(int, input().split()))
    grid = [list(map(int, list(input().strip()))) for _ in range(H)]

    # 折れる箇所全部で折った数が最大値
    ans = (H - 1) * (W - 1)

    # 横線で割るパターン全てについて縦線での降り方を考える
    for i in range(2 ** (H - 1)):
        snap = 0

        hori_grid = [grid[0]]
        for j in range(H - 1):
            if ((i >> j) & 1):
                hori_grid.append(grid[j+1])
                snap += 1
            else:
                hori_grid[-1] = [a + b for a,b in zip(hori_grid[-1], grid[j+1])]

        wc_count = [hori_grid[y][0] for y in range(snap + 1)]

        # 最初の列で超えてる場合はスキップ
        if max(wc_count) > K:
            continue

        for x in range(1, W):
            now_wc_count = [hori_grid[y][x] for y in range(len(wc_count))]
            next_wc_count = [a+b for a,b in zip(wc_count, now_wc_count)]

            if max(next_wc_count) > K:
                snap += 1
                wc_count = now_wc_count
            else:
                wc_count = next_wc_count

        ans = min(ans, snap)

    print(ans)


if __name__ == "__main__":
    main()
# Original solution
def main():
    import sys
    inf = 100100100
    ans = inf
    H, W, K = list(map(int, input().split()))
    S = [0]*H
    for i in range(H):
        S[i] = [int(x) for x in sys.stdin.readline().strip()]
    for i in range(2**(H-1)):
        group = [0]
        g = 0
        for j in range(H-1):
            if (i >> j) & 1:
                g += 1
            group.append(g)
        g += 1
        c = [[0 for _ in range(W)] for __ in range(g)]
        for j in range(H):
            for k in range(W):
                c[group[j]][k] += S[j][k]
        num = g-1
        now = [0]*g
        def large(now):
            for n in now:
                if n > K:
                    return True
            else:
                return False
        def v_vec(twodlis, k):
            ans = []
            for lis in twodlis:
                ans.append(lis[k])
            return ans
        for k in range(W):
            for n in range(len(now)):
                now[n] = now[n] + v_vec(c,k)[n]
            if large(now):
                now = v_vec(c,k)
                num += 1
                if large(now):
                    num = inf
                    break

        ans = min(ans, num)
    print(ans)

if __name__ == "__main__":
    main()


# Optimized solution
import sys
inf = 100100100
ans = inf
H, W, K = list(map(int, input().split()))
S = [0]*H
for i in range(H):
    S[i] = [int(x) for x in sys.stdin.readline().strip()]
for i in range(2**(H-1)):
    group = [0]
    g = 0
    for j in range(H-1):
        if (i >> j) & 1:
            g += 1
        group.append(g)
    g += 1
    c = [[0 for _ in range(W)] for __ in range(g)]
    for j in range(H):
        for k in range(W):
            c[group[j]][k] += S[j][k]
    num = g-1
    now = [0]*g
    def large(now):
        for n in now:
            if n > K:
                return True
        else:
            return False
    def v_vec(twodlis, k):
        ans = []
        for lis in twodlis:
            ans.append(lis[k])
        return ans
    for k in range(W):
        for n in range(len(now)):
            now[n] = now[n] + v_vec(c,k)[n]
        if large(now):
            now = v_vec(c,k)
            num += 1
            if large(now):
                num = inf
                break

    ans = min(ans, num)
print(ans)
# Original solution
n, k = list(map(int, input().split()))
a = []
if n % k == 0:
  print((0))
else :
  while n > 0 :
    n -= k
    a.append(n)
    
  if len(a) == 1 : 
    if a[-1] * -1 > n + k :
      print((n + k))
    else :
      print((a[-1] * -1))

  else :
    if (a[-1]) * -1 > a[-2] :
      print((a[-2]))
    else :
      print(((a[-1]) * -1))

# Optimized solution
n, k = list(map(int, input().split()))
a = []
if n % k == 0:
  print((0))

elif n // k == 0 :
  if -(n - k) > n :
    print(n)
  else :
    print((-(n - k)))

else :
  if n % k > (n % k) - k :
    print((-((n % k) - k)))
  else :
    print((n % k))
# Original solution
import sys
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
read = sys.stdin.buffer.read
sys.setrecursionlimit(10 ** 7)

N, K = list(map(int, readline().split()))

answer = N % K
while True:
    new = abs(answer - K)
    if new > answer:
        break
    answer = new
print(answer)

# Optimized solution
import sys
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
read = sys.stdin.buffer.read
sys.setrecursionlimit(10 ** 7)

N, K = list(map(int, readline().split()))

answer = min(N % K, abs(N % K - K))
print(answer)
# Original solution
n,k = list(map(int,input().split()))
x = n
if k==1:
    print((0))
else:
    while x > abs(x-k):
        x = abs(x-k)
    print(x)

# Optimized solution
n,k = list(map(int,input().split()))
x = n
if n>=k:
    x = n%k
if x >abs(x-k):
    print((abs(x-k)))
else:
    print(x)
# Original solution
n, k = list(map(int, input().split()))
cou = 0
i = 0
flag = 0
if  k == 1:
  n = 0
elif k == 0:
  n = n
else:
  while flag < 1:
    if n < abs(n-k):
      flag = 1
    else:
      n = abs(n-k)
      i += 1

print(n)

# Optimized solution
n, k = list(map(int, input().split()))

q = n // k
mod = n % k
ans_mod = k-mod

if mod<ans_mod:
  print(mod)
else:
  print(ans_mod)
# Original solution
n, K = [int(x) for x in input().split()]

res = 0
pn = n
for i in range(10**18):
    if n % K == 0:
        res = 0
        break
    if abs(pn - K) > pn:
        res = pn
        break
    else:
        pn = n
        n = abs(pn - K)

print (res)

# Optimized solution
n, K = [int(x) for x in input().split()]

res = 0
if n % K > abs((n % K) - K):
    res = abs((n % K) - K)
else:
    res = n % K
    
print (res)
# Original solution
N, K = list(map(int, input().split()))

r=0

if(N<K):
  if(abs(N-K)<N):
    r=abs(N-K)
  else:
    r=N

elif(K==1):
   r=0

elif(K<N):
  while(0<N):
    r=abs(N-K)
    N=N-K

print(r)

# Optimized solution
N, K = list(map(int, input().split()))

r=0

if(N<K):
  if(abs(N-K)<N):
    r=abs(N-K)
  else:
    r=N

elif(K==1):
   r=0

elif(K<N):
  a=N//K
  N=N-K*a
  while(0<N):
    r=abs(N-K)
    N=N-K

print(r)
# Original solution
n, k = list(map(int,input().split()))
n_min = 10**18
n_min_sb = 10**19
if k == 1:
    n_min = 0
else:
    while n_min != n_min_sb:
        n = abs(n-k)
        if n_min > n:
            n_min_sb = n_min
            n_min = n
        if n_min < n:
            n_min_sb = n_min
print(n_min)

# Optimized solution
n, k = list(map(int, input().split()))
print((min(n%k, k-n%k)))
# Original solution
N, K = list(map(int, input().split()))
while True:
    if K == 1:
        N=0
        break
    n = abs(N-K)
    if n >= N:
        break
    else:
        N = n
print(N)
    

# Optimized solution
N, K = list(map(int, input().split()))
n = N % K
if n > abs(n-K):
    n = abs(n-K)
print(n)
# Original solution
N, K = list(map(int, input().split()))
import math
if N > K:
    s = N // K
    print((min(abs(N - s * K), abs(N - (s + 1) * K))))
elif N == K:
    print((0))
else:
    print((min(N, abs(N - K))))

# Optimized solution
N, K = list(map(int, input().split()))
s = N // K
ans = min(abs(N - s * K), abs(N - (s + 1) * K))
print(ans)
# Original solution
N,K = list(map(int, input().split()))

if N > K and K == 1:
    print((0))
    exit(0)

while N > abs(N - K):
    N = abs(N - K)


print(N)

# Optimized solution
N,K = list(map(int, input().split()))
ans = 0

if N < abs(N - K):
    ans = N
elif N % K == 0:
    ans = 0
else:
    ans = abs(N % K - K)


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

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

if N<=K:
    print((min(N, K-N)))
else:
    M = N-(N-1)//K*K
    print((min(M, K-M)))

# Optimized solution
N, K = list(map(int, input().split()))
t = N%K

print((min(t, K-t)))
# Original solution
N, K = list(map(int, input().split()))
M = abs(N - K)
mini = M + 1

if (N%K == 0):
    print((0))
else:
    while (M < mini):
        mini = min(mini, M)
        M = abs(M - K)
    print(mini)


# Optimized solution
N, K = list(map(int, input().split()))
M = abs(N - K)
mini = M + 1

if (not N < K):
    if (N%K == 0):
        print((0))
    else:
        M = (N % K)
        while (M < mini):
            mini = min(mini, M)
            M = abs(M - K)
        print(mini)

else:
    while (M < mini):
        mini = min(mini, M)
        M = abs(M - K)
    print(mini)
# Original solution
import sys

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

if k == 1:
    print((0))
    sys.exit()

# x = n
while True:
    min_n = n
    n = abs(n-k)
    if min_n >= n:
        min_n = n
    else:
        break
print(min_n)


# Optimized solution
import sys
import math

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

# n_start = math.floor(n / k)
# # print(n_start)
# n = n - n_start*k
# # print(n)

n = n % k

while True:
    min_n = n
    n = abs(n-k)
    # print("n, k =", n, k)
    if min_n > n:
        min_n = n
    else:
        break
print(min_n)
# Original solution
N, K = list(map(int, input().split()))
ans = 0
judge = True

while judge == True:
    if K == 1:
        N = 0
        break

    ans = N - K
    N = abs(ans)

    ans = N - K
    mem = abs(ans)

    if N > mem:
        pass
    else:
        judge = False


print(N)

# Optimized solution
N, K = list(map(int, input().split()))
a = abs(N%K)
print((min(a, abs(a-K))))