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 <string>
#include <algorithm>
using namespace std;

int solve(string s, string t){
	int ans = 0;
	for(int i=0 ; i < s.size() ; i++ ){
		string s_ = s.substr(i);
		int len = min( s_.size() , t.size() );
		int a[4001] = {0};
		
		for(int j=0 ; j < len ; j++ ){
			if( s_[j] == t[j] ) a[j] = 1;
		}
		
		int sum=0;
		for(int j=1 ; j < len ; j++ ){
			if( a[j-1] > 0 && a[j] > 0 ){
				a[j] = a[j-1] + 1;
				sum = max( sum , a[j-1] + 1 );
			}
		}
		ans = max( ans , sum );
	}
	return ans;
}

int main(){
	string s,t;
	while( cin >> s >> t ){
		int ans = max( solve(s,t) , solve(t,s) );
		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=s.size();
    int a=0,b=0;
    for(int i=0;i<c;++i){
      for(int j=0;j<c;++j){
	if(u[j]==s[(i+j)%c]){
	  ++b;
	  if(i+j==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++: #include <string>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
	string S, T;

	while (cin >> S >> T)
	{
		vector<vector<int> > dp(T.size() + 1, vector<int>(S.size() + 1, 0));

		for (int i = 0; i <= S.size(); i++) { dp[0][i] = 0; }
		for (int i = 0; i <= T.size(); i++) { dp[i][0] = 0; }

		for (int i = 1; i <= T.size(); i++)
		{
			for (int j = 1; j <= S.size(); j++)
			{
				dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

				if (T[i - 1] == S[j - 1])
				{
					dp[i][j]++;
				}
			}
		}

		printf("%d\n", dp[T.size()][S.size()]);
	}

	return 0;
}

C++: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(auto it=(X).begin();it!=(X).end();it++)
#define ite iterator
#define mp make_pair
#define mt make_tuple
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define pb push_back
#define sec second
#define sz(x) ((int)(x).size())

using namespace std;

struct timer{
	time_t start;
	timer(){start=clock();}
	~timer(){cerr<<1.*(clock()-start)/CLOCKS_PER_SEC<<" secs"<<endl;}
};

typedef istringstream iss;
typedef long long ll;
typedef pair<ll,ll> pi;
typedef stringstream sst;
typedef vector<ll> vi;

string s,t;
int n,m,dp[4010][4010];

int main2(){
	cin.tie(0);
	ios_base::sync_with_stdio(0);
	
	if(!(cin>>s>>t))return 1;
	n=sz(s),m=sz(t);
	memset(dp,0,sizeof(dp));
	int ans=0;
	rep2(i,1,n+1)rep2(j,1,m+1){
		if(s[i-1]==t[j-1]){
			dp[i][j]=dp[i-1][j-1]+1;
			ans=max(ans,dp[i][j]);
		}else{
			dp[i][j]=0;
		}
	}
	cout<<ans<<endl;
	return 0;
}

int main(){
	while(!main2());
}

C++: #include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 4001;

int dp[MAX][MAX];

int main(){
  string s1,s2;

  while(cin >> s1 >> s2){
    memset(dp,0,sizeof(dp));

    int n = s1.size() ,m = s2.size();
    int ans = -1; 
    for(int i = 0 ; i < n ; i++){
      for(int j = 0 ; j < m ; j++){
	if(s1[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 <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int main()
{
    for(;;){
        string s1, s2;
        if(!(cin >> s1 >> s2))
            return 0;

        int n = s1.size();
        int m = s2.size();

        int ret = 0;
        vector<vector<int> > len(n, vector<int>(m, 0));
        for(int i=0; i<n; ++i){
            if(s1[i] == s2[0])
                ret = len[i][0] = 1;
        }
        for(int i=0; i<m; ++i){
            if(s1[0] == s2[i])
                ret = len[0][i] = 1;
        }

        for(int i=1; i<n; ++i){
            for(int j=1; j<m; ++j){
                if(s1[i] == s2[j]){
                    len[i][j] = len[i-1][j-1] + 1;
                    ret = max(ret, len[i][j]);
                }
            }
        }

        cout << ret << endl;
    }
}

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

int main() {
	while(1){
		string a,b;
    	cin>>a>>b;
    	int n,m,last=0,now=0,c=-1;
    	n=a.size();
    	m=b.size();
	    if(n==0&&m==0) break;
	    
    	for(int i=0;i<n;i++){
		c=i;
		for(int j=0;j<m;j++){
			if(a[c]==b[j]){
				last++;
				if(a[c+1]!=b[j+1]){
					now=max(last,now);
					last=0;
				}
			}
			c++;
		}
	}
	cout<<now<<endl;
	}
	return 0;
}

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

#define rep(i,n) for(int i=0;i<n;++i)
using namespace std;

int dp[4010][4010];

int main(void){
	string s,t;
	while(cin >> s >> t){
		if(cin.eof()) break;
		int n=s.size(),m=t.size();
		rep(i,n)rep(j,m) dp[i][j]=0;
		rep(i,n)rep(j,m){
			if(s[i]==t[j])
				dp[i+1][j+1]=dp[i][j]+1;
			else
				dp[i+1][j+1]=0;
		}
		int ans=0;
		rep(i,n+1)rep(j,m+1) ans=max(ans,dp[i][j]);
		cout << ans << endl;		
	}
	return 0;
}

C++: import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
for(;sc.hasNext();){
String s=sc.next();
String t=sc.next();
System.out.println(lcs(s,t).length());
}
}

	static String lcs(String s, String t){
		int m=s.length(), n=t.length();
		int[][] d=new int[n+1][m+1];
		int[][] v=new int[n+1][m+1];
		for(int j=1; j<=n; j++){
			for(int i=1; i<=m; i++){
				if(s.charAt(i-1)==t.charAt(j-1)){
					d[j][i]=d[j-1][i-1]+1;
					v[j][i]=0;
				}else if(d[j][i-1]>d[j-1][i]){
					d[j][i]=d[j][i-1];
					v[j][i]=+1;
				}else{
					d[j][i]=d[j-1][i];
					v[j][i]=-1;
				}
			}
		}
		String r="";
		for(int i=m, j=n; i>0&&j>0;){
			if(v[j][i]>0)
				i--;
			else if(v[j][i]<0)
				j--;
			else{
				r=s.charAt(i-1)+r;
				i--;
				j--;
			}
		}
		return r;
	}

}