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

# 考えると、隣り合う列は結局 2*H 回ずることになり、
# それぞれの列間について最適な沈め順を見つけると、
# その順序関係を崩さないように全体の順番も構築できる（トポロジカルソートみたいに）ので、
# 各列間の最適解を求めて総和をとればいい

# TLE が厳しすぎる

inf = 2 * 10**9
H, W = map(int, input().split())
C = [input() for _ in range(H)]
C_T = list(zip(*C))
C_T = ["".join(s) for s in C_T]
ans = 0
C1 = C_T[0]
for C2 in C_T[1:]:
    # Z[i][j] := i 個ずれてて沈んでない方が j 個沈んでる状態の連結個数
    Z1 = []  # 左を押したとき（右が上にあるとき）
    Z2 = []  # 右を押したとき（左が上にあるとき）
    for j in range(H+1):
        z1, z2 = [0], [0]
        c1 = c2 = 0
        C1_, C2_ = C1[j:], C2[j:]
        for i in range(H - j):
            if C1[i] == C2_[i]:
                c1 += 1
            z1.append(c1)
        for i in range(H - j):
            if C1_[i] == C2[i]:
                c2 += 1
            z2.append(c2)
        z1.reverse()
        z2.reverse()
        Z1.append(z1)
        Z2.append(z2)
    # dp[i][j] := 左を i 個、右を j 個沈めるまでの最小コスト  # 逆かも（どっちでもいい）
    dp = [[inf] * (H+2) for _ in range(H+2)]
    dp[0][0] = 0
    for j in range(H+1):
        for k in range(H+1):
            cost = dp[j][k] + (Z1[j-k][k] if j>=k else Z2[k-j][j])
            dp[j+1][k] = min(dp[j+1][k], cost)
            dp[j][k+1] = min(dp[j][k+1], cost)
    ans += dp[H][H]
    C1 = C2
print(ans)


### FIXED CODE ###

# 考えると、隣り合う列は結局 2*H 回ずることになり、
# それぞれの列間について最適な沈め順を見つけると、
# その順序関係を崩さないように全体の順番も構築できる（トポロジカルソートみたいに）ので、
# 各列間の最適解を求めて総和をとればいい

def accumulate_reverse(S1, S2):
    n = min(len(S1), len(S2))
    res = [0] * (n+1)
    c = 0
    for i in range(n):
        if S1[i] == S2[i]:
            c += 1
        res[n-i-1] = c
    return res

inf = 10**8
H, W = map(int, input().split())
C = [input() for _ in range(H)]
C_T = list(zip(*C))
C_T = ["".join(s) for s in C_T]
ans = 0
for C1, C2 in zip(C_T[:-1], C_T[1:]):
    # Z[i][j] := i 個ずれてて沈んでない方が j 個沈んでる状態の連結個数
    Z1 = []  # 左を押したとき（右が上にあるとき）
    Z2 = []  # 右を押したとき（左が上にあるとき）
    Z1.append(accumulate_reverse(C1, C2))
    for j in range(1, H+1):
        Z1.append(accumulate_reverse(C1, C2[j:]))
        Z2.append(accumulate_reverse(C1[j:], C2))
    Z1 += Z2[::-1]
    # dp[i][j] := 左を i 個、右を j 個沈めるまでの最小コスト  # 逆かも（どっちでもいい）
    dp = [[inf] * (H+2) for _ in range(H+2)]
    dp[0][0] = 0
    for j in range(H+1):
        for k in range(H+1):
            cost = dp[j][k] + Z1[j-k][min(j, k)]
            dp[j+1][k] = min(dp[j+1][k], cost)
            dp[j][k+1] = min(dp[j][k+1], cost)
    ans += dp[H][H]
print(ans)
### BUGGY CODE ###

import numpy as np

num = input()
num = int(num)

str = input()
list_in = str.split()

count_arr = np.zeros((num+1))
sum_arr = np.zeros((num+1))

for item in list_in:
    count_arr[int(item)] += 1

sum = 0
for i in range(len(count_arr)):
    tmp = count_arr[i]
    tmp = (tmp * (tmp -1)) / 2
    sum += tmp
    sum_arr[i] = tmp

for item in list_in:
    tmp = int(item)
    old_sum = sum_arr[tmp]
    tmp = count_arr[tmp] - 1
    tmp = (tmp * (tmp -1)) / 2
    result = sum - old_sum + tmp
    print(int(result))


### FIXED CODE ###

import numpy as np

num = input()
num = int(num)

str = input()
list_in = list(map(int, str.split()))

count_arr = [0]*num

for item in list_in:
    count_arr[item-1] += 1

sum = 0
for i in range(num):
    tmp = count_arr[i-1]
    tmp = (tmp * (tmp -1))//2
    sum += tmp

for item in list_in:
    tmp = count_arr[item-1]
    result = sum - (tmp - 1)
    print(result)
### BUGGY CODE ###

import numpy as np

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

A_point = np.array([K] * N)

for _ in range(Q):
  a = int(input())
  A_point[a-1] += 1
  A_point -= 1

for i in range(N):
  if A_point[i] > 0:
    print('Yes')
  else:
    print('No')  

### FIXED CODE ###

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

A_point = [K] * N

for _ in range(Q):
  A_point[int(input())-1] += 1

A_point = map(lambda x:x-Q, A_point)

for r in A_point:
  if r > 0:
    print('Yes')
  else:
    print('No')
### BUGGY CODE ###

import sys
sys.setrecursionlimit(int(2e6))
h,w=map(int,input().split())
a=[]
for _ in range(h):
    a.append(list(input()))

dp=[[0]*w for _ in range(h)]
z=[[0]*w for _ in range(h)]
dp[h-1][w-1]=1
z[h-1][w-1]=1
def c(i,j):
    if z[i][j]!=0:
        return dp[i][j]
    if 1<=i+1<=h-1 and 0<=j<=w-1:
        if a[i+1][j]!="#":
            dp[i][j]+=c(i+1,j)
    if 1<=j+1<=w-1 and 0<=i<=h-1:
        if a[i][j+1]!="#":
            dp[i][j]+=c(i,j+1)
    z[i][j]=1
    return dp[i][j]
print(c(0,0)%(10**9+7))

### FIXED CODE ###

h,w=map(int,input().split())
a=[]
for _ in range(h):
    a.append(list(input()))

dp=[[0]*w for _ in range(h)]
dp[0][0]=1
for i in range(h):
    for j in range(w):
        if i+1<h and a[i+1][j]=='.':
            dp[i+1][j]+=dp[i][j]%(10**9+7)
        if j+1<w and a[i][j+1]=='.':
            dp[i][j+1]+=dp[i][j]%(10**9+7)
print(dp[h-1][w-1]%(10**9+7))
### BUGGY CODE ###

import math
from functools import reduce
k = int(input())
ans = 0

def gcd(*numbers):
    return reduce(math.gcd, numbers)

for i in range(1, k+1):
    for j in range(1, k + 1):
        for m in range(1, k + 1):
            ans += gcd(i, j, m)

print(ans)




### FIXED CODE ###

import math
k = int(input())
ans = 0
ans1 = 0

for i in range(1, k + 1):
    for j in range(1, k + 1):
        ans1 = math.gcd(i, j)
        for m in range(1, k + 1):
            ans += math.gcd(ans1, m)

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

def fact(n):
    a = 1
    for i in range(n):
        a *= i+1
    return a

def conb(m, n):
    return fact(n) // fact(m) // fact(n-m)

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

sum = 0
c = conb(K-2, N*M-2)
for m in range(M):
    sum += c * (M-m) * (N**2) * m
    sum %= 1000000007
for n in range(N):
    sum += c * (N-n) * (M**2) * n
    sum %= 1000000007

print(sum)

### FIXED CODE ###

mod = 10**9 + 7
 
 
def comb(n, k):
    x, y = 1, 1
    k = min(k, n - k)
    for i in range(k):
        x *= n - i
        x %= mod
        y *= i + 1
        y %= mod
    return x * pow(y, mod - 2, mod) % mod

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

c = comb(N*M-2,K-2)

ans = c * (M**2 * (N**2 * (N+1)//2 - N*(N+1)*(2*N+1)//6) + N**2 * (M**2 * (M+1)//2 - M*(M+1)*(2*M+1)//6)) % mod

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

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

lists2=list(map(int,input().split()))
lists3=list(map(int,input().split()))
numbers=0
for x in range(n):
    for y in range(n):
        for z in range(n):
            if lists1[x]<lists2[y]<lists3[z]:
                numbers+=1
            else:
                continue
print(numbers)

### FIXED CODE ###

n=int(input())
lists1=sorted(list(map(int,input().split())))+[10**9+1]

lists2=sorted(list(map(int,input().split())))+[10**9+2]
lists3=sorted(list(map(int,input().split())))+[10**9+3]
lists_small=[0]*(n+1)
lists_big=[0]*(n+1)

numbers=0
for x in range(n):
    while lists1[numbers]<lists2[x]:
        numbers+=1
    lists_small[x]=numbers


numberss=0
for y in range(n):
    while lists3[numberss]<=lists2[y]:
        numberss+=1
    changes=n-numberss
    lists_big[y]=changes



ans=0
for xy in range(n):
    ans+=lists_big[xy]*lists_small[xy]
print(ans)
### BUGGY CODE ###

from collections import deque

n = int(input())
li = deque(list(map(int,input().split())) for i in range(1,n+1))

cnt = 0
check = []
play = 0
tamel = []
s = 0

while play < n*(n-1) // 2:
    s = play
    for i in range(1,n):
        if i in check or len(li[i-1]) == 0:
            continue
        temp = li[i-1][0]
        if temp <= i:
            continue
        if li[temp-1][0] == i and temp not in check:
            del li[i-1][0]
            del li[temp-1][0]
            play += 1
            check.append(temp)
    cnt += 1
    tamel = []
    check = []
    
    if s == play:
        print(-1)
        exit()

print(cnt)


### FIXED CODE ###

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)
 
N = int(input())
A = [[-1] + [int(x)-1 for x in row.split()][::-1] for row in sys.stdin.readlines()]
 
A.append([-1])

def f(cand):
    cand1 = set()
    can_use = []
    for n in cand:
        if A[A[n][-1]][-1] == n:
            can_use.append(n)
    for n in can_use:
        A[n].pop()
        cand1.add(n)
        if A[n][-1] != -1:
            cand1.add(A[n][-1])
    return len(can_use), cand1
    
answer = 0
rest = N*(N-1)
cand = set(range(N))
while True:
    answer += 1
    x,cand = f(cand)
    if x == 0:
        answer = -1
        break
    rest -= x
    if rest == 0:
        break
    
print(answer)
### BUGGY CODE ###

count = int(input())
zenbu = []

for x in range(count):
    keihin = input()

    if not keihin in zenbu:
        zenbu.append(keihin)
print(len(zenbu))
        


### FIXED CODE ###

count = int(input())
zenbu = set()
 
for x in range(count):
    keihin = input()
    zenbu.add(keihin)
print(len(zenbu))
### BUGGY CODE ###

n, m = map(int, input().split())
par = [-1 for i in range(n)]  # 親だった場合は-(その集合のサイズ)


# xがどのグループに属しているか調べる
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return find(par[x])


# 自分のいるグループの数
def size(x):
    return -par[find(x)]


# xとyの属する集合を併合
def unite(x, y):
    # 根を探す
    x, y = find(x), find(y)

    # 根が一緒
    if x == y:
        return

    # 大きい方に小さい方をくっつける
    if size(x) < size(y):
        x, y = y, x

    # xのサイズを更新
    par[x] += par[y]
    # yの親をxにする
    par[y] = x


# 同じ集合に属するか判定
def same(x, y):
    return find(x) == find(y)


bridges = [list(map(int, input().split())) for _ in range(m)]
bridges.reverse()
huben = n * (n - 1) // 2
ans = []
for i in range(m):
    ans.append(huben)
    a, b = bridges[i]
    a, b = a - 1, b - 1
    if not same(a, b):
        huben -= size(a) * size(b)
    unite(a, b)
for i in range(m):
    print(ans[::-1][i])


### FIXED CODE ###

n, m = map(int, input().split())
par = [-1] * n  # 親だった場合は-(その集合のサイズ)


# xがどのグループに属しているか調べる
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return find(par[x])


# 自分のいるグループの数
def size(x):
    return -par[find(x)]


# xとyの属する集合を併合
def unite(x, y):
    # 根を探す
    x, y = find(x), find(y)

    # 根が一緒
    if x == y:
        return

    # 大きい方に小さい方をくっつける
    if size(x) < size(y):
        x, y = y, x

    # xのサイズを更新
    par[x] += par[y]
    # yの親をxにする
    par[y] = x


# 同じ集合に属するか判定
def same(x, y):
    return find(x) == find(y)


bridges = [list(map(int, input().split())) for _ in range(m)]
bridges.reverse()
huben = n * (n - 1) // 2
ans = []
for i in range(m):
    ans.append(huben)
    a, b = bridges[i]
    a, b = a - 1, b - 1
    if same(a, b):
        continue
    else:
        huben -= size(a) * size(b)
        unite(a, b)
ans = ans[::-1]
for i in range(m):
    print(ans[i])
### BUGGY CODE ###

n,m = map(int,input().split())
a = [0 for _ in range(m)]
b = [0 for _ in range(m)]

for i in range(m):
    a[i],b[i] = map(int,input().split())

go = []

for i in range(len(a)):
    if (a[i] == 1):
        go.append(b[i])

for i in range(len(go)):
    for j in range(len(a)):
        if(go[i] == a[j]):
            if(b[j] == n):
                print("POSSIBLE")
                exit()

print("IMPOSSIBLE")

### FIXED CODE ###

n,m = map(int,input().split())
a = [0 for _ in range(m)]
b = [0 for _ in range(m)]

for i in range(m):
    a[i],b[i] = map(int,input().split())

go = []
goal = []

for i in range(len(a)):
    if a[i] == 1:
        go.append(b[i])
    if b[i] == n:
        goal.append(a[i])

count = [0 for i in range(n)]
for i in range(len(go)):
    count[go[i]-1] = 1
for i in range(len(goal)):
    count[goal[i]-1] += 1
for i in range(len(count)):
    if count[i] > 1:
        print("POSSIBLE")
        exit()
print("IMPOSSIBLE")
### BUGGY CODE ###

from collections import Counter,deque
def bfs(G,s,N):
    dist=[-1]*(N+1)
    d=deque()
    dist[s]=0
    d.append(s)
    while(len(d)!=0):
        v=d[0]
        d.popleft()
        for nv in G[v]:
            if(dist[nv]!=-1):
                continue
            #発見した地点への操作
            dist[nv]=dist[v]+1
            d.append(nv)
            #ここまで
    return dist

N,X,Y=map(int,input().split())
G=[[] for i in range(N+1)]
for i in range(1,N):
    G[i].append(i+1)
    G[i+1].append(i)
G[X].append(Y);G[Y].append(X)
Count=[0]*(N+1)
for i in range(1,N+1):
    li=bfs(G,i,N)
    c=Counter(li)
    for i in range(1,N+1):
        Count[i]+=c[i]
for i in range(1,N):
    print(Count[i]//2)


### FIXED CODE ###

from collections import Counter,deque
def bfs(G,s,N):
    dist=[-1]*(N+1)
    d=deque()
    dist[s]=0
    d.append(s)
    while(len(d)!=0):
        v=d[0]
        d.popleft()
        for nv in G[v]:
            if(dist[nv]!=-1):
                continue
            #発見した地点への操作
            dist[nv]=dist[v]+1
            d.append(nv)
            #ここまで
    return dist

N,X,Y=map(int,input().split())
G=[[] for i in range(N+1)]
for i in range(1,N):
    G[i].append(i+1)
    G[i+1].append(i)
G[X].append(Y);G[Y].append(X)
Count=[0]*(N+1)
for i in range(1,N+1):
    li=bfs(G,i,N)
    c=Counter(li)
    for i in range(1,N+1):
        Count[i]+=c[i]
for i in range(1,N):
    print(Count[i]//2)
### BUGGY CODE ###

from bisect import bisect_left
N = int(input())
L = [int(x) for x in input().split()]
L.sort()
ans = 0
for a in range(N-2):
    for b in range(a+1, N-1):
        ans += bisect_left(L[b+1:], L[a]+L[b])
print(ans)

### FIXED CODE ###

from bisect import bisect_left
N = int(input())
L = [int(x) for x in input().split()]
L.sort()
ans = 0
for a in range(N-2):
    for b in range(a+1, N-1):
        ans += bisect_left(L[b+1:], L[a]+L[b])
print(ans)
### BUGGY CODE ###

n, m = map(int, input().split())
a = [None]*m
c = [0]*m
for i in range(m):
    a[i], b = map(int, input().split())
    ls = list(map(int,input().split()))
    for j in ls:
        c[i] |= 1<<(j-1)

dp = [[1e9]*(1<<n) for i in range(m+1)]
dp[0][0] = 0
for i in range(m):
    for S in range(1<<n):
        dp[i+1][S] = min(dp[i+1][S], dp[i][S])
        dp[i+1][S|c[i]] = min(dp[i+1][S|c[i]], dp[i][S]+a[i])
if dp[m][(1<<n)-1] < 1e9:
    print(dp[m][(1<<n)-1])
else:
    print(-1)

### FIXED CODE ###

n, m = map(int, input().split())
a = [None]*m
c = [0]*m
for i in range(m):
    a[i], b = map(int, input().split())
    ls = list(map(int,input().split()))
    for j in ls:
        c[i] |= 1<<(j-1)

dp = [[1e9]*(1<<n) for i in range(m+1)]
dp[0][0] = 0
for i in range(m):
    for S in range(1<<n):
        dp[i+1][S] = min(dp[i+1][S], dp[i][S])
        dp[i+1][S|c[i]] = min(dp[i+1][S|c[i]], dp[i][S]+a[i])
if dp[m][(1<<n)-1] < 1e9:
    print(dp[m][(1<<n)-1])
else:
    print(-1)
### BUGGY CODE ###

for _ in range(int(input())):
    X = input()
    Y = input()
    dp = [[0 for y in range(len(Y)+1)] for x in range(len(X)+1)]
    for x in range(len(X) + 1):
        for y in range(len(Y) + 1):
            if x == 0 or y == 0:
                dp[x][y] = 0
            elif X[x-1] == Y[y-1]:
                dp[x][y] = dp[x-1][y-1] + 1
            else:
                dp[x][y] = max(dp[x-1][y], dp[x][y-1])
    print(dp[-1][-1])


### FIXED CODE ###

def ser(X, Y):
    dp = [[0] * (len(Y)+1) for x in range(len(X)+1)]
    for i, x in enumerate(X, 1):
        tmp = dp[i]
        pre = dp[i-1]
        for j, y in enumerate(Y, 1):
            if x == y:
                tmp[j] = pre[j-1] + 1
            elif pre[j] < tmp[j-1]:
                tmp[j] = tmp[j-1]
            else:
                tmp[j] = pre[j]
    return(dp[-1][-1])

for _ in range(int(input())):
    X, Y = input(), input()
    print(ser(X, Y))
### BUGGY CODE ###

import sys
from collections import deque
from copy import deepcopy

input=sys.stdin.readline
N=int(input())
a=[0]*(N-1)
b=[0]*(N-1)
c=[set() for _ in range(N)]
d=[set() for _ in range(N)] # 隣接リスト
e=[-1 for _ in range(N)] #訪問ずみかどうか
di=dict()

maxi=0
for i in range(N-1):
    a[i],b[i] = map(int,input().split())
    d[a[i]-1].add(b[i]-1)
    d[b[i]-1].add(a[i]-1)
    maxi=max(maxi,len(d[a[i]-1]),len(d[b[i]-1]))

v=deque([0])
e[0]=0

while len(v)>0:
  k=v.popleft()
  all=set(i+1 for i in range(maxi) )
  pos=deepcopy(all)
  pos -= c[k]
  for item in d[k]:
    if e[item]==-1:
      s=min(pos)
      c[k].add(s)
      c[item].add(s)
      pos.remove(s)
      e[item] = e[k]+1
      v.append(item)
      st=str(k)+","+str(item)
      di[st] = s
    
print(maxi)
for i in range(N-1):
  t_str = str(a[i]-1)+","+str(b[i]-1)
  print(di[t_str])

### FIXED CODE ###

from collections import deque

N=int(input())
a=[0]*(N-1)
b=[0]*(N-1)
c=[set() for _ in range(N)] # 使用している色
d=[set() for _ in range(N)] # 隣接リスト
e=[ False for _ in range(N)] #訪問ずみかどうか
f=[0]*N  #答え
for i in range(N-1):
    a[i],b[i] = map(int,input().split())
    d[a[i]-1].add(b[i]-1)
    d[b[i]-1].add(a[i]-1)

maxi=max([len(d[i]) for i in range(N-1)])
print(maxi)
#print("c:",c)
#print("d",d)
#print("e",e)

#x=0としてBFSする

v=deque([0])
e[0]=True
color=1

while v:
  p = v.popleft()
  for q in d[p]:
    if e[q]==False:
      while color in c[p]:
        color +=1
        if color>maxi:
          color=1
      c[p].add(color)
      c[q].add(color)
      f[q]=color
      e[q]=True
      v.append(q)
      
for i in range(N-1):
  print( f[b[i]-1])
### BUGGY CODE ###

# D
N, M = map(int, input().split())
a_list = list(map(int, input().split()))

G = dict()
for i in range(N):
    G[i] = []

for _ in range(M):
    x, y = map(int, input().split())
    G[x].append(y)
    G[y].append(x)
    
res = 0
connec = 0
done_list = [0]*N
conn_list = []

st = 0
while True:
    while st < N:
        if done_list[st] == 0:
            break
        st += 1

    if st == N:
        break

    queue = [st]
    conn = [a_list[st]]
    done_list[st] = 1
    connec += 1

    while len(queue) > 0:
        s = queue.pop()
        for t in G[s]:
            if done_list[t] == 0:
                done_list[t] = 1
                queue.append(t)
                conn.append(a_list[t])
                
    conn_ = sorted(conn, reverse=True)
    res += conn_.pop()
    conn_list = conn_list + conn_

conn_list_ = sorted(conn_list)

if connec == 1:
    print(0)
elif len(conn_list_) < connec - 2:
    print('Impossible')
else:
    print(res + sum(conn_list_[:(connec - 2)]))


### FIXED CODE ###

# D
import numpy as np

N, M = map(int, input().split())
a_list = list(map(int, input().split()))

G = dict()
for i in range(N):
    G[i] = []

for _ in range(M):
    x, y = map(int, input().split())
    G[x].append(y)
    G[y].append(x)
    
res = 0
connec = 0
done_list = [0]*N

st = 0
while True:
    while st < N:
        if done_list[st] == 0:
            break
        st += 1

    if st == N:
        break

    queue = [st]
    conn = [a_list[st]]
    conn_ = [st]
    done_list[st] = 1
    connec += 1

    while len(queue) > 0:
        s = queue.pop()
        for t in G[s]:
            if done_list[t] == 0:
                done_list[t] = 1
                queue.append(t)
                conn.append(a_list[t])
                conn_.append(t)
                
    args = np.argsort(conn)
    res += conn[args[0]]
    a_list[conn_[args[0]]] = 2000000000

a_list.sort()

if connec == 1:
    print(0)
elif len(a_list) < 2*connec - 2:
    print('Impossible')
else:
    print(res + sum(a_list[:(connec - 2)]))
### BUGGY CODE ###

N = int(input())
S = input()
s = list(S)
r = 0
g = 0
b = 0
for i in range(N):
    if s[i] == 'R':
        r = r + 1
    if s[i] == 'G':
        g = g + 1
    if s[i] == 'B':
        b = b + 1
p = 0
for i in range(N-1):
    for j in range(i+1,N):
        if 2*j-i < N:
            if s[j+j-i] != s[i] and s[j+j-i] != s[j] and s[i] != s[j]:
                p = p+1
print(r*g*b-p)

### FIXED CODE ###

N = int(input())
S = input()
s = list(S)
r = 0
g = 0
b = 0
for i in range(N):
    if s[i] == 'R':
        r = r + 1
    if s[i] == 'G':
        g = g + 1
    if s[i] == 'B':
        b = b + 1
p = 0
for i in range(N-1):
    for j in range(i+1,N):
        if 2*j-i < N:
            if s[2*j-i] == s[i] or s[2*j-i] == s[j] or s[i] == s[j]:
                p = p
            else:
                p = p+1
        else:
            break
print(r*g*b-p)
### BUGGY CODE ###

# -*- coding: utf-8 -*-
import itertools
N,M,Q=map(int,input().split())
abcd=[]
for _ in range(Q):
    abcd.append(list(map(int,input().split())))
Abase=[]
for a in range(1,M+1):
    Abase.append(a)
Abase=Abase*N
A=list(itertools.combinations(Abase,N))
A2=[sorted(x) for x in A]
ans=0
for i in A2:
    temp=0
    for j in abcd:
        if i[j[1]-1]-i[j[0]-1]==j[2]:
            temp=temp+j[3]
    if temp>=ans:
        ans=temp
print(ans)

### FIXED CODE ###

# -*- coding: utf-8 -*-
import itertools
N,M,Q=map(int,input().split())
abcd=[]
for _ in range(Q):
    abcd.append(tuple(map(int,input().split())))
Abase=[]
for a in range(1,M+1):
    Abase=Abase+[a]
A=set(itertools.combinations_with_replacement(Abase,N))
ans=0
for i in A:
    temp=0
    for j in abcd:
        if i[j[1]-1]-i[j[0]-1]==j[2]:
            temp=temp+j[3]
    if temp>=ans:
        ans=temp
print(ans)
### BUGGY CODE ###

vs = set()
def dfs_w(d, stack):
    S, F, depth, depthh = [], [None]+[0]*N, [-1] + [0]*N, [0] + [0]*N
    path = [0]
    pvs = set()
    if stack[0] in vs:
        return True
    while stack:
        v, dpd = stack.pop()
        if v > 0:
            parent = path[-1]
            path.append(v)
            vs.add(v)
            pvs.add(v)

            F[v] = len(S)
            depth[v], depthh[v] = depth[parent] + 1, depthh[parent] + dpd

            S.append(v)
            for u, dpd in d[v]:
                if u in pvs:
                    if depthh[u] != depthh[v] + dpd:
                        return False
                if u in vs:
                    continue
                stack += [(-v, dpd), (u, dpd)]
        else:
            path.pop()
            S.append(v)

    return True
#    return S, F, depth, depthh

if __name__ == '__main__':
    N, M = map(int, input().split())
    G = [set() for _ in range(N+1)]
    for _ in range(M):
        a, b, c = map(int, input().split())
        G[a].add((b,c))
        G[b].add((a,-c))
    for i in range(N):
        stack = [(i+1, 0)] 
        r =  dfs_w(G, stack)
        if not r:
            break
    if r:
        print("Yes")
    else:
        print("No")


### FIXED CODE ###

import sys
input = sys.stdin.readline
vs = set()
def dfs_w(d, stack):
    depth = defaultdict(int)
    pvs = set()
    while stack:
        v = stack.pop()
        vs.add(v)
        pvs.add(v)
        for u, dpd in d[v]:
            if u in pvs:
                if depth[u] != depth[v] + dpd:
                    return False
            if u in vs:
                continue
            depth[u] = depth[v] + dpd
            stack.append(u)
    return True

if __name__ == '__main__':
    from collections import defaultdict
    N, M = map(int, input().split())
    G = defaultdict(set)
    for _ in range(M):
        a, b, c = map(int, input().split())
        G[a].add((b,c))
        G[b].add((a,-c))
    for i in range(N):
        if i+1 in vs:
            continue
        stack = [i+1] 
        r =  dfs_w(G, stack)
        if not r:
            break
    if r:
        print("Yes")
    else:
        print("No")
### BUGGY CODE ###

N=int(input())
S=["" for i in range(N)]

for i in range(N):
    S[i]=input()

count=0

for l in range(N):
    JUDGE=1
    for j in range(N):
        for k in range(j+1,N):
            
            kk=(k-l)%N
            jj=(j-l)%N
            if S[j][kk]!=S[k][jj]:
                JUDGE=0
                break
        if JUDGE==0:
            break

    if JUDGE==1:
        count+=1

print(count*N)

### FIXED CODE ###

N=int(input())
S=["" for i in range(N)]

for i in range(N):
    S[i]=input()

count=0

for l in range(N):
    JUDGE=1
    for j in range(N):
        for k in range(j+1,N):
            
            if S[j][k-l]!=S[k][j-l]:
                JUDGE=0
                break
        if JUDGE==0:
            break

    if JUDGE==1:
        count+=1

print(count*N)