Go: package main

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

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}
	for i := 0; i < n; i++ {
		strX := nextText(sc)
		strY := nextText(sc)
		fmt.Println(calcLcs(strX, strY))
	}
}

func calcLcs(strX, strY string) int {
	lenX, lenY := len(strX), len(strY)
	memo := make([][]int, lenX+1)
	for i := 0; i < lenX+1; i++ {
		memo[i] = make([]int, lenY+1)
	}

	lcs := 0
	for i := 1; i < lenX+1; i++ {
		for j := 1; j < lenY+1; j++ {
			if strX[i-1] == strY[j-1] {
				memo[i][j] = memo[i-1][j-1] + 1
			} else {
				if memo[i-1][j] > memo[i][j-1] {
					memo[i][j] = memo[i-1][j]
				} else {
					memo[i][j] = memo[i][j-1]
				}
			}
			if memo[i][j] > lcs {
				lcs = memo[i][j]
			}
		}
	}
	return lcs
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

func nextText(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

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

#define rep(i, n) for (int i=0; i<(n); ++i)
using ll = long long;
using P = pair<int, int>;

const int MAX = 1003;
int dp[MAX][MAX];

int lcs(string x, string y) {
  int m = x.length();
  int n = y.length();
  x = ' ' + x;
  y = ' ' + y;
  rep(i,m+1) dp[i][0] = 0;
  rep(i,n+1) dp[0][i] = 0;

  int ans = 0;
  for (int i=1; i<=m; i++) {
    for (int j=1; j<=n; j++) {
      if (x[i] == y[j]) dp[i][j] = dp[i-1][j-1] + 1;
      else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
      //printf("[*] %d %d %d\n", i, j, dp[i][j]);
      ans = max(ans, dp[i][j]);
    }
  }

  return ans;
}

int main() {
  int n;
  cin >> n;
  string x, y;
  vector<int> ans;
  rep(i,n) {
    cin >> x;
    cin >> y;
    ans.push_back(lcs(x, y));
  }

  rep(i,ans.size()) cout << ans[i] << endl;
  return 0;
}

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

int lcs(string a,string b){
  int c[1001][1001];
  int m=a.size(),n=b.size();
  int mx=0;
  a=' '+a;
  b=' '+b;
  for(int i=1;i<=m;i++){
    for(int j=1;j<=n;j++){
      if(a[i]==b[j]){
	c[i][j]=c[i-1][j-1]+1;
      }else{
	c[i][j]=max(c[i-1][j],c[i][j-1]);
      }
      mx=max(mx,c[i][j]);
    }
  }
  return mx;
}


int main(){
  int q;
  string s1,s2;
  cin>>q;
  for(int i=0;i<q;i++){
    cin>>s1>>s2;
    cout<<lcs(s1,s2)<<endl;
  }
  return 0;
}

C++: #include <iostream>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <bitset>
#include <algorithm>
#include <complex>
#include <array>
#include <iomanip>
using namespace std;

#define REP(i,n) for(int i=0; i<n; ++i)
#define FOR(i,a,b) for(int i=a; i<=b; ++i)
#define FORR(i,a,b) for (int i=a; i>=b; --i)
#define ALL(c) (c).begin(), (c).end()

typedef long long ll;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<long double> VD;
typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VD> VVD;
typedef pair<int,int> P;
typedef pair<ll,ll> PL;

template<typename T> void chmin(T &a, T b) { if (a > b) a = b; }
template<typename T> void chmax(T &a, T b) { if (a < b) a = b; }

int in() { int x; scanf("%d", &x); return x; }
ll lin() { ll x; scanf("%lld", &x); return x; }
#define INF 1LL<<60

int main() {
    int Q;
    cin >> Q;
    REP(q, Q) {
        string X, Y;
        cin >> X >> Y;
        int len_x = X.length(), len_y = Y.length();
        vector<vector<int>> dp(len_x + 1, vector<int>(len_y + 1));

        FOR(i, 1, len_x)
             FOR(j, 1, len_y) {
                 if(X[i-1] == Y[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
                 else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
             }
             
        cout << dp[len_x][len_y] << endl;
    }
    return 0;
}

C++: #include "iostream"
#include "string.h"

using namespace std;

int L[1001][1001];

int lcs( char s1[], char s2[], int l1, int l2 ) {

	if (L[l1][l2] != 0)return L[l1][l2];

	if (l1 == 0 || l2 == 0) return 0;
	else if (s1[l1-1] == s2[l2-1]) L[l1][l2] = lcs(s1, s2, l1 - 1, l2 - 1) + 1;
	else {
		int lsc1 = lcs(s1, s2, l1 - 1, l2);
		int lsc2 = lcs(s1, s2, l1, l2 - 1);

		if (lsc1 > lsc2) L[l1][l2] = lsc1;
		else L[l1][l2] = lsc2;
	}

	return L[l1][l2];
}

int main() {

	int n;
	char s1[1000], s2[1000];

	cin >> n;

	int ans[150];

	for (int i = 0; i < n; i++) {
		cin >> s1;
		cin >> s2;

		ans[i] = lcs(s1, s2, strlen(s1), strlen(s2));
	}

	for (int i = 0; i < n; i++) {
		cout << ans[i] << endl;
	}

	return 0;
}

C++: #include<cstdio>
#include<queue>
#include<utility>
#include<cstring>
#include<stack>
#include<algorithm>
#include<cmath>
#include<iostream>
#define MAX_N 100001
#define INF 2147483647
#define REP(i,n) for(int i=0;i<(int)(n);i++)
void init(int n);
int find(int n);
void unite(int x,int y);
bool same(int x, int y);
int dx[4] = {1,0,0,-1};
int dy[4] = {0,1,-1,0};
using namespace std;

struct edge{
  int from,to,cost;
};
typedef vector<vector<edge> > AdjList;
AdjList graph;
typedef pair<int , int> P;
bool comp(const edge& e1, const edge& e2){
  return e1.cost < e2.cost;
}
int E,V;
edge es[100001];
int kruskal(){
  sort(es,es+E,comp);
  init(V);
  int res = 0;
  for(int i=0;i<E;i++){
    edge e = es[i];
    if(!same(e.to,e.from)){
      unite(e.to,e.from);
      res += e.cost;
    }
  }
  return res;
}


int main()
{
  int co=0,dp[1001][1001];
  dp[0][0] = 0;
  dp[0][1] = 0;
  dp[1][0] = 0;
  string x,y;
  cin >> co;
  REP(i,co){
    cin >> x;
    cin >> y;
    REP(i,x.length())REP(j,y.length()){
      if(i == 0 || j== 0){
        if(x[i] == y[j])
          dp[i][j] = 1;
        else
          dp[i][j] = 0;
      }
      else{if(x[i] == y[j]){
        dp[i][j] = dp[i-1][j-1]+1;
        }else{
        dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
        }
      }
    }
    cout << dp[x.length()-1][y.length()-1] << endl;
  }
  
  return 0;
}

int par[MAX_N];
int ranks[MAX_N];

//n要素で初期化
void init(int n){
  REP(i,n){
    par[i] = i;
    ranks[i] = 0;
  }

}

//木の根を求める
int find(int x){
  if(par[x] == x){
    return x;
  }else{
    return par[x] = find(par[x]);
  }
}

void unite(int x,int y){
  x = find(x);
  y = find(y);
  if(x == y) return ;
  if(ranks[x] < ranks[y]){
    par[x] = y;
  }else{
    par[y] = x;
    if(ranks[x] == ranks[y]) ranks[x]++;
  }
}

bool same(int x, int y){
  return find(x) == find(y);
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <map>
#include <queue>
using ll = long long;
using namespace std;

const ll MOD = 1e9 + 7;

int main(void)
{
    int N;
    cin >> N;

    while (N--)
    {
        string s, t;
        cin >> s >> t;

        int dp[1010][1010];
        for (int i = 0; i < 1010; ++i)
            for (int j = 0; j < 1010; ++j)
                dp[i][j] = 0;

        int n = s.size(), m = t.size();

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

                    dp[i + 1][j + 1] = max({dp[i + 1][j + 1], dp[i][j], dp[i + 1][j], dp[i][j + 1]});
                }
            }
        }

        cout << dp[n][m] << endl;
    }

    return 0;
}