<p>An original string, consisting of lowercase English letters, can be encoded by the following steps:</p>

<ul>
	<li>Arbitrarily <strong>split</strong> it into a <strong>sequence</strong> of some number of <strong>non-empty</strong> substrings.</li>
	<li>Arbitrarily choose some elements (possibly none) of the sequence, and <strong>replace</strong> each with <strong>its length</strong> (as a numeric string).</li>
	<li><strong>Concatenate</strong> the sequence as the encoded string.</li>
</ul>

<p>For example, <strong>one way</strong> to encode an original string <code>&quot;abcdefghijklmnop&quot;</code> might be:</p>

<ul>
	<li>Split it as a sequence: <code>[&quot;ab&quot;, &quot;cdefghijklmn&quot;, &quot;o&quot;, &quot;p&quot;]</code>.</li>
	<li>Choose the second and third elements to be replaced by their lengths, respectively. The sequence becomes <code>[&quot;ab&quot;, &quot;12&quot;, &quot;1&quot;, &quot;p&quot;]</code>.</li>
	<li>Concatenate the elements of the sequence to get the encoded string: <code>&quot;ab121p&quot;</code>.</li>
</ul>

<p>Given two encoded strings <code>s1</code> and <code>s2</code>, consisting of lowercase English letters and digits <code>1-9</code> (inclusive), return <code>true</code><em> if there exists an original string that could be encoded as <strong>both</strong> </em><code>s1</code><em> and </em><code>s2</code><em>. Otherwise, return </em><code>false</code>.</p>

<p><strong>Note</strong>: The test cases are generated such that the number of consecutive digits in <code>s1</code> and <code>s2</code> does not exceed <code>3</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s1 = &quot;internationalization&quot;, s2 = &quot;i18n&quot;
<strong>Output:</strong> true
<strong>Explanation:</strong> It is possible that &quot;internationalization&quot; was the original string.
- &quot;internationalization&quot; 
  -&gt; Split:       [&quot;internationalization&quot;]
  -&gt; Do not replace any element
  -&gt; Concatenate:  &quot;internationalization&quot;, which is s1.
- &quot;internationalization&quot;
  -&gt; Split:       [&quot;i&quot;, &quot;nternationalizatio&quot;, &quot;n&quot;]
  -&gt; Replace:     [&quot;i&quot;, &quot;18&quot;,                 &quot;n&quot;]
  -&gt; Concatenate:  &quot;i18n&quot;, which is s2
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s1 = &quot;l123e&quot;, s2 = &quot;44&quot;
<strong>Output:</strong> true
<strong>Explanation:</strong> It is possible that &quot;leetcode&quot; was the original string.
- &quot;leetcode&quot; 
  -&gt; Split:      [&quot;l&quot;, &quot;e&quot;, &quot;et&quot;, &quot;cod&quot;, &quot;e&quot;]
  -&gt; Replace:    [&quot;l&quot;, &quot;1&quot;, &quot;2&quot;,  &quot;3&quot;,   &quot;e&quot;]
  -&gt; Concatenate: &quot;l123e&quot;, which is s1.
- &quot;leetcode&quot; 
  -&gt; Split:      [&quot;leet&quot;, &quot;code&quot;]
  -&gt; Replace:    [&quot;4&quot;,    &quot;4&quot;]
  -&gt; Concatenate: &quot;44&quot;, which is s2.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> s1 = &quot;a5b&quot;, s2 = &quot;c5b&quot;
<strong>Output:</strong> false
<strong>Explanation:</strong> It is impossible.
- The original string encoded as s1 must start with the letter &#39;a&#39;.
- The original string encoded as s2 must start with the letter &#39;c&#39;.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s1.length, s2.length &lt;= 40</code></li>
	<li><code>s1</code> and <code>s2</code> consist of digits <code>1-9</code> (inclusive), and lowercase English letters only.</li>
	<li>The number of consecutive digits in <code>s1</code> and <code>s2</code> does not exceed <code>3</code>.</li>
</ul>

class Solution:
    def possiblyEquals(self, s1: str, s2: str) -> bool:
        n1,n2 = len(s1),len(s2)

        @cache
        def gethelp(n):
            n1 = len(str(n))
            ans = []
            if n1==1:
                return [n]
            elif n1==2:
                return [n//10 + n%10,n]
            else:
                return [n//100 + (n//10)%10 + n%10,n//10 + n%10,n//100 + n%100,n]
            return []

        @cache
        def helper2(type,ind,l):
            s = ""
            if type==1:
                s = s1
            else:
                s = s2
            if ind==len(s):
                return (l==0)
            if l<0:
                return False
            if s[ind].isalpha():
                return helper2(type,ind+1,l-1)
            t,i = 0,min(len(s),ind+3)
            flag = False
            for j in range(ind,ind+3):
                if j==len(s) or s[j].isalpha():
                    i = j
                    break
                t = t*10 + int(s[j])
            lt = gethelp(t)
            for it in lt:
                flag |= helper2(type,i,l-it)
            return flag

        @cache
        def helper(i1,i2,left):
            # print(i1,i2,left)
            if i1==n1 and i2==n2:
                return (left==0)
            if i1==n1:
                if left<=0:
                    return False
                return helper2(2,i2,left)
            if i2==n2:
                if left>=0:
                    return False
                return helper2(1,i1,-left)

            flag = False
            if s1[i1].isalpha() and s2[i2].isalpha():
                if left>0:
                    flag |= helper(i1,i2+1,left-1)
                elif left<0:
                    flag |= helper(i1+1,i2,left+1)
                else:
                    flag |= (s1[i1]==s2[i2] and helper(i1+1,i2+1,left))
                return flag
            t1,t2,ind1,ind2 = 0,0,n1,n2
            l1,l2 = [],[]
            if s1[i1].isnumeric():
                t2,ind1 = 0,min(i1+3,n1)
                for i in range(i1,i1+3):
                    if i==n1 or s1[i].isalpha():
                        ind1 = i
                        break
                    t1 = t1*10 + int(s1[i])
                l1 = gethelp(t1)

            if s2[i2].isnumeric():
                t2,ind2 = 0,min(i2+3,n2)
                for i in range(i2,i2+3):
                    if i==n2 or s2[i].isalpha():
                        ind2 = i
                        break
                    t2 = t2*10 + int(s2[i])
                l2 = gethelp(t2)

            if s1[i1].isnumeric() and s2[i2].isnumeric():
                for i in l1:
                    for j in l2:
                        flag |= helper(ind1,ind2,left+i-j)
            elif s1[i1].isalpha() and s2[i2].isnumeric():
                for i in l2:
                    flag |= helper(i1,ind2,left-i)
            elif s2[i2].isalpha() and s1[i1].isnumeric():
                for i in l1:
                    flag |= helper(ind1,i2,left+i)

            return flag
        return helper(0,0,0)


1547