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] = 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 <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <functional>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
 
using namespace std;
 
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define rep(i,n) REP(i, 0, n)
#define pb push_back
#define mp make_pair
#define all(r) (r).begin(),(r).end()
#define rall(r) (r).rbegin(),(r).rend()
#define fi first
#define se second
 
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vl;
typedef vector<vl> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 

 
const int INF = 1e9;
const double EPS = 1e-8;
const int mod = 1e9 + 7;
const ll LINF = 1e18;
const double PI = acos(-1);

struct Input
{
	int n;
	char c;
	char str[1024];
	string s;
	ll l;
	int nextInt(){
		scanf("%d", &n);
		return n;
	}
	ll nextLong(){
		scanf("%lld", &l);
		return l;
	}
	char nextChar(){
		scanf("%c", &c);
		return c;
	}
	string next(){
		scanf("%s", str);
		return string(str);
	}
	string nextLine(){
		getline(cin, s);
		return s;
	}
};
Input in;

int f(const string &s, const string &t){
	int ret = 0;
	int prv = 0;
	for(int i = 0; i < s.size(); i++){
		if(s[i] == t[i]) prv++;
		else prv = 0;
		ret = max(ret, prv);
	}
	return ret;
}

int calc(const string &s, const string &t){
	int ret = 0;
	for(int i = 0; i < s.size(); i++){
		ret = max(ret, f(s.substr(i), t.substr(0, s.size()-i)));
	}
	return ret;
}

int main(){
	string s, t;
	while(cin>>s>>t){
		if(t.size() < s.size()) swap(s, t);
		printf("%d\n", calc(s, t));
	}
}

C++: #include <iostream>
#include <string.h>
using namespace std;
short dp[4001][4001];
int main(){
  string s,t;


  while(cin >> s >> t){
    memset(dp,0,sizeof(dp));
    dp[0][0] = 0;
    int ans = 0;
    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;
	  if(dp[i+1][j+1] > ans)ans = dp[i+1][j+1];
	}else {
	  dp[i+1][j+1] = 0;
	}
      }
    }
    cout << ans << endl;
  }
}

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

using namespace std;

int main()
{
	string str,str2;
	int i,j;
	vector<short int> ss[4001];
	
	for(i=0;i<4000;i++)
		for(j=0;j<4000;j++)
			ss[i].push_back(0);
	
	for(;cin >> str;)
	{
		cin >> str2 ;
		
		int ans=0;
		
		
		for(i=0;i<str.size();i++)
		{
			for(j=0;j<str2.size();j++)
			{
				ss[i][j]=0;
				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 <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(){
	string s1,s2;
	
	while(cin>>s1>>s2){
		int maxcom=0;
		
		for(int i=0;i<s1.size();i++){
			for(int j=0;j<s2.size();j++){
				if(s1[i]!=s2[j])continue;
				int tmax=0;
				for(int k=0;i+k<s1.size() && j+k<s2.size();k++){
					if(s1[i+k]==s2[j+k])++tmax;
					else break;
				}
				maxcom=max(maxcom,tmax);
			}
		}
		
		cout<<maxcom<<endl;
	}
}

C++: #include <cstdio>
#include <cstdint>
#include <cassert>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

template <intmax_t X = 943681729, intmax_t MOD = 1000000007>
class rolling_hash {
  std::vector<intmax_t> hash, offset;

public:
  rolling_hash(const std::string& s): hash(s.length()+1), offset(s.length()+1) {
    for (size_t i = 0; i < s.length(); ++i)
      hash[i+1] = (hash[i]*X+s[i]) % MOD;

    offset[0] = 1;
    for (size_t i = 1; i <= s.length(); ++i)
      offset[i] = offset[i-1] * X % MOD;
  }

  intmax_t get_base() const { return X; }
  intmax_t get_mod() const { return MOD; }

  intmax_t prefix(size_t i) const {
    // hash of prefix s[0..i-1] (inclusive)
    assert(0 < i);
    return hash[i];
  }

  intmax_t substr(size_t i, size_t j) const {
    // hash of substring s[i..j-1] (inclusive)
    assert(i < j);
    intmax_t res = hash[j];
    res = (res - offset[j-i]*hash[i]) % MOD;
    if (res < 0) res += MOD;
    return res;
  }

  intmax_t inserted(size_t i, int ch) const {
    intmax_t res = 0;
    if (i > 0) res += prefix(i);
    res = (res*X + ch) % MOD;
    size_t n = hash.size()-1;
    if (i < n) res = (res*offset[n-i] + substr(i, n)) % MOD;
    return res;
  }

  void debug() const {
    for (size_t i = 0; i < hash.size(); ++i)
      fprintf(stderr, "%jd%c", hash[i], i+1<hash.size()? ' ':'\n');
  }
};

int testcase_ends() {
  char buf[4096];
  if (scanf("%s", buf) == EOF) return 1;
  std::string s = buf;
  scanf("%s", buf);
  std::string t = buf;

  if (s.length() > t.length()) std::swap(s, t);

  size_t n = s.length();
  size_t m = t.length();

  rolling_hash<> rs(s), rt(t);

  for (size_t w = n; w > 0; --w) {
    std::set<intmax_t> rl;
    for (size_t i = 0; i+w <= n; ++i)
      rl.insert(rs.substr(i, i+w));

    for (size_t i = 0; i+w <= m; ++i)
      if (rl.count(rt.substr(i, i+w)))
        return !printf("%zu\n", w);
  }

  puts("0");
  return 0;
}

int main() {
  while (!testcase_ends()) {}
}

C++: #include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[4000][4000];
int main(){
	string s,t;
	int ans=0;
	while(cin>>s>>t){
		for(int i=0;i<s.size();i++){
			for(int j=0;j<t.size();j++){
				if(i==0||j==0){
					if(s[i]==t[j])dp[i][j]=1;
					else dp[i][j]=0;
				}else{
					if(s[i]==t[j])dp[i][j]=dp[i-1][j-1]+1;
					else dp[i][j]=0;
				}
				ans=max(ans,dp[i][j]);
			}
		}
		cout<<ans<<endl;
	}
}

C++: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>

using namespace std;

int main(){
	
	string str1, str2, s;
	
	while(true){
		
		cin >> str1;
		
		if(cin.eof()){
			break;
		}
		
		cin >> str2;
		
		int ans = 0;
		
		for(int i = 0; i < str1.size(); i++){
			for(int j = 0; j < str1.size() - i; j++){
				if(ans > j){
					continue;
				}
				s = str1.substr(i, j);
				if(str2.find(s, 0) != string::npos){
					if(s.size() > ans){
						ans = s.size();
					}
				}
			}
		}
		
		printf("%d\n", ans);
		
	}
	return 0;
}

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

int main(){
while(1){
	int ls=0,lt=0,ans=0;
	char s[4002],t[4002];
	if(scanf("%s",&s)==EOF)break;
	while(s[ls]!='\0')ls++;
	scanf("%s",&t);
	while(t[lt]!='\0')lt++;
	for(int i=0;i<lt-ans;i++){
		int k=0;
		for(int j=0;j<ls&&j+i<lt;j++){
			if(s[j]==t[j+i])k++;
			if(s[j]!=t[j+i]){
				if(k>ans)ans=k;
				k=0;
			}
		}
	}
	for(int i=0;i<ls-ans;i++){
		int k=0;
		for(int j=0;j<lt&&j+i<ls;j++){
			if(t[j]==s[j+i])k++;
			if(t[j]!=s[j+i]){
				if(k>ans)ans=k;
				k=0;
			}
		}
	}
	printf("%d\n",ans);
}
}