During a normal walk in the forest, Katie has stumbled upon a mysterious code! However, the mysterious code had some characters unreadable. She has written down this code as a string c consisting of lowercase English characters and asterisks ("*"), where each of the asterisks denotes an unreadable character. Excited with her discovery, Katie has decided to recover the unreadable characters by replacing each asterisk with arbitrary lowercase English letter (different asterisks might be replaced with different letters).

Katie has a favorite string s and a not-so-favorite string t and she would love to recover the mysterious code so that it has as many occurrences of s as possible and as little occurrences of t as possible. Formally, let's denote f(x, y) as the number of occurrences of y in x (for example, f(aababa, ab) = 2). Katie wants to recover the code c' conforming to the original c, such that f(c', s) - f(c', t) is largest possible. However, Katie is not very good at recovering codes in general, so she would like you to help her out.

Input

The first line contains string c (1 ≤ |c| ≤ 1000) — the mysterious code . It is guaranteed that c consists of lowercase English characters and asterisks "*" only.

The second and third line contain strings s and t respectively (1 ≤ |s|, |t| ≤ 50, s ≠ t). It is guaranteed that s and t consist of lowercase English characters only.

Output

Print a single integer — the largest possible value of f(c', s) - f(c', t) of the recovered code.

Examples

Input


*****
katie
shiro


Output


1


Input


caat
caat
a


Output


-1


Input


*a*
bba
b


Output


0


Input


***
cc
z


Output


2

Note

In the first example, for c' equal to "katie" f(c', s) = 1 and f(c', t) = 0, which makes f(c', s) - f(c', t) = 1 which is the largest possible.

In the second example, the only c' conforming to the given c is "caat". The corresponding f(c', s) - f(c', t) = 1 - 2 = -1.

In the third example, there are multiple ways to recover the code such that f(c', s) - f(c', t) is largest possible, for example "aaa", "aac", or even "zaz". The value of f(c', s) - f(c', t) = 0 for all of these recovered codes.

In the fourth example, the optimal recovered code c' would be "ccc". The corresponding f(c', s) - f(c', t) = 2.
import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

// fail

public class cf1163d {

    public static void main(String[] args) throws IOException {
        char[] c = rcha(), s = rcha(), t = rcha();
        /* if (kmp(s, t).size() != 0) {
            prln(kmp(c, s).size() - kmp(c, t).size());
            close();
            return;
        } */
        int n = c.length, m = s.length, r = t.length, dp[][][] = new int[n + 1][m + 1][r + 1], pi_s[] = pi(s), pi_t[] = pi(t), nxt_s[][] = new int[m + 1][26], nxt_t[][] = new int[r + 1][26];
        for (int[][] layer : dp) {
            for (int[] row : layer) {
                fill(row, -IBIG);
            }
        }
        nxt_s[0][s[0] - 'a'] = 1;
        for (int i = 1; i <= m; ++i) {
            for (char ch = 'a'; ch <= 'z'; ++ch) {
                int cur = i;
                while (cur != 0 && (cur == m || ch != s[cur])) {
                    cur = pi_s[cur - 1];
                }
                if (ch == s[cur]) {
                    ++cur;
                }
                nxt_s[i][ch - 'a'] = cur;
            }
        }
        nxt_t[0][t[0] - 'a'] = 1;
        for (int i = 1; i <= r; ++i) {
            for (char ch = 'a'; ch <= 'z'; ++ch) {
                int cur = i;
                while (cur != 0 && (cur == r || ch != t[cur])) {
                    cur = pi_t[cur - 1];
                }
                if (ch == t[cur]) {
                    ++cur;
                }
                nxt_t[i][ch - 'a'] = cur;
            }
        }
        dp[0][0][0] = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j <= m; ++j) {
                for (int k = 0; k <= r; ++k) {
                    if (dp[i][j][k] != -IBIG) {
                        for (char ch = 'a'; ch <= 'z'; ++ch) {
                            if (c[i] == '*' || c[i] == ch) {
                                int nxt_j = nxt_s[j][ch - 'a'], nxt_k = nxt_t[k][ch - 'a'];
                                dp[i + 1][nxt_j][nxt_k] = max(dp[i + 1][nxt_j][nxt_k], dp[i][j][k] + (nxt_j == m ? 1 : 0) - (nxt_k == r ? 1: 0));
                            }
                        }
                    }
                }
            }
        }
        /* for (int[][] layer : dp) {
            for (int[] row : layer) {
                prln(row);
            }
            prln();
        } */
        int ans = -IBIG;
        for (int[] row : dp[n]) {
            ans = max(ans, maxof(row));
        }
        prln(ans);
        close();
    }

    // pi[i] = longest proper prefix that is also a suffix of s[:i + 1]
    static int[] pi(char[] s) {
        int len = 0, i = 1, pi[] = new int[s.length];
        while (i < s.length) {
            if (s[i] == s[len]) {
                pi[i++] = ++len;
            } else if (len != 0) {
                len = pi[len - 1];
            } else {
                pi[i++] = len;
            }
        }
        return pi;
    }

    // kmp(str, pattern) returns indices of matches (ind of 1st char)
    static List<Integer> kmp(char[] str, char[] pat) {
        List<Integer> ans = new ArrayList<>();
        int len = 0, i = 1, j = 0, lps[] = new int[pat.length];
        while (i < pat.length) {
            if (pat[i] == pat[len]) {
                lps[i++] = ++len;
            } else if (len != 0) {
                len = lps[len - 1];
            } else {
                lps[i++] = len;
            }
        }
        i = 0;
        while (i < str.length) {
            if (str[i] == pat[j]) {
                ++i;
                ++j;
            }
            if (j == pat.length) {
                ans.add(i - j);
                j = lps[j - 1];
            } else if (i < str.length && str[i] != pat[j]) {
                if (j == 0) {
                    ++i;
                } else {
                    j = lps[j - 1];
                }
            }
        }
        return ans;
    }

    static BufferedReader __i = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __o = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;
    static Random __r = new Random();

    // references
    // IBIG = 1e9 + 7
    // IMAX ~= 2e9
    // LMAX ~= 9e18

    // constants
    static final int IBIG = 1000000007;
    static final int IMAX = 2147483647;
    static final long LMAX = 9223372036854775807L;
    // math util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); int min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); long min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); int max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); long max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static int powi(int a, int b) {if (a == 0) return 0; int ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if (a == 0) return 0; long ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int fli(double d) {return (int) d;}
    static int cei(double d) {return (int) ceil(d);}
    static long fll(double d) {return (long) d;}
    static long cel(double d) {return (long) ceil(d);}
    static int gcf(int a, int b) {return b == 0 ? a : gcf(b, a % b);}
    static long gcf(long a, long b) {return b == 0 ? a : gcf(b, a % b);}
    static int[] exgcd(int a, int b) {if (b == 0) return new int[] {1, 0}; int[] y = exgcd(b, a % b); return new int[] {y[1], y[0] - y[1] * (a / b)};}
    static long[] exgcd(long a, long b) {if (b == 0) return new long[] {1, 0}; long[] y = exgcd(b, a % b); return new long[] {y[1], y[0] - y[1] * (a / b)};}
    static int randInt(int min, int max) {return __r.nextInt(max - min + 1) + min;}
    static long mix(long x) {x += 0x9e3779b97f4a7c15L; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9L; x = (x ^ (x >> 27)) * 0x94d049bb133111ebL; return x ^ (x >> 31);}
    // array util
    static void reverse(int[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {int swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(long[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {long swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(double[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {double swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(char[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {char swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void shuffle(int[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); int swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(long[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); long swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(double[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); double swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void rsort(int[] a) {shuffle(a); sort(a);}
    static void rsort(long[] a) {shuffle(a); sort(a);}
    static void rsort(double[] a) {shuffle(a); sort(a);}
    static int[] copy(int[] a) {int[] ans = new int[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static long[] copy(long[] a) {long[] ans = new long[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static double[] copy(double[] a) {double[] ans = new double[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static char[] copy(char[] a) {char[] ans = new char[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    // input
    static void r() throws IOException {input = new StringTokenizer(rline());}
    static int ri() throws IOException {return Integer.parseInt(rline());}
    static long rl() throws IOException {return Long.parseLong(rline());}
    static double rd() throws IOException {return Double.parseDouble(rline());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni(); return a;}
    static int[] riam1(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni() - 1; return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; r(); for (int i = 0; i < n; ++i) a[i] = nl(); return a;}
    static double[] rda(int n) throws IOException {double[] a = new double[n]; r(); for (int i = 0; i < n; ++i) a[i] = nd(); return a;}
    static char[] rcha() throws IOException {return rline().toCharArray();}
    static String rline() throws IOException {return __i.readLine();}
    static String n() {return input.nextToken();}
    static int rni() throws IOException {r(); return ni();}
    static int ni() {return Integer.parseInt(n());}
    static long rnl() throws IOException {r(); return nl();}
    static long nl() {return Long.parseLong(n());}
    static double rnd() throws IOException {r(); return nd();}
    static double nd() {return Double.parseDouble(n());}
    // output
    static void pr(int i) {__o.print(i);}
    static void prln(int i) {__o.println(i);}
    static void pr(long l) {__o.print(l);}
    static void prln(long l) {__o.println(l);}
    static void pr(double d) {__o.print(d);}
    static void prln(double d) {__o.println(d);}
    static void pr(char c) {__o.print(c);}
    static void prln(char c) {__o.println(c);}
    static void pr(char[] s) {__o.print(new String(s));}
    static void prln(char[] s) {__o.println(new String(s));}
    static void pr(String s) {__o.print(s);}
    static void prln(String s) {__o.println(s);}
    static void pr(Object o) {__o.print(o);}
    static void prln(Object o) {__o.println(o);}
    static void prln() {__o.println();}
    static void pryes() {prln("yes");}
    static void pry() {prln("Yes");}
    static void prY() {prln("YES");}
    static void prno() {prln("no");}
    static void prn() {prln("No");}
    static void prN() {prln("NO");}
    static boolean pryesno(boolean b) {prln(b ? "yes" : "no"); return b;};
    static boolean pryn(boolean b) {prln(b ? "Yes" : "No"); return b;}
    static boolean prYN(boolean b) {prln(b ? "YES" : "NO"); return b;}
    static void prln(int... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(long... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(double... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for (int i = 0; i < n; pr(iter.next()), pr(' '), ++i); if (n >= 0) prln(iter.next()); else prln();}
    static void h() {prln("hlfd"); flush();}
    static void flush() {__o.flush();}
    static void close() {__o.close();}
}