using System; using static System.Console; using System.Linq; using System.Collections.Generic; using System.Security.Cryptography; class Program { static int NN => int.Parse(ReadLine()); static int[] NList => ReadLine().Split().Select(int.Parse).ToArray(); static int[][] NArr(long n) => Enumerable.Repeat(0, (int)n).Select(_ => NList).ToArray(); static string[] SList(long n) => Enumerable.Repeat(0, (int)n).Select(_ => ReadLine()).ToArray(); public static void Main() { Solve(); } static void Solve() { var a = ReadLine(); var b = ReadLine(); var alist = new List(); foreach (var ai in a) { if ('a' <= ai && ai <= 'z') alist.Add(new Info(ai)); else if (ai == '?') alist[^1].Q = true; else if (ai == '*') alist[^1].S = true; } var blist = new List(); foreach (var bi in b) { if ('a' <= bi && bi <= 'z') blist.Add(new Info(bi)); else if (bi == '?') blist[^1].Q = true; else if (bi == '*') blist[^1].S = true; } var INF = int.MaxValue / 2; var dp = new int[alist.Count + 1, blist.Count + 1]; for (var i = 0; i <= alist.Count; ++i) for (var j = 0; j <= blist.Count; ++j) dp[i, j] = INF; dp[0, 0] = 0; for (var i = 0; i < alist.Count; ++i) for (var j = 0; j < blist.Count; ++j) { if ((alist[i].Q || alist[i].S) && (blist[i].Q || blist[i].S)) { Setdp(dp, i, j + 1, dp[i, j]); Setdp(dp, i + 1, j, dp[i, j]); Setdp(dp, i + 1, j + 1, dp[i, j]); } else if (alist[i].Q) { if (alist[i].C == blist[j].C) { Setdp(dp, i, j + 1, dp[i, j] + 1); Setdp(dp, i + 1, j, dp[i, j]); Setdp(dp, i + 1, j + 1, dp[i, j]); } else { Setdp(dp, i, j + 1, dp[i, j] + 1); Setdp(dp, i + 1, j, dp[i, j]); Setdp(dp, i + 1, j + 1, dp[i, j] + 1); } } else if (alist[i].S) { if (alist[i].C == blist[j].C) { Setdp(dp, i, j + 1, dp[i, j]); Setdp(dp, i + 1, j, dp[i, j]); Setdp(dp, i + 1, j + 1, dp[i, j]); } else { Setdp(dp, i, j + 1, dp[i, j] + 1); Setdp(dp, i + 1, j, dp[i, j]); Setdp(dp, i + 1, j + 1, dp[i, j] + 1); } } else if (blist[j].Q) { if (alist[i].C == blist[j].C) { Setdp(dp, i, j + 1, dp[i, j]); Setdp(dp, i + 1, j, dp[i, j] + 1); Setdp(dp, i + 1, j + 1, dp[i, j]); } else { Setdp(dp, i, j + 1, dp[i, j]); Setdp(dp, i + 1, j, dp[i, j] + 1); Setdp(dp, i + 1, j + 1, dp[i, j] + 1); } } else if (blist[j].S) { if (alist[i].C == blist[j].C) { Setdp(dp, i, j + 1, dp[i, j]); Setdp(dp, i + 1, j, dp[i, j]); Setdp(dp, i + 1, j + 1, dp[i, j]); } else { Setdp(dp, i, j + 1, dp[i, j]); Setdp(dp, i + 1, j, dp[i, j] + 1); Setdp(dp, i + 1, j + 1, dp[i, j] + 1); } } else { if (alist[i].C == blist[j].C) { Setdp(dp, i, j + 1, dp[i, j]); Setdp(dp, i + 1, j, dp[i, j]); Setdp(dp, i + 1, j + 1, dp[i, j]); } else { Setdp(dp, i, j + 1, dp[i, j] + 1); Setdp(dp, i + 1, j, dp[i, j] + 1); Setdp(dp, i + 1, j + 1, dp[i, j] + 2); } } } for (var i = 0; i < alist.Count; ++i) { if (alist[i].Q || alist[i].S) Setdp(dp, i + 1, blist.Count, dp[i, blist.Count]); else Setdp(dp, i + 1, blist.Count, dp[i, blist.Count] + 1); } for (var j = 0; j < blist.Count; ++j) { if (blist[j].Q || blist[j].S) Setdp(dp, alist.Count, j + 1, dp[alist.Count, j]); else Setdp(dp, alist.Count, j + 1, dp[alist.Count, j] + 1); } WriteLine(dp[alist.Count, blist.Count]); } static void Setdp(int[,] dp, int tx, int ty, int setval) { dp[tx, ty] = Math.Min(dp[tx, ty], setval); } class Info { public char C; public bool Q; public bool S; public Info(char c) { C = c; } } }