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 <bits/stdc++.h>
using namespace std;
#define int long long

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,int> plli;
typedef pair<int,pii> pipii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;

#define rep(i,n) for (int i=0;i<(n);i++)
#define rep2(i,a,b) for (int i=(a);i<(b);i++)
#define rrep(i,n) for (int i=(n);i>0;i--)
#define rrep2(i,a,b) for (int i=(a);i>b;i--)
#define pb push_back
#define fi first
#define se second
#define all(a) (a).begin(),(a).end()

const ll mod = 1e9 + 7;
const ll INF = 1<<30;
const int dx4[4] = {1, 0, -1, 0};
const int dy4[4] = {0, 1, 0, -1};
const int dx8[8] = {1, 1, 1, 0, 0, -1, -1, -1};
const int dy8[8] = {0, 1, -1, 1, -1, 0, 1, -1};
const double pi = 3.141592653589793;

string s, t;

signed main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    while (cin >> s >> t) {
        int ssize = s.length();
        int tsize = t.length();
        set<string> st;
        map<string, int> mst;
        rep(i, ssize){
            string tmp = "";
            rep2(j, i, ssize) {
                tmp += s[j];
                mst[tmp] += 1;
                st.insert(tmp);
            }
        }
        rep(i, tsize){
            string tmp = "";
            rep2(j, i, tsize) {
                tmp += t[j];
                mst[tmp] += 1;
                st.insert(tmp);
            }
        }
        int ans = 0;
        for(auto itr = st.begin(); itr != st.end(); ++itr) {
            string common = *itr;
            if (mst[common] >= 2) {
                int le = common.length();
                ans = max(ans, le);
            }
        }
        cout << ans << endl;
    }
}

C++: #include <cstdio>
int dp[4001][4001][6];
int main(){
return 0;
}

C++: #include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef double db;
ll n,k;
ll rank[200010];
ll tmp[200010];

bool compare_sa(ll i,ll j){
	if(rank[i]!=rank[j]) return rank[i] < rank[j];
	else{
		ll ri=(((i+k)<=n)?rank[i+k]:-1);
		ll rj=(((j+k)<=n)?rank[j+k]:-1);
		return ri<rj;
	}
}

void construct_sa(string S,ll *sa){
	n=S.length();
	for(ll i=0;i<=n;i++){
		sa[i]=i;
		rank[i]=i<n?S[i]:-1;
	}
	
	for(k=1;k<=n;k*=2){
		sort(sa,sa+n+1,compare_sa);
		
		tmp[sa[0]]=0;
		for(ll i=1;i<=n;i++){
			tmp[sa[i]]=tmp[sa[i-1]]+(compare_sa(sa[i-1],sa[i])?1:0);
		}
		for(ll i=0;i<=n;i++){
			rank[i]=tmp[i];
		}
	}
}

void construct_lcp(string S,ll *sa,ll *lcp){
	ll h=0;
	lcp[0]=0;
	//for(ll i=0;i<=n;i++) rank[sa[i]]=i;
	for(ll i=0;i<n;i++){
		ll j=sa[rank[i]-1];
		if(h>0) h--;
		for(;j+h<n&&i+h<n;h++){
			if(S[j+h]!=S[i+h]) break;
		}
		lcp[rank[i]-1]=h;
	}
}

ll sa[100000];
ll lcp[100000];
int main()
{
	string S,T;
	ll sl;
	ll ans;
	while(cin>>S>>T){
	ans=0;
	sl=S.length();
	S+="$"+T;
	construct_sa(S,sa);
	construct_lcp(S,sa,lcp);
	for(ll i=0;i<S.length();i++){
		if((sa[i]<sl)!=(sa[i+1]<sl)){
			ans=max(ans,lcp[i]);
		}
	}
	cout<<ans<<endl;
}}

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

using namespace std;

int main(){
  string s,t,u;
  while(cin>>s>>t){
    u=(s.size()>t.size())?t:s;
    if(s==u) s=t;
    int c=u.size();
    int a=0,b=0;
    for(int i=0;i<c;++i){
      for(int j=0;j<s.size();++j){
	if(u[(j+i)%c]==s[j]){
	  ++b;
	  if((i+j)%c==c-1){
	    a=max(a,b);b=0;
	  }
	}
	else{
	  a=max(a,b);b=0;
	}
      }
      a=max(a,b);b=0;
    }
    cout<<a<<endl;
  }
  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[6200000]={}, 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;
}

C++: 
//08-2 共通部分文字列
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<time.h>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<stack>
#include<cstdlib>
#include<algorithm>
#include<random>
#include<cassert>
using namespace std;
#define LL long long
#define INT_MIN -2147483648
#define INT_MAX 2147483647
#define LL_MIN -9223372036854775808
#define LL_MAX 9223372036854775807
#define ROOP() while(true)

int main(){
	ROOP(){
		string A,B;
		cin >> A;
		if(cin.eof()) { break; }
		cin >> B;
		if(B.size() > A.size()){//Aのほうが長い
			string tmp = B;
			 B = A;
			 A = tmp;
		}
		string t = "";
		for(int i=0; i<B.size(); i++){
			t += ".";
		}
		A = t + A;

		int ans = 0;
		while(A.size()>0){
			int tmp = 0;
			for(int j=0; j<min(A.size(),B.size()); j++){
				if(A[j]==B[j]){
					tmp++;
					ans = max(ans,tmp);
				}
				else tmp = 0;
			}
			A.erase(A.begin());
		}
		cout << ans << endl;
	}

	return 0;
}