Go: ///
// File:  0528.go
// Author: ymiyamoto
//
// Created on Thu Mar 22 01:52:09 2018
//
package main

import (
	"bufio"
	"fmt"
	"os"
)

var S, T string

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	for {
		scanner.Scan()
		S = scanner.Text()
		if len(S) == 0 {
			return
		}

		scanner.Scan()
		T = scanner.Text()

		dp := make([][]int, len(S)+1)
		for i := range dp {
			dp[i] = make([]int, len(T)+1)
		}

		dp[0][0] = 0
		for i := range S {
			for j := range T {
				if S[i] == T[j] {
					dp[i+1][j+1] = max(dp[i+1][j], max(dp[i][j+1], dp[i][j]+1))
				} else {
					dp[i+1][j+1] = 0
				}
			}
		}
		var m int
		for i := range dp {
			for j := range dp[i] {
				m = max(m, dp[i][j])
			}
		}
		fmt.Println(m)
	}
}

C++: #include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int check(string, string);

int main()
{
  string str1, str2;
  while( cin >> str1 >> str2 ){

    int res = 0;

    for(int i = 0; i < str1.size(); i++){
      if(str1.size() > str2.size())
	rotate(str1.begin(), str1.begin() + 1, str1.end());
      else
	rotate(str1.begin(), str1.begin() + 1, str1.end());
      res = max(res, check(str1, str2));
    }

    cout << res << endl;
  }
}

int check(string str1, string str2)
{
  int sn = 0, res = 0;
  for(int i = 0; i < min(str1.size(), str2.size()); i++){
    if(str1[i] == str2[i])
      sn++;
    else{
      res = max(res, sn);
      sn = 0;
    }
  }
  return res;
}

C++: #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[4001][4001]={};
char str1[4005],str2[4005];
int ans=0;
int main(){while(scanf("%s%s",str1,str2)!=-1){
  for(int i=0;i<strlen(str1);i++){
    for(int j=0;j<strlen(str2);j++){
      if(str1[i]==str2[j]){
         if(i==0 || j==0){ dp[i][j]=1;ans=max(ans,1);}
         else{ dp[i][j]=1+dp[i-1][j-1];ans=max(ans,dp[i][j]);}
      }}}printf("%d\n",ans); }return 0;}

C++: #include<cstdio>
#include <iostream>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#include<functional>
#include<cmath>
#include<map>
#include<stack>
#include<cstdlib>
#include<list>
#include<set>
#include<numeric>

#define MOD 1000000007

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int main()
{
	string s1, s2;
	while (cin >> s1 >> s2) {
		string s3;
		int ans = 0;
		for (int i = 0; i < s1.size(); i++) {
			for (int j = i; j < s1.size(); j++) {
				for (int k = i; k < j + 1; k++) {
					s3 += s1[k];
				}
				int pos = s2.find(s3);
				int s = s3.size();
				if (pos != -1)ans = max(ans, s);
				s3 = "";
			}
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #include<stdio.h>
#include<string.h>

char A[4002],B[4002];

int seach(int atop,int lenA,int lenB){
	int i,count,max = 0;
	int acor;
	for(i = 0;i < lenB && max < lenA-atop;i++){
		acor = 0;
		count = 1;
		for(;i < lenB && count < lenA-atop;i++){
			if(A[acor+atop] == B[i]){
				count++;
				acor++;
			}
			else{
				break;
			}
		}
		if(max < count)
			max = count;
	}
	return max;
}
int main(){
	int i,j,lenA,lenB,kyotu;
	int max[1000] = {0},mcor = 0;
	while(1){
		if(scanf("%s%s",A,B) == -1){
			break;
		}
		lenA = strlen(A);
		lenB = strlen(B);
		for(i = 0;i < lenA;i++){
			kyotu = seach(i,lenA,lenB);
			//printf("kyotu = %d\n",kyotu);
			if(max[mcor] < kyotu)
				max[mcor] = kyotu;
		}
		mcor++;
	}
	for(i = 0;i < mcor;i++){
		printf("%d\n",max[i]);
	}
	return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
#include<fstream>
using namespace std;
typedef long long int ll;

int main()
{
	
   string s1,s2;
	int dp[4001][4001];
	for(int i=0;i<=400;i++){
		dp[i][0]=0;
		dp[0][i]=0;
	}
	while(	cin >> s1 >> s2){
		int ans=0;
		for(int i=1;i<=s1.length();i++){
			for(int j=1;j<=s2.length();j++){
				if(s1[i-1]==s2[j-1]){
					dp[i][j]=dp[i-1][j-1]+1;
				}
				else dp[i][j]=0;
				ans=max(ans,dp[i][j]);
			}
		}
cout << ans << "\n";
	}
    return 0;
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <functional>
#include <numeric>
#define rep(i,a) for( int i = 0; i != (a); ++i )
#define repd(i,a) for( int i = (a); i >= 0; --i )
#define repi(i,a,b) for( int i = (a); i != (b); ++i )
using namespace std;
typedef unsigned long long ull;

int n, m;
std::string s, t;
int dp[4001][4001];

void solve(){
	memset(dp, 0, sizeof(dp));
	int ans = 0;
	for (int i = 0; i < n; ++i){
		for (int j = 0; j < m; ++j){
			if (s[i] == t[j]){
				dp[i + 1][j + 1] = dp[i][j] + 1;
				ans = max(dp[i + 1][j + 1], ans);
			}
			else{
				dp[i + 1][j + 1] = 0;
			}
		}
	}
	std::cout << ans << endl;
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	while (std::cin >> s >> t){
		n = s.size(), m = t.size();
		solve();
		
	}
	//std::cout << '\n';
	//system("pause");
	return 0;

}

//1000000000000000000

C++: class Main{

}

C++: #include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int zo[2][4010]={};
int dp[2][4010];
char ar1[4010],ar2[4010];
int main(){
	int l1,l2,I,O,hog,cnt;
	while(true){
		cin>>ar1;
		if(cin.eof()) break;
		cin>>ar2;
		l1=strlen(ar1);
		l2=strlen(ar2);
		I=1;O=0;
		memset(zo[I],0,sizeof(zo[I]));
		memset(dp[I],0,sizeof(dp[I]));
		cnt=0;
		for(int i=0;i<l1;i++){
			for(int j=0;j<l2;j++){
				if(ar1[i]==ar2[j]){
					if(i!=0&&j!=0){
						zo[O][j]=zo[I][j-1]+1;
					}
					else{
						zo[O][j]=1;
					}
				}
				else{
					zo[O][j]=0;
				}
			}
			for(int j=0;j<l2;j++){
				cnt=max(cnt,zo[O][j]);
			}
			swap(I,O);
		}
		cout<<cnt<<endl;
	}
	return 0;
}

C++: #include<iostream>
#include<string>
#include<algorithm>
using namespace std;

string str1;
string str2;
int solve(){
    int count=0;
    int m=0;
    int limit1;
    int limit2;
    int limit;
    limit1 = str1.size();
    limit2 = str2.size();
    for(int i=0;i<limit2;i++){
        if(limit1-i<limit2){
            break;
        }else{
            limit = limit1-1;
        }
        for(int j=0;j<limit;j++){
            if(str1[j+i] == str2[j]){
                count++;
            }else{
                m = max(m, count);
                count = 0;
            }
        }
    }
    count = 0;
    for(int i=0;i<limit2;i++){
        limit = limit1+i<limit2 ? limit1+i : limit2;
        for(int j=i;j<limit;j++){
            if(str1[j-i] == str2[j]){
                count++;
            }else{
                m = max(m, count);
                count = 0;
            }
        }
    }
    return m;
}
int main(){
    string temp;
    while(cin >> str1 >> str2){
        if(str1.size() > str2.size()){
            temp = str1;
            str1 = str2;
            str2 = temp;
        }
        cout << solve() << endl;
    }
}

C++: #include<cstdio>
char c[4001],d[4001],*a,*b;
int main(){
	while(~scanf("%s%s",c,d)){
		int mx=0,o,i,k,s;
		for(a=c,b=d,k=0;k++<2;a=d,b=c)for(o=0;a[o];o++)for(i=s=0;a[i+o]&&b[i];i++){
			if(a[i+o]==b[i]){
				s++;
				if(mx<s)mx=s;
			}
			else s=0;
		}
		printf("%d\n",mx);
	}
	return 0;
}

C++: //JOI 0528 Common Sub-String
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
	while(1){
		string s, t; int roop1=0, roop2 = 0, save[300000]={}, ans = 0;
		cin>>s;
		cin>>t;
		if(cin.eof())
		break;
	for (int i = 0; i<s.size(); i++){
		for (int j = 0; j<t.size(); j++){
			if (s[i] == t[j]){
				roop1 = 0;
				save[roop2] = 0;
				while (1){
					if (s[i + roop1] == 0 || t[j + roop1] == 0){
						break;
					}
					else{
						if (s[i + roop1] == t[j + roop1]){
							save[roop2] += 1;
							roop1++;
						}
						else if (s[i + roop1] != t[j + roop1]){
							roop2++;
							break;
						}
					}
				}
			}
		}
	}
	sort(save, save + roop2 + 1);
	ans = save[roop2];
	cout << ans << endl;
	}
	return 0;
}