Go: package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

const N = 1001

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func lcs(x, y string) int {
	var c [N][N]int
	m := len(x)
	n := len(y)
	var maxl int

	x = " " + x
	y = " " + y

	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if x[i] == y[j] {
				c[i][j] = c[i-1][j-1] + 1
			} else {
				c[i][j] = max(c[i-1][j], c[i][j-1])
			}
			maxl = max(maxl, c[i][j])
		}
	}
	return maxl
}

func answer(reader io.Reader) string {
	sc := bufio.NewScanner(reader)
	sc.Split(bufio.ScanWords)

	sc.Scan()
	q, _ := strconv.Atoi(sc.Text())

	var out bytes.Buffer
	for i := 0; i < q; i++ {
		sc.Scan()
		s1 := sc.Text()
		sc.Scan()
		s2 := sc.Text()
		out.WriteString(fmt.Sprintf("%d\n", lcs(s1, s2)))
	}
	return strings.TrimRight(out.String(), "\n")
}

func main() {
	fmt.Println(answer(os.Stdin))
}

C++: #include <iostream>
#include <cstring>
#include <algorithm>

#define MAX_SIZE (1000 + 10)

int A[MAX_SIZE][MAX_SIZE];
char X[MAX_SIZE];
char Y[MAX_SIZE];

int main()
{
  int N, m, n;
  std::cin >> N;

  for (int q = 0; q < N; ++q)
  {
    std::cin >> X >> Y;
    m = strlen(X);
    n = strlen(Y);
    for (int i = 1; i <= m; ++i)
    {
      for (int j = 1; j <= n; ++j)
      {
        if (X[i - 1] == Y[j - 1])
        {
          A[i][j] = A[i - 1][j - 1] + 1;
        }
        else
        {
          A[i][j] = std::max(A[i][j - 1], A[i - 1][j]);
        }
      }
    }

    std::cout << A[m][n] << std::endl;
  }

  return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
// define
#define int long long
#define UNIQUE(v) v.erase(unique(all(v)), v.end());
#define ZIP(v) sort(all(v)),UNIQUE(v)
#define ADD(a, b) a = (a + b) % mod
#define SUB(a, b) a = (a+mod-b)%mod
#define MUL(a, b) a = (((a)%mod) * ((b)%mod)) % mod
#define rollcall cout << "I'm Sucu." << endl;
#define repi(i,m,n) for(int i = m;i < n;i++)
#define drep(i,n,m) for(int i = n;i >= m;i--)
#define rep(i,n) repi(i,0,n)
#define rrep(i,n) repi(i,1,n+1)
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(), v.rend()
#define dmp(x,y) make_pair(x,y)
#define dmt(x, y, z) make_tuple(x, y, z)
#define pb(x) push_back(x)
#define pf(x) push_front(x)
#define fi first
#define se second
// debug
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
  os << "(" << p.first << "," << p.second << ")";return os;
}
template <typename T, typename U, typename V>
ostream &operator<<(ostream &os, const tuple<T, U, V> &t){
  os << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ")";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
  for (auto it = v.begin();it != v.end();++it){
    if(it != v.begin())os << " ";os << *it;
  }return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &mp){
  for(auto x: mp)os << "(" << x.first << "," << x.second << ")" << endl;
  return os;
}
template<typename T, int SIZE>
int array_length(const T (&)[SIZE]){return SIZE;}
template<typename T, int N>
void PRINTF(const T (&a)[N], int s = N, int t = -1, bool f = true){
	if(t == -1){rep(i,s){if(i)cout << " ";cout << a[i];}}
	else repi(i,s,t){if(i!=s)cout << " ";cout << a[i];}
	if(f)cout << "\n";
}
template<typename T, int N1, int N2>
void PRINTF(const T (&a)[N1][N2], int h = N1, int w = N2){
	rep(i,h){rep(j,w){cout << a[i][j] << " \n"[j==w-1];}}
}
string substr(const string &str, int S1, int S2 = -1){
  if(S2 == -1)return str.substr(S1);
  return str.substr(S1, S2-S1);
}
// typedef
typedef complex<double> Point;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<P, int> Pi;
typedef tuple<int, int, int> TT;
typedef pair<int, TT> PT;
typedef vector<int> vi;
typedef deque<int> dq;
const int inf = 1e9+7;
const int INF = 1e18+7;
// int sum = accumulate(a, a+n, 0LL);
// int mx = max_element(a, a+n);
// int mn = min_element(a, a+n);
// int cnt = count(a, a+n, k);

int dp[2000][2000];
signed main(){
  int n;cin >> n;
  rep(i,n){
    string s1, s2;cin >> s1 >> s2;
    s1 = " " + s1;s2 = " " + s2;
    int ans = 0;
    rep(j,2000)rep(k,2000)dp[j][k] = 0;
    rrep(j,s1.size()-1)rrep(k,s2.size()-1){
      if(s1[j] == s2[k])dp[j][k] = dp[j-1][k-1] + 1;
      else dp[j][k] = max(dp[j-1][k], dp[j][k-1]);
      // if(j == 5 and k == 5)cout << dp[j][k] << endl;
      ans = max(ans, dp[j][k]);
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include<bits/stdc++.h>
#define REP(i,n) for(long long i=0;i<n;++i)
#define FOR(i,a,b) for(long long i=a;i<b;++i)
using namespace std;
int main(){
    int q;
    scanf("%d",&q);
    string x,y;
    REP(i,q){
        cin>>x>>y;
        int dp[x.size()+1][y.size()+1];
        fill(dp[0],dp[y.size()],-1);
        REP(j,x.size()+1){
            REP(k,y.size()+1){
                if(j==0||k==0) dp[j][k]=0;
                else if(x[j]==y[k]) dp[j][k]=dp[j-1][k-1]+1;
                else dp[j][k]=max(dp[j][k-1],dp[j-1][k]);
            }
        }
        printf("%d\n",dp[x.size()][y.size()]);
    }
    return 0;
}