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;
int ans,s1,s2,text_here,patn_here,text_len,patn_len;
string str1,str2;

int main(){

    while(cin >> str1){
            cin >> str2;

            int s1=str1.size();
            int s2=0;

        while(s1!=0 || s2<=str2.size()){

            if(s1!=0){
                s1--;
            }else{
                s2++;
            }
            text_here=0;
            patn_here=0;
            text_len=str1.size();
            patn_len=str2.size();

            while(text_here<text_len && patn_here<patn_len){
                if(str1[s1+text_here]==str2[s2+patn_here]){
                    patn_here++;
                    text_here++;
                    //cout << str1[s1+text_here] << endl;
                    ans=max(patn_here,ans);
                }else{
                    text_here++;
                    patn_here=0;
                }

            }
        }
        cout << ans << endl;
        ans=0;
    }

return 0 ;
}

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

using namespace std;

string s,t;
long long m=1,dp[4001][4001];

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


int main(){
while(1){
cin >> s >>t;
if(s=="EOF")break;
solve();
}
//cout << s.size();
return 0;
}

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

using namespace std;

struct RollingHash {
  typedef unsigned long long hash_t;
  static const hash_t P = 1469979569;
  static const hash_t M = 1ll << 63;
  const int n;
  vector<hash_t> pow, phash;
  RollingHash(const string& s) : n(s.size()), pow(n + 1), phash(n + 1) {
    pow[0] = 1;
    phash[0] = 0;
    for (int i = 0; i < n; i++){
      phash[i + 1] = (s[i] + phash[i] * P) % M;
      pow[i + 1] = (pow[i] * P) % M;
    }
  }
  hash_t hash(int i, int j){
    return (phash[j] - phash[i] * pow[j - i]) % M;
  }
  int lcp(int i, int j){
    int l = 0, r = min(n - i, n - j) + 1;
    while (r - l > 1){
      int m = r + l >> 1;
      if (hash(i, i + m) == hash(j, j + m)) l = m;
      else r = m;
    }
    return l;
  }
};

typedef long long ll;
typedef long double ld;
typedef tuple<int, int> duo;
const int dx[] = {0, 0, 1, -1, 1, 1, -1, -1};
const int dy[] = {1, -1, 0, 0, 1, -1, 1, -1};
const int Mod = 1000000000 + 0;
//{{{ templates
#define TT_ template<typename T>inline
#define TTF_ template<typename T,typename F>inline
TT_ T sq(T x){return x*x;}
TT_ T In(){T x;cin>>x;return x;}
TT_ void Out(T&x){cout<<x;}
TT_ void sort(T&v){sort(begin(v),end(v));}
TT_ void revs(T&v){reverse(begin(v),end(v));}
TT_ void uniq(T&v){sort(v);v.erase(unique(begin(v),end(v)),end(v));}
TT_ int ubnd(T&v,typename T::value_type&x){return upper_bound(begin(v),end(v),x)-begin(v);}
TT_ int lbnd(T&v,typename T::value_type&x){return lower_bound(begin(v),end(v),x)-begin(v);}
TTF_ void inpt(T&v,int n,F f){for(v.reserve(n);n--;v.emplace_back(f()));}
TTF_ void show(T&v,F f,string d=" ",string e="\n"){int i=0;for(auto&x:v)i++&&(cout<<d),f(x);cout<<e;}
TT_ typename T::iterator minel(T&v){return min_element(begin(v),end(v));}
TT_ typename T::iterator maxel(T&v){return max_element(begin(v),end(v));}

inline void fast_io(){ios::sync_with_stdio(0);cin.tie(0);}
inline int in(){int x;scanf("%d",&x);return x;}
inline ll pow_mod(ll a,ll k,ll m){ll r=1;for(;k>0;a=a*a%m,k>>=1)if(k&1)r=r*a%m;return r;}
inline ll mod_inv(ll a,ll p){return pow_mod(a,p-2,p);}
//}}} priority_queue queue deque front stringstream max_element min_element insert count make_tuple

int main()
{
  string s, t;
  cin >> s >> t;
  string S = s + '$' + t;
  RollingHash rh(S);

  int maxi = 0;
  for (int i = 0; i < s.size(); i++){
    for (int j = 0; j < t.size(); j++){
      maxi = max(maxi, rh.lcp(i, s.size() + 1 + j));
    }
  }
  cout << maxi << endl;

  return 0;
}

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

string s, t;
char a[4001];
char b[4001];
int dp[4001][4001];

int main(){
	while(scanf("%s%s", a, b) != EOF){

		s = a;
		t = b;

		for(int i=0; i<4001; i++)
			for(int j=0; j<4001; j++)
				dp[i][j] = 0;

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

		printf("%d\n", ans);
	}
	return 0;
}

C++: #include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#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 <cassert>
using namespace std;
inline int toInt(string s) {int v; istringstream sin(s); sin>>v; return v;}
template<class T> inline string toString(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 EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define EACH(t,i,c) for(t::iterator i=(c).begin(); i!=(c).end(); ++i)
const double EPS = 1e-10;
const double PI = acos(-1.0);


int main(){
	string s1,s2;
	while(cin>>s1>>s2,cin){
		int ans=0;
		int j=0;
		REP(i,s1.size()){
			j=max(j,i);
			string ss;
			while(j<s1.size()&&(ss=string(s1.begin()+i,s1.begin()+j+1),s2.find(ss)!=s2.npos)){
				ans=max(ans,j-i+1);
				j++;
			}
		}
		cout<<ans<<endl;
	}
}

C++: #define _USE_MATH_DEFINES
#define INF 100000000
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>

using namespace std;

typedef long long ll;
typedef pair <int,int> P;

static const double EPS = 1e-8;

short dp[4001][4001];

int main(){
	string str1;
	while(cin>> str1){
		memset(dp,0,sizeof(dp));

		string str2;
		cin >> str2;

		for(int i=0;i<str1.size();i++){
			for(int j=0;j<str2.size();j++){
				if(str1[i] == str2[j]){
					dp[i+1][j+1] = max((int)dp[i][j]+1,max((int)dp[i+1][j],(int)dp[i][j+1]));
				}
				else{
					dp[i+1][j+1] = 0;
				}
			}
		}

		short res=0;
		for(int i=0;i<=str1.size();i++){
			for(int j=0;j<=str2.size();j++){
				res = max(res,dp[i][j]);
			}
		}

		printf("%d\n",res);
	}
}

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

int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
	
	string s, t;
	cin >> s >> t;
	
	int ans = 0, c = 0;;
	for(size_t i = 0; i < s.size(); ++i){
		for(size_t j = 0; j < t.size(); ++j){
			if(s[i] == t[j]){
				c = 1;
				while(s[i + c] == t[j + c]){
					c++;
				}
				ans = max(ans, c);
			}
		}
	}
	cout << ans << endl;
	
	return 0;
}