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
var dp [4001][4001]int

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()

		for i := range dp {
			for j := range dp[i] {
				dp[i][j] = 0
			}
		}

		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 <vector>
# include <string>
# include <set>
# include <map>
# include <cmath>
# include <iomanip>
# include <functional>
# include <utility>
# include <stack>
# include <queue>
# include <list>
# include <tuple>
# include <unordered_map>
# include <numeric>
# include <complex>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
constexpr int INF = 2000000000;
constexpr int HINF = INF / 2;
constexpr double DINF = 100000000000000000.0;
constexpr long long LINF = 9223372036854775807;
constexpr long long HLINF = 4500000000000000000;
const double PI = acos(-1);
int dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };
# define ALL(x)     (x).begin(),(x).end()
# define UNIQ(c)    (c).erase(unique(ALL((c))), end((c)))
# define mp         make_pair
# define eb         emplace_back
# define FOR(i,a,b) for(int i=(a);i<(b);++i)
# define REP(i,n)   FOR(i,0,n)
# define INIT       std::ios::sync_with_stdio(false);std::cin.tie(0);


int main() {

	string s, t;
	while (cin >> s >> t) {
		int dp[4040][4040] = {};
		for (int i = 1; i <= s.size(); i++) {
			for (int j = 1; j <= t.size(); j++) {
				if (s[i - 1] == t[j - 1]) {
					dp[i][j] = dp[i - 1][j - 1] + 1;
				}
			}
		}

		int ans = 0;
		for (int i = 0; i < s.size() + 1; i++) {
			for (int j = 0; j < t.size() + 1; j++) {
				ans = max(ans, dp[i][j]);
			}
		}
		cout << ans << endl;

		return 0;
	}
}

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

int dp[4005][4005];

int main() {
	string s;
	while (cin >> s) {
		string sa;
		cin >> sa;
		for (int i = 0; i < 4003; i++)
			for (int j = 0; j < 4003; j++)dp[i][j] = 0;
		s.push_back('@');
		int ans = 0;
		for (int i = 0; i < s.size(); i++) {
			for (int j = 0; j < sa.size(); j++) {
				int a = s.size();
				int I = min(a-1, i + j);
				if (s[I] == sa[j]) {
					dp[i][j + 1] = dp[i][j] + 1;
					ans = max(ans, dp[i][j + 1]);
				}
				else dp[i][j + 1] = 0;
			}
		}
		cout << ans << endl;
	}
	return 0;
}

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

int main(){
	set< deque<char> > e;
	e.insert(deque<char>(0));
	string a,b;
	cin >> a >> b;
	if( a.length() > b.length() )swap(a,b);
	
	for(int i = 0 ; i < b.length() ; i++){
		deque<char> s;
		for(int j = i ; j < b.length() ; j++){
			s.push_back(b[j]);
			e.insert(s);
		}
	}
	deque<char> cur;
	int l = 0 , r = 0;
	int ans = 0;
	while(r <= a.length() ){
		if( e.find(cur) != e.end() ){
			ans = max<int>(ans,cur.size());
			if(r != a.length())cur.push_back(a[r]);
			r++; 
		}else{
			cur.pop_front();
			l++;
		}
	}
	cout << ans << endl;
}

C++: #include <bits/stdc++.h>
#define ll long long
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 100000005
#define MAX 5001
using namespace std;
//__gcd(a,b), __builtin_popcount(a);

int dp[4001][4001];
int main(){
	string s1, s2;
	while(cin >> s1 >> s2){
	s1 = " " + s1;s2 = " " + s2;
	fill((int*)dp, (int*)(dp+4001), 0);
	int ans = 0;
	for(int i = 1;i < s1.size();i++){
		for(int j = 1;j < s2.size();j++){
			if(s1[i] == s2[j])dp[i][j] = dp[i-1][j-1]+1;
			ans = max(ans, dp[i][j]);
		}
	}
	cout << ans << endl;
	}
	return 0;
}

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

using namespace std;

const int MAX = 4001;

int dp[2][MAX];
string in[2];

void solve(){
  int out = 0;
  for(int i = 0; i < in[0].length(); i++){
    for(int j = 0; j < in[1].length(); j++){
      if(in[0][i] == in[1][j]) dp[(i+1)&1][j+1] = dp[i&1][j]+1;
      out = max(out,dp[1][j]);
      out = max(out,dp[0][j]);
    }
  }
  cout << out << endl;
}

int main(){
  while(cin >> in[0] >> in[1]){
    memset(dp,0,sizeof(dp));
    solve();
  }
  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,roop3, save[100000]={}, 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++: #include<iostream>
#include<vector>
#include<string>

using namespace std;

int main()
{
	string str,str2;
	int i,j;
	
	for(;cin >> str;)
	{
		cin >> str2 ;
		
		vector<int> ss[4001];
		int ans=0;
		
		for(i=0;i<str.size();i++)
		{
			for(j=0;j<str2.size();j++)
			{
				ss[i].push_back(0);
			}
		}
		
		for(i=0;i<str.size();i++)
		{
			for(j=0;j<str2.size();j++)
			{
				if(str[i]==str2[j] && i!=0 && j!=0)
				{
					ss[i][j]=ss[i-1][j-1]+1;
				}
				else if(str[i]==str2[j])
					ss[i][j]++;
				if(ss[i][j]>ans)
					ans=ss[i][j];
			}
		}
		cout << ans << endl;
	}
}

C++: #include <bits/stdc++.h>

#define LL long long
#define VI vector<int>
#define VVI vector<vector<int>>
#define VVVI vector<vector<vector<int>>>
#define VVVVI vector<vector<vector<vector<int>>>>
#define VL vector<LL>
#define VVL vector<vector<LL>>
#define VVVL vector<vector<vector<LL>>>
#define VVVVL vector<vector<vector<vector<LL>>>>
#define VB vector<bool>
#define FOR(i,a,b) for(int i= (a); i<((int)b); ++i)
#define RFOR(i,a) for(int i=(a); i >= 0; --i)
#define FOE(i,a) for(auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
#define BIT(n) (1LL<<(n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
#define EPS 1e-14

template<class T> T ceil(T a, T b) { return (a + b - 1) / b; }
template<class T> void print(T x) { std::cout << x << std::endl; }
inline bool inside(int y, int x, int H, int W) { return 0 <= y and y < H and 0 <= x and x < W; }

const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
const std::vector<int> dy = { 0, 1, 0, -1 }, dx = { 1, 0, -1, 0 };    // 4近傍（右, 下, 左, 上）

using namespace std;


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (true) {
        string s, t;
        cin >> s;
        if (s == "") { break; }
        cin >> t;

        VVI dp(s.size() + 1, VI(t.size() + 1, 0));

        FOR(i, 0, s.size()) {
            FOR(j, 0, t.size()) {
                if (s[i] == t[j]) {
                    dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j] + 1);
                }
                else {
                    dp[i + 1][j + 1] = 0;
                }
            }
        }

        int ans = 0;
        FOR(i, 0, dp.size()) {
            FOR(j, 0, dp[0].size()) {
                ans = max(ans, dp[i][j]);
            }
        }
        print(ans);
    }

    return 0;
}