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 <bits/stdc++.h>

using namespace std;

#define int long long
#define double long double
#define FOR(i, a, b) for(ll i = (a); i < (b); ++i)
#define FORR(i, a, b) for(ll i = (a); i > (b); --i)
#define REP(i, n) for(ll i = 0; i < (n); ++i)
#define REPR(i, n) for(ll i = n; i >= 0; i--)
#define FOREACH(x, a) for(auto &(x) : (a))
#define VECCIN(x)                                                              \
    for(auto &youso_ : (x)) cin >> youso_
#define bitcnt(x) __builtin_popcount(x)
#define lbit(x) __builtin_ffsll(x)
#define rbit(x) __builtin_clzll(x)
#define SZ(x) ((ll)(x).size())
#define fi first
#define se second
#define All(a) (a).begin(), (a).end()
#define rAll(a) (a).rbegin(), (a).rend()

template <typename T = long long> inline T IN() {
    T x;
    cin >> x;
    return (x);
}
inline void CIN() {}
template <class Head, class... Tail>
inline void CIN(Head &&head, Tail &&... tail) {
    cin >> head;
    CIN(move(tail)...);
}
#define CCIN(...)                                                              \
    char __VA_ARGS__;                                                          \
    CIN(__VA_ARGS__)
#define DCIN(...)                                                              \
    double __VA_ARGS__;                                                        \
    CIN(__VA_ARGS__)
#define LCIN(...)                                                              \
    ll __VA_ARGS__;                                                            \
    CIN(__VA_ARGS__)
#define SCIN(...)                                                              \
    string __VA_ARGS__;                                                        \
    CIN(__VA_ARGS__)
#define Yes(a) cout << (a ? "Yes" : "No") << "\n"
#define YES(a) cout << (a ? "YES" : "NO") << "\n"
#define Printv(v)                                                              \
    {                                                                          \
        FOREACH(x, v) { cout << x << " "; }                                    \
        cout << "\n";                                                          \
    }
template <typename T = string> inline void eputs(T s) {
    cout << s << "\n";
    exit(0);
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
    std::fill((T *)array, (T *)(array + N), val);
}

template <typename T> using PQG = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using PQ = priority_queue<T>;

typedef long long ll;
typedef vector<ll> VL;
typedef vector<VL> VVL;
typedef pair<ll, ll> PL;
typedef vector<PL> VPL;
typedef vector<bool> VB;
typedef vector<double> VD;
typedef vector<string> VS;

const int INF = 1e9;
const int MOD = 1e9 + 7;
// const int MOD = 998244353;
const ll LINF = 1e18;
// const double PI = atan(1.0) * 4.0;
const ll dx[] = {1, 1, 0, -1, -1, -1, 0, 1};
const ll dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
#define PI 3.141592653589793238

VL Zalgo(const string &S) {
    int N = (int)S.size();
    VL res(N);
    res[0] = N;
    int i = 1, j = 0;
    while(i < N) {
        while(i + j < N && S[j] == S[i + j]) ++j;
        res[i] = j;
        if(j == 0) {
            ++i;
            continue;
        }
        int k = 1;
        while(i + k < N && k + res[k] < j) res[i + k] = res[k], ++k;
        i += k, j -= k;
    }
    return res;
}

signed main() {
    string S, T;
    while(1) {
        if(!(cin >> S)) break;
        cin >> T;
        string ST = S + "$" + T;
        ll res = 0;
        ll N = S.length();
        REP(i, N) {
            VL z = Zalgo(ST.substr(i));
            REP(j, T.size()) { res = max(res, z[S.length() + 1 + j - i]); }
        }
        cout << res << "\n";
    }
}

C++: #include<bits/stdc++.h>
#define LL long long
#define rep(a,b) for(int a=0;a<b;a++)
#define pb push_back
#define str string
#define INF 100000000
using namespace std;
LL sub_string(const string& s1,const string& s2,LL l1,LL l2){
    LL len=min(s1.size()-l1,s2.size()-l2);
    LL lon=0;
    LL ans=0;
    for(int j=0;j<len;j++){
        if(s1[l1+j]==s2[l2+j]){
            lon++;
        }else{
            ans=max(ans,lon);
        }
    }return max(ans,lon);
}
int main(){
    while(1){
    str s1,s2;
    LL ans=0;
    cin >> s1 >> s2;
    if(s1=="EOF")break;
    LL l1=s1.size();
    LL l2=0;
        while(l1>0||l2<s2.size()){
            if(l1>0){
                l1--;
            }else{
                l2++;
            }
            ans=max(ans,sub_string(s1,s2,l1,l2));
        }
    cout << ans << endl;
    }
return 0;
}

C++: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cassert>
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<utility>
#include<numeric>
#include<algorithm>
#include<bitset>
#include<complex>

using namespace std;

typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

int main() {
	char a[4010],b[4010];
	while(scanf("%s",a)!=EOF){
		scanf("%s",b);
		int i,j,k;
		int max=0;
		for(i=0;i<strlen(a);i++){
			k=0;
			for(j=0;j<strlen(b)&&j<strlen(a)-i;j++){
				if(a[i+j]==b[j])k++;
				else{
					chmax(max,k);
					k=0;
				}
			}
			chmax(max,k);
		}
		for(i=0;i<strlen(b);i++){
			k=0;
			for(j=0;j<strlen(a)&&j<strlen(b)-i;j++){
				if(a[j]==b[i+j])k++;
				else{
					chmax(max,k);
					k=0;
				}
			}
			chmax(max,k);
		}
		cout<<max<<endl;
	}
	return 0;
}

C++: #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
    string s1, s2;
    while (cin>>s1>>s2) {
        int res=0;
        for(int off = -(int)s1.size(); off <= (int)s2.size(); off++) {
            int len = 0;
            for(int i = max(off, 0); i < min(s1.size()+off, s2.size()); i++) {
                if(len > res) {
                    res = len;
                }
                if(s1[i-off] != s2[i]) {
                    len = 0;
                } else {
                    len++;
                }
            }
        }
        cout << res << endl;
    }
}
/*
char str1[4001], str2[4001];
int main() {
    while (scanf("%s%s",&str1,&str2)!=EOF) {
        int res=0;
        for (int off=-1*(int)strlen(str1); off<=(int)strlen(str2); off++) {
            int len=0;
            for (int i=max(off,0); i<min(strlen(str1)+off,strlen(str2)); i++) {
                if (len>res) res=len;
                if (str1[i-off]!=str2[i]) len=0;
                else len++;
            }
        }
        printf("%d\n",res);
    }
}
*/