## 1. Abridged Problem Statement

You are given n file names that must match and m file names that must not match (all lowercase, length ≤ 11; n, m ≤ 10). Output a single pattern (length ≤ 100) consisting of lowercase letters plus wildcards:

- `?` matches exactly one letter
- `*` matches any sequence of letters (possibly empty)

The pattern must match all of the first set and none of the second set. If impossible, output `OOPS`.

---

## 2. Detailed Editorial

### Key idea

Because all names are very short (≤ 11) and counts are tiny (≤ 20 total), we can search for a pattern that works by constructing candidate patterns and testing them against all strings.

A crucial observation used by the solution:

- Pick the shortest string among the "must match" set, call it `base`.
- Any valid pattern must match `base`.
- So we can generate patterns that are "based on" the characters of `base`, inserting wildcards in a controlled way, and whenever a partial pattern already separates the two sets, we stop.

### Wildcard matching subroutines

The code implements two matchers:

**Classic greedy glob matcher** (`match_classic`): the common algorithm for patterns with `*` and `?`:
- Walk through `pattern` and `name`.
- On `?`: consume one char from `name`.
- On letter: must match same letter.
- On `*`: remember where the star is, and allow it to "expand" if later matching fails (backtracking to last star position).
This is typically fast for short strings.

**Bitset/bitmask matcher** (`match_bitwise`): for name lengths 8..62 it uses a bitmask DP approach:
- Maintain a bitmask `mask` where bit `i` means "pattern processed so far can match the prefix of length `i`".
- For each pattern character, update `mask` accordingly.
This is a compact simulation of NFA/DP in bit operations.

The wrapper `match()` chooses bitwise for medium lengths, classic otherwise. With length ≤ 11, classic would suffice; bitwise is an optimization included in the template.

### Checking a candidate pattern

`check_all(p)` tests pattern `p` against all strings:
- For indices `< n` it must match.
- For indices `>= n` it must not match.
If any violation occurs, pattern is rejected.

### Recursive pattern construction (`rec(p, suff_to_match)`)

The solver does backtracking over `base`:

- `p` = pattern built so far
- `suff_to_match` = remaining suffix of `base` we still need to account for

Stopping conditions:
1. If `suff_to_match` is empty and `check_all(p)` succeeds → found exact solution.
2. If `check_all(p + "*")` succeeds → appending a trailing `*` makes it work; return `p + "*"`.
3. If suffix empty but not valid → fail.

Transition / branching — it loops over positions `i` in `suff_to_match` and tries to "use" `suff_to_match[i]` as the next concrete anchor character, but possibly preceded by a `*` to skip some characters:

- Always consider option `"*"+suff_to_match[i]`: allow any run of chars, then match this specific character.
- Additionally, only when `i == 0` (matching the next character immediately), also consider:
  - the literal character alone: `suff_to_match[i]`
  - a single-char wildcard: `?`

Then recurse with `p + mid` as new pattern and `suff_to_match.substr(i+1)` as remaining suffix.

This explores a reasonable set of patterns built from `base` while mixing `*`, `?`, and literals.

### Why this works within constraints

- `base` length ≤ 11, so recursion depth is small.
- Branching is limited: for each suffix position, at most 1 option (`*c`) plus up to 2 extra at `i==0`.
- Each candidate is validated by `check_all`, which is cheap (≤ 20 strings, length ≤ 11).

If recursion finds nothing: output `OOPS`.

---

## 3. C++ Solution

```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

bool match_classic(string pattern, string name) {
    int px = 0;
    int nx = 0;
    int next_px = 0;
    int next_nx = 0;
    while(px < (int)pattern.size() || nx < (int)name.size()) {
        if(px < (int)pattern.size()) {
            char c = pattern[px];
            if(c == '?') {
                if(nx < (int)name.size()) {
                    px++;
                    nx++;
                    continue;
                }
            } else if(c == '*') {
                next_px = px;
                next_nx = nx + 1;
                px++;
                continue;
            } else {
                if(nx < (int)name.size() && name[nx] == c) {
                    px++;
                    nx++;
                    continue;
                }
            }
        }
        if(0 < next_nx && next_nx <= (int)name.size()) {
            px = next_px;
            nx = next_nx;
            continue;
        }
        return false;
    }
    return true;
}

uint64_t char_masks[26];

bool match_bitwise(string pattern, string name) {
    const uint64_t mask_all = (1llu << ((uint64_t)name.size() + 1)) - 1llu;

    memset(char_masks, 0, sizeof(char_masks));
    for(uint64_t i = 0; i < (uint64_t)name.size(); i++) {
        char_masks[name[i] - 'a'] |= (1llu << i);
    }

    uint64_t mask = 1;
    for(char c: pattern) {
        if(c == '*') {
            mask = mask_all - ((mask & -mask) - 1llu);
        } else if(c == '?') {
            mask = (mask << 1llu);
        } else {
            mask = (mask & char_masks[c - 'a']) << 1llu;
        }

        mask = mask & mask_all;
        if(mask == 0) {
            return false;
        }
    }

    return mask & (1llu << (uint64_t)name.size());
}

bool match(string pattern, string name) {
    if(8 <= name.size() && name.size() <= 62) {
        return match_bitwise(pattern, name);
    } else {
        return match_classic(pattern, name);
    }
}

int n, m;
vector<string> a;

void read() {
    cin >> n >> m;
    a.resize(n + m);
    for(int i = 0; i < n + m; i++) {
        cin >> a[i];
    }
}

bool check_all(string p) {
    for(int i = 0; i < n + m; i++) {
        bool should_match = i < n;
        if(match(p, a[i]) != should_match) {
            return false;
        }
    }
    return true;
}

pair<bool, string> rec(string p, string suff_to_match) {
    if(suff_to_match.empty() && check_all(p)) {
        return {true, p};
    } else if(check_all(p + "*")) {
        return {true, p + "*"};
    } else if(suff_to_match.empty()) {
        return {false, ""};
    }

    for(int i = 0; i < (int)suff_to_match.size(); i++) {
        vector<string> options = {"*"};
        options[0].push_back(suff_to_match[i]);

        if(i == 0) {
            options.push_back(string(1, suff_to_match[i]));
            options.push_back("?");
        }

        string new_suff = suff_to_match.substr(i + 1);
        for(string mid: options) {
            auto [ok, ans] = rec(p + mid, new_suff);
            if(ok) {
                return {true, ans};
            }
        }
    }

    return {false, ""};
}

void solve() {
    // Some intuition on how globs / shell matching works is useful for this
    // problem. One good summary is: https://research.swtch.com/glob. The
    // algorithm we are going to use is the one where where we always maintain
    // the position of the last *, and whenever we fail matching, we refresh the
    // position to the last *. This is quadratic in worst case, but for the
    // given inputs works well. The core for our approach is that because all
    // inputs are short (<= 11 characters), it's likely that the answer will
    // also be short. Particularly, we can have at most 11 non-star characters.
    // And after each of them we can either have a star or not have one. There
    // is also no reason for having two stars in a row. Let's fix the shortest
    // string s in the first set. We know we have to match it, so let's try to
    // generate the set of all candidate patterns. One way is to backtrack it by
    // starting with an empty pattern, and incrementally either adding the first
    // available character, a ?, or a *. The issue comes from the fact that we
    // need to track what the "first available character" is when it comes to
    // stars. It's also unclear how to bound the complexity of this approach.
    // One way is to think of it as selecting a subset of L <= |s| characters
    // that will stay as is, then this implies that the rest of the |s| - L will
    // either be covered by a * or a ?. The naive way is that each of the |s| -
    // L characters can either be there or no, and then we have 2^(|s|+1)
    // possible gaps to put the *. This is already less than a few million, but
    // we are actually over-counting because it never makes sense to put two
    // stars in a row. This solution is fast enough to pass, but a nice
    // observation that can theoretically speed this up is to actually do a
    // bitwise wildcard matching algorithm that maintains a mask of prefixes of
    // the text that can be matched, and incrementally adds characters from the
    // pattern. However, in practice the classic greedy matching algorithm is
    // faster for this problem.

    string base = a[0];
    for(int i = 0; i < n; i++) {
        if(base.size() > a[i].size()) {
            base = a[i];
        }
    }

    auto [ok, ans] = rec("", base);
    if(ok) {
        cout << ans << endl;
    } else {
        cout << "OOPS" << endl;
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        solve();
    }

    return 0;
}
```

---

## 4. Python Solution

```python
import sys
sys.setrecursionlimit(10**7)


def match_classic(pattern: str, name: str) -> bool:
    """Greedy glob matching with backtracking to last '*'."""
    px = 0
    nx = 0
    last_star_px = -1
    next_nx_after_star = -1

    while px < len(pattern) or nx < len(name):
        if px < len(pattern):
            c = pattern[px]
            if c == '?':
                if nx < len(name):
                    px += 1
                    nx += 1
                    continue
            elif c == '*':
                last_star_px = px
                next_nx_after_star = nx + 1
                px += 1
                continue
            else:
                if nx < len(name) and name[nx] == c:
                    px += 1
                    nx += 1
                    continue

        if last_star_px != -1 and 0 <= next_nx_after_star <= len(name):
            px = last_star_px
            nx = next_nx_after_star
            next_nx_after_star += 1
            continue

        return False

    return True


def solve() -> None:
    data = sys.stdin.read().strip().split()
    if not data:
        return
    n = int(data[0])
    m = int(data[1])
    a = data[2:2 + n + m]

    base = min(a[:n], key=len)

    def check_all(p: str) -> bool:
        for i, s in enumerate(a):
            should_match = (i < n)
            if match_classic(p, s) != should_match:
                return False
        return True

    def rec(p: str, suff: str):
        if not suff and check_all(p):
            return True, p

        if check_all(p + "*"):
            return True, p + "*"

        if not suff:
            return False, ""

        for i in range(len(suff)):
            c = suff[i]
            new_suff = suff[i + 1:]

            options = ["*" + c]
            if i == 0:
                options.append(c)
                options.append("?")

            for mid in options:
                ok, ans = rec(p + mid, new_suff)
                if ok:
                    return True, ans

        return False, ""

    ok, ans = rec("", base)
    sys.stdout.write((ans if ok else "OOPS") + "\n")


if __name__ == "__main__":
    solve()
```

---

## 5. Compressed Editorial

- We need one glob pattern with `?` (one char) and `*` (any string) that matches all `n` good names and none of `m` bad names (all very small).
- Pick `base` = shortest good name. Any valid pattern must match it.
- Backtrack to build a pattern from `base`:
  - At each step, pick a next character of the remaining suffix as an "anchor".
  - Add either `'*'+anchor` (skip anything then match anchor); if using the immediate next character also try `anchor` and `?`.
  - After each build, test the whole pattern against all strings (`check_all`).
  - If `p` works, or `p+'*'` works, return it.
- Use greedy wildcard matching to evaluate a pattern against a name efficiently.
- If backtracking finds no valid pattern, print `OOPS`.
