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 int long long

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned __int128 HASH;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pullull;
typedef pair<ll,int> plli;
typedef pair<double, int> pdbi;
typedef pair<int,pii> pipii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;
typedef vector<vector<int>> mat;

#define rep(i,n) for (int i=0;i<(n);i++)
#define rep2(i,a,b) for (int i=(a);i<(b);i++)
#define rrep(i,n) for (int i=(n);i>0;i--)
#define rrep2(i,a,b) for (int i=(a);i>b;i--)
#define pb push_back
#define fi first
#define se second
#define all(a) (a).begin(),(a).end()

const ll hmod1 = 999999937;
const ll hmod2 = 1000000000 + 9;
const ll INF = 1<<30;
const ll mod = 1000000000 + 7;
const int dx4[4] = {1, 0, -1, 0};
const int dy4[4] = {0, 1, 0, -1};
const int dx8[8] = {1, 1, 1, 0, 0, -1, -1, -1};
const int dy8[8] = {0, 1, -1, 1, -1, 0, 1, -1};
const double pi = 3.141592653589793;

#define addm(X, Y) ((X) = ((X) + (Y) % mod) % mod)

string s, t;

struct SuffixArray {
    int n, k;
    string text;
    vector<int> sa;
    vector<int> rank;
    vector<int> lcp;

    SuffixArray (const string &s)
    : text(s), n(s.size()), sa(n + 1), rank(n + 1), lcp(n)
    {}

    bool comp(int i, int j) {
        if (rank[i] != rank[j]) return rank[i] < rank[j];
        int ri = i + k <= n ? rank[i + k] : -1;
        int rj = j + k <= n ? rank[j + k] : -1;
        return ri < rj;
    }

    void construct_sa() {
        for (int i = 0; i <= n; i++) {
            sa[i] = i;
            rank[i] = i < n ? text[i] : -1;
        }

        for (k = 1; k <= n; k *= 2) {
            sort(sa.begin(), sa.end(), [&](const int& i, const int& j) {return comp(i, j);});

            vector<int> tmp(n + 1);
            tmp[sa[0]] = 0;
            for (int i = 1; i <= n; i++) {
                tmp[sa[i]] = tmp[sa[i - 1]] + (comp(sa[i - 1], sa[i]) ? 1 : 0);
            }

            for (int i = 0; i <= n; i++) {
                rank[i] = tmp[i];
            }
        }
    }

    void construct_lcp () {
        int h = 0;
        lcp[0] = 0;
        for (int i = 0; i < n; i++) {
            int j = sa[rank[i] - 1];
            if (h > 0) h--;
            for (; j + h < n && i + h < n; h++) {
                if (text[j + h] != text[i + h]) break;
            }
            lcp[rank[i] - 1] = h;
        }
    }

    int low_bd(const string &pt) {
        int l = 0, r = n + 1;
        while (r - l > 1) {
            int m = (r + l) / 2;
            int val = text.compare(sa[m], pt.length(), pt);
            if (val < 0) l = m;
            else r = m;
        }
        return r;
    }

    int up_bd(const string &pt) {
        int l = 1, r = n + 1;
        while (r - l > 1) {
            int m = (r + l) / 2;
            int val = text.compare(sa[m], pt.length(), pt);
            if (val <= 0) l = m;
            else r = m;
        }
        return r;
    }

    bool match(const string &pt) {
        int idx = low_bd(pt);
        if (idx == sa.size()) return false;
        return text.compare(sa[idx], pt.length(), pt) == 0 ? true : false;
    }

    int count(const string &pt) {
        int l_idx = low_bd(pt);
        if (l_idx == sa.size()) return 0;
        if (text.compare(sa[l_idx], pt.length(), pt) != 0) return 0;
        int r_idx = up_bd(pt);
        return r_idx - l_idx;
    }
};

signed main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    while (cin >> s >> t) {
        int n = s.size();
        int m = t.size();
        string st = s + '$' + t;
        SuffixArray suf(st);
        suf.construct_sa();
        suf.construct_lcp();
        int ans = 0;
        rep(i, n + m - 1) {
            int mn = min(suf.sa[i], suf.sa[i + 1]);
            int mx = max(suf.sa[i], suf.sa[i + 1]);
            if (mn < n && n < mx) ans = max(ans, suf.lcp[i]);
        }
        cout << ans << endl;
    }
}

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

string in[2];

void solve()
{
	int c;
	int ans = 0;

	for(int u = 0; u < 2; u++){
	for(int i = 0; i < in[0].size(); i++){
		c = 0;
		int j = 0;
		while(j + 1 < in[1].size() && in[0][i] != in[1][j])j++;
		while(in[0][i+c] == in[1][j+c]){
			c++;
		}

		if(c > 0)
			c++;
		ans = max(ans, c);

	
	}
		swap(in[0],in[1]);
	}
	cout << ans << endl;
}


int main(void)
{
	while(cin >> in[0] >> in[1], !cin.eof())
		solve();
	return 9;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int lcs(string s, string s2) {
	int m = s.size();
	int n = s2.size();
	int c[max(m, n) + 1][max(m, n) + 1];
	int ret = 0;

	memset(c, 0, sizeof(c));
	s = ' ' + s;
	s2 = ' ' + s2;

	REP(i,1,m+1) c[i][0] = 0;
	REP(j,1,n+1) c[0][j] = 0;

	REP(i,1,m+1) {
		REP(j,1,n+1) {
			if(s[i] == s2[j]) c[i][j] = c[i-1][j-1] + 1;
			ret = max(ret,c[i][j]);
	    }
    }

	return ret;
}

int main() {
	string a, b;
	while(cin >> a >> b) {
		cout << lcs(a, b) << endl;
	}
	return 0;
}

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

std::string s1,s2;

int dp[4001][4001];

int main() {
    
    while(1) {
        
        if(std::cin.eof())
            break;
        
        std::cin>>s1>>s2;
        
        for(int i=1;i<=s1.size();++i){
            for(int j=1;j<=s2.size();++j){
                if(s1[i-1]==s2[j-1])
                    dp[i][j]=dp[i-1][j-1]+1;
            }
        }
        
        int ans=0;
        
        for(int i=1;i<=s1.size();++i){
            for(int j=1;j<=s2.size();++j){
                ans=std::max(ans,dp[i][j]);
            }
        }
        
        std::cout<<ans<<std::endl;
    }
    
    return 0;
}