#include <bits/stdc++.h>
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
using namespace std;
long long A[500006];
long long B[500006];
long long C[500006];
vector<long long> V;
vector<long long> Ans;
vector<pair<long long, long long> > VP;
map<long long, long long> M;
vector<long long> prime;
bool mark[10000008];
long long N = 1e7;
void seive() {
  int limit = sqrt(N * 1.0) + 2;
  mark[1] = 1;
  for (int i = 4; i <= N; i += 2) mark[i] = 1;
  prime.push_back(2);
  for (int i = 3; i <= N; i += 2) {
    if (!mark[i]) {
      prime.push_back(i);
      if (i <= limit) {
        for (int j = i * i; j <= N; j += i * 2) mark[j] = 1;
      }
    }
  }
}
string s, s1, s3, s4;
int lookup[5100][5100], res;
int dp[5100][5100], mod = 1000000007;
void lcs(int n, int m) {
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (i == 0 || j == 0) lookup[i][j] = 0;
      lookup[i][j] = max(lookup[i - 1][j] - 1, lookup[i][j]);
      lookup[i][j] = max(lookup[i][j - 1] - 1, lookup[i][j]);
      if (s[i - 1] == s1[j - 1]) lookup[i][j] = lookup[i - 1][j - 1] + 2;
    }
  }
}
int main() {
  long long a, n, m, b, c, d, k, l, p, q, r, t, x, y;
  long long cnt = 0, cntr = 0, sum = 0, check = 0;
  cin >> n >> m;
  cin >> s >> s1;
  n = s.size();
  m = s1.size();
  memset(lookup, 0, sizeof(lookup));
  lcs(n, m);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      sum = max((int)sum, lookup[i][j]);
    }
  }
  cout << sum << endl;
  return 0;
}
