Go: package main

import (
	"fmt"
	"os"
	"strconv"
	"bufio"
	"strings"
	"sort"
)

// define
var (
	sc = bufio.NewScanner(os.Stdin)
)

func bordersInt(in_map [][]int, invalid int) [][]int{
	H, W := len(in_map), len(in_map[0])
	out_map := make([][]int, H+2)
	for h:=0; h<H+2; h++ {
		out_map[h] = make([]int, W+2)
		for w:=0; w<W+2; w++ {
			out_map[h][w] = invalid
		}
	}
	for h:=0; h<H; h++{
		for w:=0; w<W; w++{
			out_map[h+1][w+1] = in_map[h][w] 
		}
	}
	return out_map
}

func bordersString(in_map [][]string, invalid string) [][]string{
	H, W := len(in_map), len(in_map[0])
	out_map := make([][]string, H+2)
	for h:=0; h<H+2; h++ {
		out_map[h] = make([]string, W+2)
		for w:=0; w<W+2; w++ {
			out_map[h][w] = invalid
		}
	}
	for h:=0; h<H; h++{
		for w:=0; w<W; w++{
			out_map[h+1][w+1] = in_map[h][w] 
		}
	}
	return out_map
}

func scanIntLine(len int) []int{
	arr := make([]int, len)
	for i:=0; i<len; i++{
		sc.Scan()
		tmp, err := strconv.Atoi(sc.Text())
		if err == nil{
			arr[i] = tmp
		}
	}
	return arr
}

func scanStringLine(len int) []string{
	arr := make([]string, len)
	for i:=0; i<len; i++{
		sc.Scan()
		arr[i] = sc.Text()
	}
	return arr
}

func scanIntSplit(len int) []int{
	arr := make([]int, len)
	sc.Scan()
	for i, v := range strings.Split(sc.Text(), " "){
		tmp, err := strconv.Atoi(v)
		if err == nil{
			arr[i] = tmp
		}
	}
	return arr
}

func maxInt(args... int) int{
	sort.Ints(args)
	return args[len(args)-1]
}

func main(){
	var n int 
	fmt.Scan(&n)
	dp := make([][]int, 1003)
	for i:=0; i<1003; i++ {
		dp[i] = make([]int, 1003)
	}
	input_lines := scanStringLine(2*n)
	for i:=0; i<n; i++ {
		S, T := input_lines[2*i], input_lines[2*i+1]
		lenS, lenT := len(S), len(T)
		for i:=1; i<lenS+1; i++ {
			for j:=1; j<lenT+1; j++ {
				if S[i-1] == T[j-1] {
					dp[i][j] = maxInt(dp[i-1][j-1]+1, dp[i-1][j], dp[i][j-1])
				} else {
					dp[i][j] = maxInt(dp[i-1][j], dp[i][j-1])
				}
			}
		}
		fmt.Println(dp[lenS][lenT])
	}
}

C++: #include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define spair(p) cout<<#p<<": "<<p.fi<<" "<<p.se<<endl
#define sar(a,n) cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl
#define svec(v) cout<<#v<<":";rep(pachico,v.size())cout<<" "<<v[pachico];cout<<endl
#define svecp(v) cout<<#v<<":";each(pachico,v)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl
#define sset(s) cout<<#s<<":";each(pachico,s)cout<<" "<<pachico;cout<<endl
#define smap(m) cout<<#m<<":";each(pachico,m)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl

using namespace std;

typedef pair<int,int> P;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<P> vp;
typedef vector<string> vs;

const int MAX_N = 100005;

const int MAX_SIZE = 52;

int LCS(const string& a, const string& b){
    int n = (int)a.size(), m = (int)b.size();
    vector<int> x(n), y(m);
    rep(i,n){
        x[i] = a[i]-'a';
        if(x[i] < 0){
            x[i] = a[i]-'A'+26;
        }
    }
    rep(i,m){
        y[i] = b[i]-'a';
        if(y[i] < 0){
            y[i] = b[i]-'A'+26;
        }
    }
    vector<vector<int> > vec(MAX_SIZE);
    for(int j = m-1; j >= 0; --j){
        vec[y[j]].push_back(j);
    }
    vector<int> xs(n, INF);
    rep(i,n){
        rep(j,(int)vec[x[i]].size()){
            *lower_bound(xs.begin(),xs.end(),vec[x[i]][j]) = vec[x[i]][j];
        }
    }
    return lower_bound(xs.begin(),xs.end(),INF) - xs.begin();
}


int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int q;
    cin >> q;
    rep(i,q){
        string a,b;
        cin >> a >> b;
        cout << LCS(a,b) << "\n";
    }
    return 0;
}

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

#define MAX_N 1000
#define MAX_M 1000

int n, m;
string s, t;

int dp[MAX_N+1][MAX_M+1];

void solve() {
    for (int i=0; i<n; ++i) {
        for (int j=0; j<m; ++j) {
            if (s[i] == t[j]) {
                dp[i+1][j+1] = dp[i][j] + 1;
            }
            else {
                dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);
            }
        }
    }
}

int main() {
    int cnt;
    cin >> cnt;
    for(int i = 0; i < cnt; i++){
        cin >> s >> t;
        n = s.length();
        m = t.length();
        solve();
        cout << dp[n][m] << endl;
    }

}

C++: #include <bits/stdc++.h>

using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(v) v.begin(),v.end()
#define _GLIBCXX_DEBUG

using ll = long long;
using vi = vector<int>;
using vll = vector<ll>;
using vd = vector<double>;
using vvi = vector<vi>;
using vvll = vector<vll>;
using vvd = vector<vd>;
using vvvi = vector<vvi>;
using vvvll = vector<vvll>;
using vvvd = vector<vvd>;

const double pi=acos(-1);
const ll MOD=1e9+7;
const ll INF=(1LL<<60);

int main() {
    int n;
    cin>>n;
    rep(i,n){
        string w1,w2;
        cin>>w1>>w2;
        int n1=w1.size(),n2=w2.size();
        int dp[n1+1][n2+1];
        memset(dp,0,sizeof(dp));
        for (int i=1;i<n1+1;i++){
            for (int j=1;j<n2+1;j++){
                if (w1[i-1]==w2[j-1]){
                    dp[i][j]=1+dp[i-1][j-1];
                }
                else{
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        cout<<dp[n1][n2]<<endl;
    }

    

    return 0;
}

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

int main() {
    int q, max_num, now_max, start_pos, target_pos;
    char target;
    string X, Y;

    cin >> q;

    for (int i = 0; i < q; i++) {
        cin >> X >> Y;
        if (X.length() < Y.length()) swap(X, Y);
        max_num = 0;
        for (int j = 0; j < Y.length(); j++) {
            start_pos = j;
            target = Y[start_pos];
            target_pos = 0;
            now_max = 0;
            while (start_pos < Y.length()) {
                for (int k = target_pos; k < X.length(); k++) {
                    if (target == X[k]) {
                        now_max++;
                        target = Y[start_pos];
                        target_pos = k + 1;
                        break;
                    }
                }
                start_pos++;
                target = Y[start_pos];
            }
            max_num = max(max_num, now_max);
        }
        cout << max_num << endl;
    }
}

C++: #include <bits/stdc++.h>
using namespace std;

int main(){
    int q;
    cin >> q;

    for (int z = 0; z < q; z++) {
        string X, Y;
        cin >> X >> Y;
        int n = X.size();
        int m = Y.size();
        vector< vector<int> > dp(n+1, vector<int>(m+1));

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (X.at(i) == Y.at(j)) {
                    dp.at(i+1).at(j+1) = dp.at(i).at(j) + 1;
                } else {
                    dp.at(i+1).at(j+1) = max(dp.at(i).at(j+1), dp.at(i+1).at(j));
                }
            }
        }

        cout << dp.at(n).at(m) << endl;
    }
}