#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int M =1e6+20;
int len,len1,len2;
char s[M];
int sa[M];//sa[i]排名i的后缀编号
int c[M];//计数数组 c[i]=j表示关键字<=i的有j个
int t1[M],t2[M];
void SA(char *s,int n,int m) //n为strlen(s)+1; m为最大字符的ascii码值
{
int *x=t1;//x[i]=j表示后缀i的排名 (每一轮的rank)
int *y=t2;//y[p]=i;后缀i的第二关键字排名为p
int i;
for(i=0;i<m;i++)
c[i]=0;
for(i=0;i<n;i++)
{
c[x[i]=s[i]]++;//长度为1时 x[i]的排名就为该字符ascii值
}
for(i=1;i<m;i++)
c[i]+=c[i-1];
for(i=n-1;i>=0;i--)//长度(1)的名次数组
sa[--c[x[i]]]=i;//aabaaaab 若x[i]值相同的sa靠前的小
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(i=n-k;i<n;i++)
y[p++]=i;//第二关键字为0的排前面
for(i=0;i<n;i++)
{
//倍增:x+k后缀的第一关键字排名等于x后缀的第二关键字排名
if(sa[i]>=k)//只有编号大于k的才能作为第二关键字
{
y[p++]=sa[i]-k;
}
}
//通过x[],y[]计算每个后缀的长为2*k前缀的sa数组
for(i=0;i<m;i++)
c[i]=0;
for(i=0;i<n;i++)
c[x[y[i]]]++;//第二关键字排名为i的后缀y[i]的第一关键字排名
//此时c[p]的值表示第一关键字排名为p的有多少个
for(i=1;i<m;i++)
c[i]+=c[i-1];// 此时c[i]:第一关键字的排名为i时,小于等于它的个数
for(i=n-1;i>=0;i--)
sa[--c[x[y[i]]]]=y[i];//后缀y[i]在它的2*k长度中排名为?
//后缀y[i]的第一关键字排名为c[x[y[i]]] 第一关键字相同时 此时看第二关键字
//y[i]中i越小 第二关键字排名就越小 后缀y[i]排名就越小 (逆推的原因)
//接着更新x为长度2*k的名次数字
swap(x,y);//令y表示名次数组(rank)
p=1;//此时p记录排名的不同的个数
x[sa[0]]=0;
for(i=1;i<n;i++)
{
x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;
//两个关键字相同则在x数组的排名是一样的
//y[sa[i]]==y[sa[i-1]],即这两个后缀的长k的第一关键字相同的情况下
//他们必定还存在第二关键需要比较
}
if(p>=n) break;//字典序比较法得出 当前排名都不同时,最终排名就为此排名
m=p; //
}
}
int rank[M],height[M];//设 height[i]=LCP(Suffix(sa[i]),Suffix(sa[i-1]))后缀排名为i和i-1的LCP
//则 h[i]=height[rank[i]]= 后缀i和它前一个后缀的 LCP
//h[i]>=h[i-1]-1
//h[i-1]为后缀i-1和它排在它前一个的后缀k的LCP
//同时去掉相同的首字符之后 后缀k+1和和后缀i的LCP为h[i]=h[i-1]-1
//因为后缀k+1和后缀i名次不一定相邻 所以若存在后缀t为后缀i相邻 则h[i]>=h[i]-1;
void Height()
{
int i,j,k=0;
for(i=0;i<len;i++)
rank[sa[i]]=i;
for(i=0;i<len;i++)
{
if(k)
k--;//h[i]>=h[i-1]-1;先减一
int j=sa[rank[i]-1];//前一个后缀
while(s[i+k]==s[j+k])
k++;
height[rank[i]]=k;
}
}
void solve()
{
int ans=0;
for(int i=2;i<len;i++)
{
if(height[i]>ans)
{
//后缀sa[i]和sa[i-1]不能在同一个串中
if(sa[i-1]>=0&&sa[i-1]<len1&&sa[i]>len1&&sa[i]<len)
{
ans=height[i];
}
if(sa[i]>=0&&sa[i]<len1&&sa[i-1]>len1&&sa[i-1]<len)
{
ans=height[i];
}
}
}
printf("%d\n",ans);
}
int main()
{
scanf("%s",s);
len1=strlen(s);
s[len1]=1;//分隔符
scanf("%s",s+len1+1);//拼接两个粗串
len2=strlen(s)-len1-1;
s[len1+len2+1]=0;//末尾
len=len1+len2+2;
SA(s,len,128);
Height();
solve();//求两个串的最长公共字串
//首先如果这两个长字符串存在某个最长的公共子串,那么该子串一定分别是这两个串的后缀的前缀.
//将两个串拼接起来求最大的LCP&&两个后缀不属于同一个串
return 0;
}