using
System;
using
System.Collections.Generic;
class
ComputeHash
{
private
List<
long
> hash;
private
List<
long
> invMod;
private
long
mod;
private
long
p;
public
ComputeHash(
string
s,
long
p,
long
mod)
{
int
n = s.Length;
this
.hash =
new
List<
long
>(n);
this
.invMod =
new
List<
long
>(n);
this
.mod = mod;
this
.p = p;
long
pPow = 1;
long
hashValue = 0;
for
(
int
i = 0; i < n; i++)
{
char
c = s[i];
c = (
char
)(c -
'A'
+ 1);
hashValue = (hashValue + c * pPow) %
this
.mod;
this
.hash.Add(hashValue);
this
.invMod.Add(ModularInverse(pPow,
this
.mod));
pPow = (pPow *
this
.p) %
this
.mod;
}
}
private
long
ModularInverse(
long
a,
long
m)
{
long
m0 = m, t, q;
long
x0 = 0, x1 = 1;
if
(m == 1)
return
0;
while
(a > 1)
{
q = a / m;
t = m;
m = a % m;
a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
if
(x1 < 0)
x1 += m0;
return
x1;
}
public
long
GetHash(
int
l,
int
r)
{
if
(l == 0)
{
return
this
.hash[r];
}
long
window = (
this
.hash[r] -
this
.hash[l - 1] +
this
.mod) %
this
.mod;
return
(window *
this
.invMod[l]) %
this
.mod;
}
}
class
LongestCommonSubstring
{
private
static
bool
Exists(
int
k,
string
X,
string
Y,
ComputeHash hashX1, ComputeHash hashX2,
ComputeHash hashY1, ComputeHash hashY2)
{
for
(
int
i = 0; i <= X.Length - k; i++)
{
for
(
int
j = 0; j <= Y.Length - k; j++)
{
if
(X.Substring(i, k) == Y.Substring(j, k))
{
return
true
;
}
}
}
return
false
;
}
private
static
int
LongestCommonSubstr(
string
X,
string
Y)
{
int
n = X.Length;
int
m = Y.Length;
long
p1 = 31;
long
p2 = 37;
long
m1 = (
long
)Math.Pow(10, 9) + 9;
long
m2 = (
long
)Math.Pow(10, 9) + 7;
ComputeHash hashX1 =
new
ComputeHash(X, p1, m1);
ComputeHash hashX2 =
new
ComputeHash(X, p2, m2);
ComputeHash hashY1 =
new
ComputeHash(Y, p1, m1);
ComputeHash hashY2 =
new
ComputeHash(Y, p2, m2);
int
low = 0, high = Math.Min(n, m);
int
answer = 0;
while
(low <= high)
{
int
mid = (low + high) / 2;
if
(Exists(mid, X, Y, hashX1, hashX2, hashY1, hashY2))
{
answer = mid;
low = mid + 1;
}
else
{
high = mid - 1;
}
}
return
answer;
}
static
void
Main()
{
string
X =
"GeeksforGeeks"
;
string
Y =
"GeeksQuiz"
;
Console.WriteLine(LongestCommonSubstr(X, Y));
}
}