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;
typedef long long ll;
#define MAX_N 200050
int n,k;
int r[MAX_N+1],r2[MAX_N+1];
int t[MAX_N+1];
bool compare_sa(int i,int j){
  if(r[i]!=r[j]) return r[i]<r[j];
  else{
    int ri=i+k<=n?r[i+k]:-1;
    int rj=j+k<=n?r[j+k]:-1;
    return ri<rj;
  }
}
void constract_sa(string S, int *sa){
  n=S.length();
  for(int i=0;i<=n;i++){
    sa[i]=i;
    r[i]=i<n?S[i]:-1;
  }
  for(k=1;k<=n;k*=2){
    sort(sa,sa+n+1,compare_sa);
    t[sa[0]]=0;
    for(int i=0;i<=n;i++){
      t[sa[i]]=t[sa[i-1]]+(compare_sa(sa[i-1],sa[i])?1:0);
    }
    for(int i=0;i<=n;i++){
      r[i]=t[i];
    }
  }
}
void constract_lcp(string S,int *sa,int *lcp){
  for(int i=0;i<=n;i++) r2[sa[i]]=i;
  int h=0;
  lcp[0]=0;
  for(int i=0;i<n;i++){
    int j=sa[r2[i]-1];
    if(h>0) h--;
    for(;j+h<n&&i+h<n;h++){
      if(S[j+h]!=S[i+h]) break;
    }
    lcp[r2[i]-1]=h;
  }
}
bool contains(string S,int *sa,string T){
  int a=0,b=S.length()+1;
  while(b-a>1){
    int c=(a+b)/2;
    if(S.compare(sa[c],T.length(),T)<0) a=c;
    else b=c;
  }
  return S.compare(sa[b],T.length(),T)==0;
}

int count(string &S,int *sa,string T){
  int sl=S.length(),tl=T.length();
  int a[2],b[2];
  for(int i=0;i<2;i++){
    a[i]=0;
    b[i]=sl;
    while(a[i]+1<b[i]){
      int c=(a[i]+b[i])/2;
      if(S.compare(sa[c],tl,T)<0||
	 (i&&S.compare(sa[c],tl,T)==0)) a[i]=c;
      else b[i]=c;
    }
  }
  if(S.compare(sa[b[0]],tl,T)!=0) return 0;
  if(a[1]<sl&&S.compare(sa[a[1]+1],tl,T)==0) a[1]++;
  if(b[0]> 0&&S.compare(sa[b[0]-1],tl,T)==0) b[0]--;
  return a[1]-b[0]+1;
}

struct RMQ{
  int n;
  vector<int> dat;
  const int def=INT_MAX;
  RMQ(){}
  RMQ(int n_){init(n_);}
  void init(int n_){
    n=1;
    while(n<n_) n*=2;
    dat.clear();
    dat.resize(2*n-1,def);
  }
  void update(int k,int a){
    k+=n-1;
    dat[k]=a;
    while(k>0){
      k=(k-1)/2;
      dat[k]=min(dat[k*2+1],dat[k*2+2]);
    }
  }
  int query(int a,int b,int k,int l,int r){
    if(r<=a||b<=l) return def;
    if(a<=l&&r<=b) return dat[k];
    else{
      int vl=query(a,b,k*2+1,l,(l+r)/2);
      int vr=query(a,b,k*2+2,(l+r)/2,r);
      return min(vl,vr);
    }
  }
  int query(int a,int b){
    return query(a,b,0,0,n);
  }
};

int getlcp(string &S,int p,string &T,int d){
  int i=0;
  int len=min((int)T.length()-d,(int)S.length()-p-d);
  while(i<len&&S[p+d+i]==T[d+i]) i++;
  return i;
}


int count(string &S,int *sa,string T,RMQ &rmq){
  int a[2],b[2];
  int sl=S.length(),tl=T.length();
  for(int i=0;i<2;i++){
    int p,l,r;
    p=tl;
    a[i]=0;
    b[i]=sl;
    l=getlcp(S,sa[a[i]],T,0);
    r=getlcp(S,sa[b[i]],T,0);
    while(b[i]-a[i]>1){
      int c=(a[i]+b[i])/2;
      //cout<<a[i]<<" "<<b[i]<<" "<<c<<endl;
      if(l>=r){
	int m=rmq.query(a[i],c);
	if(m<l) b[i]=c,r=m;
        else{
	  int k=l+getlcp(S,sa[c],T,l);
	  if(i){
	    if(k==p||S[sa[c]+k]<T[k]) a[i]=c,l=k;
	    else b[i]=c,r=k;
	  }else{
	    if(k==p) b[i]=c,r=k;
	    else if(S[sa[c]+k]<T[k]) a[i]=c,l=k;
	    else b[i]=c,r=k;
	  }
	}
      }else{
	int m=rmq.query(c,b[i]);
	if(m<r) a[i]=c,l=m;
        else{
	  int k=r+getlcp(S,sa[c],T,r);
	  if(i){
	    if(k==p||S[sa[c]+k]<T[k]) a[i]=c,l=k;
	    else b[i]=c,r=k;
	  }else{
	    if(k==p) b[i]=c,r=k;
	    else if(S[sa[c]+k]<T[k]) a[i]=c,l=k;
	    else b[i]=c,r=k;
	  }
	}
      }
    }
  }
  
  if(a[1]<sl&&getlcp(S,sa[a[1]+1],T,0)==tl) a[1]++;
  if(b[0]> 0&&getlcp(S,sa[b[0]-1],T,0)==tl) b[0]--;
  
  if(getlcp(S,sa[b[0]],T,0)!=tl) return 0;
  
  return a[1]-b[0]+1;
}

int main(){
  string s,t;
  while(cin>>s>>t){
    int n=s.size(),m=t.size();
    s+=' '+t;
    int sa[MAX_N+1],lcp[MAX_N+1];
    constract_sa(s,sa);
    constract_lcp(s,sa,lcp);
    int ans=0;
    for(int i=0;i<n+m;i++){
      if((sa[i]<n)^(sa[i+1]<n))
	ans=max(ans,lcp[i]);
    }
    cout<<ans<<endl;
  }
  return 0;
}

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

using namespace std;

int main()
{
	string str,str2;
	
	for(;cin >> str;)
	{
		cin >> str2 ;
		int ans=0;
		if(str.size()>str2.size())
		{
			string a;
			a=str2;
			str2=str;
			str=a;
		}
		
		for(int i=0;i<str.size();i++)
		{
			for(int j=str.size()-i;j>0;j--)
			{
				string se;
				se=str.substr(i,j);
				if(str2.find(se)!=-1)
				{
					if(ans<se.size())
						ans=se.size();
					break;
				}
			}
		}
		cout << ans << endl;
	}
}

C++: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
#define INF (1<<30)
#define INFLL (1ll<<60)
typedef pair<int, int> P;
typedef pair<ll, P> E;
#define MOD (1000000007ll)
#define l_ength size
#define PI 3.14159265358979
 
void mul_mod(ll& a, ll b){
    a *= b;
    a %= MOD;
}
 
void add_mod(ll& a, ll b){
    b += MOD;
    a += b;
    a %= MOD;
}

int n,m;
int memo[4444][4444];
bool done[4444][4444];
char s[4444],t[4444];

int dp(int i, int j){
    if(done[i][j]){
        return memo[i][j];
    }
    done[i][j] = true;
    if(i == n || j == m){
        memo[i][j] = 0;
    }else if(s[i] != t[j]){
        memo[i][j] = 0;
    }else{
        memo[i][j] = dp(i+1,j+1) + 1;
    }
    return memo[i][j];
}

int main(void){
    int i,j,ans;
    while(scanf("%s",s)!=EOF){
        fill(done[0],done[4444],false);
        ans = 0;
        scanf("%s",t);
        n = strlen(s); m = strlen(t);
        for(i=0; i<n; ++i){
            for(j=0; j<m; ++j){
                ans = max(ans,dp(i,j));
            }
        }
        cout << ans << endl;
    }
    return 0;
}

C++: #include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <bitset>
#include <cstring>
using namespace std;
#define FOR(I,A,B) for(int I = (A); I < (B); ++I)
#define CLR(mat) memset(mat, 0, sizeof(mat))
typedef long long ll;
 
int main()
{
  string s, t; cin >> s >> t;
  // s??????
  int ans = 0;
  int cnt = 0;
  FOR(i,0,t.length()) {
  	cnt = 0;
   	for(int j = 0; j < s.length() && i + j < t.length(); j++) {
      if(s[j] == t[i+j]) cnt++;
      else {
        ans = max(ans, cnt);
        cnt = 0;
      }
    }
    ans = max(ans, cnt);
  }
    
  // t??????
  FOR(i,0,s.length()) {
    cnt = 0;
   	for(int j = 0; j < t.length() && i + j < s.length(); j++) {
      if(s[i+j] == t[j]) cnt++;
      else {
        ans = max(ans, cnt);
        cnt = 0;
      }
    }
    ans = max(ans, cnt);
  }
  cout << ans << endl;
  return 0;
}

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

int main()
{
  string s1,s2;
  for(;cin>>s1;)
    {
      cin>>s2;
      int ans=0;
      int i=0,j=0;
      while(i+j<=s1.size())
      {
        if(s1.size()-i<ans)
          break;

        if(s2.find(s1.substr(i,j))!=string::npos)
          {
            //    cerr<<s1.substr(i,j)<<endl;

            ans=max(ans,j);
            j++;
          }
        else
          {
            i++;
            j=1;
          }
      }
      cout<<ans<<endl;
    }
}