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

#define pb(n) push_back(n)
#define fi first
#define se second
#define all(r) (r).begin(),(r).end()
#define gsort(st,en) sort((st),(en),greater<int>())
#define vmax(ary) *max_element(all(ary))
#define vmin(ary) *min_element(all(ary))
#define debug(x) cout<<#x<<": "<<x<<endl
#define fcout(n) cout<<fixed<<setprecision((n))
#define scout(n) cout<<setw(n)
#define vary(type,name,size,init) vector< type> name(size,init)

#define rep(i,n) for(int i = 0; i < (int)(n);++i)
#define REP(i,a,b) for(int i = (a);i < (int)(b);++i)
#define repi(it,array) for(auto it = array.begin(),end = array.end(); it != end;++it)
#define repa(n,array) for(auto &n :(array))

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using dict = map<string,int>;
using pii = pair<int,int> ;
using pll = pair<ll,ll> ;

const int mod = 1000000007;
constexpr int imax = ((1<<30)-1)*2+1 ;
constexpr int inf = 100000000;
constexpr double PI = acos(-1.0) ;
double eps = 1e-10 ;
const int dy[] = {-1,0,1,0};
const int dx[] = {0,-1,0,1};

inline bool value(int x,int y,int w,int h){
  return (x >= 0 && x < w && y >= 0 && y < h);
}

template<typename T>
void Unique(vector<T> &v){
  sort(all(v));
  v.erase(unique(all(v)),v.end());
}

template<typename T>
T ston(string& str, T n){
  istringstream sin(str) ;
  T num ;
  sin >> num ;
  return num ;
}

void Ans(bool f){
  if(f) cout << "YES"<<endl;
  else cout << "NO"<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  string s,s2;
  while(cin >> s >> s2){
    ll ans = 0;
    vector<vector<ll>> dp(s.size()+1,vector<ll>(s2.size()+1,0));
    rep(i,s.size()){
      rep(j,s2.size()){
        if(s[i] == s2[j]){
          dp[i+1][j+1] += dp[i][j]+1;
          ans = max(ans,dp[i+1][j+1]);
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <map>
#include <cstring>
using namespace std;
map<string,int> m;
int main(){
	string s,t;
	while(cin >> s >> t){
		int x,a=0,b,S=s.size(),T=t.size(),i,j;
		b=min(S,T)+1;
		while(true){
			x=0;
			j=(a+b)/2;
			if(b-a==1) break;
			for(i=0;i<S-j;i++) m[s.substr(i,j)]++;
			for(i=0;i<T-j;i++) if(m[t.substr(i,j)]>=1) x++;
			m.clear();
			if(!x) b=j;
			else a=j;
		}
		cout<<a<<endl;
	}
}

C++: #include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
int lcs(string &a,string &b){
	int r=0,la=a.size(),lb=b.size(),t,tla,tlb;
	for(int i=0;i<la||i<lb;i++)if(a[tla=min(i,la-1)]==b[tlb=min(i,lb-1)]){
		rep(j,tla){
			t=0;while(tla>j+t&&tlb>t&&a[tla-1-j-t]==b[tlb-1-t])t++;
			if(t>r)r=t;
		}
		rep(j,tlb){
			t=0;while(tla>t&&tlb>j+t&&a[tla-1-t]==b[tlb-j-1-t])t++;
			if(t>r)r=t;
		}
	}
	return r;
}
int main(){
	string a,b;
	while(cin>>a>>b)cout<<lcs(a,b)<<endl;
}

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

int dp[4001][4001];

int main()
{
  string a, b;
  while(cin >> a >> b)
  {
    int ans = 0;
    for(int i = 0; i < a.length(); i++)
    {
      for(int j = 0; j < b.length(); j++)
      {
        if(a[i] == b[j])
          ans = max(dp[i + 1][j + 1] = dp[i][j] + 1, ans);
        else
          dp[i + 1][j + 1] = 0;
      }
    }
    
    cout << ans << endl;
  }
}

C++: #include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <fstream>
using namespace std;
inline int toInt(string s) { int v; istringstream sin(s); sin >> v; return v;}
template<class T> inline string toStr(T x) { ostringstream sout; sout << x; return sout.str();}
typedef vector<int> vi;
typedef vector<vi>  vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,n) FOR(i,0,(n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX/10;

int main() {
	string s1, s2;
	while(cin >> s1 >> s2) {
		int l1 = s1.length();
		int l2 = s2.length();
		vvi dp(l1, vi(l2, 0));
		int ans = 0;
		REP(i, l1) {
			if(s1[i] == s2[0]) {
				dp[i][0] = 1;
			}
		}
		REP(i, l2) {
			if(s2[i] == s1[0]) {
				dp[0][i] = 1;
			}
		}
		FOR(i, 1, l1-1) {
			FOR(j, 1, l2-1) {
				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++: //JOI 0528 Common Sub-String
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {

	while (1){
		string s, t; int roop1, roop2 = 0, save[10000] = {}, 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 <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstring>
using namespace std;
static const double EPS = 1e-5;
typedef long long ll;


int main(){
	char s1[4003],s2[4003];
	
	while(1<scanf("%s %s",s1,s2)){
		int maxcom=0;
		int s1len=strlen(s1),s2len=strlen(s2);
		for(int i=0;i<s1len+s2len;i++){
			int is1,is2;
			if(i<s1len){
				is1=i;
				is2=0;
			}else{
				is1=0;
				is2=i-s1len;
			}
			int tmax=0;
			for(int k=0;is1+k<s1len && is2+k<s2len;k++){
				if(s1[is1+k]==s2[is2+k])++tmax;
				else{
					maxcom=max(tmax,maxcom);
					tmax=0;
				}
			}
			
		}
		
		cout<<maxcom<<endl;
	}
}