class Solution {
public://size of rank and sa are n+1//size of lcp is n, definition of lcp[i] is max common prefix of s[sa[i]...] and s[sa[i+1]...]//input s of getSa and getLcp can be string as well
vector<int> rank, sa, lcp;voidgetSa(const vector<int>& s, vector<int>& rank, vector<int>& sa){int n = s.size();
vector<int>tmp(n+1);for(int i =0; i < n; i++){
sa.push_back(i);
rank.push_back(s[i]);}
sa.push_back(n);
rank.push_back(-1);for(int k =1; k <= n; k <<=1){auto cmp =[&](int x,int y){if(rank[x]!= rank[y])return rank[x]< rank[y];auto tx = x + k > n ?-1: rank[x + k];auto ty = y + k > n ?-1: rank[y + k];return tx < ty;};sort(sa.begin(), sa.end(), cmp);
tmp[sa[0]]=0;for(int i =1; i <= n; i++){
tmp[sa[i]]= tmp[sa[i-1]];if(cmp(sa[i-1], sa[i])){
tmp[sa[i]]++;}}for(int i =0; i <= n; i++)
rank[i]= tmp[i];}}voidgetLcp(const vector<int>& s,const vector<int>& rank,const vector<int>& sa,
vector<int>& lcp){int n = s.size();
lcp.insert(lcp.begin(), n,0);for(int i =0, h =0; i < n; i++){if(h >0)
h--;int k = rank[i];int j = sa[k-1];while(max(j, i)+ h < n && s[j+h]== s[i+h]){
h++;}
lcp[k-1]= h;}}intfindLength(vector<int>& A, vector<int>& B){int n = A.size(), m = B.size();
A.push_back(101);
A.insert(A.end(), B.begin(), B.end());getSa(A, rank, sa);getLcp(A, rank, sa, lcp);int ans =0;for(int i =0; i <= n + m; i++){if(sa[i]< n && sa[i+1]> n || sa[i]> n && sa[i+1]< n){
ans =max(ans, lcp[i]);}}return ans;}};