jiahuimbzuai/CoQuIR huggingface dataset:
//  [java]
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    char[] s, t;

    public static void main(String args[]) {
        new Main().run();
    }

    void run() {
        FastReader sc = new FastReader();
        s = sc.next().toCharArray();
        t = sc.next().toCharArray();
        solve();
    }

    void solve() {
        char[] ans = s.clone();
        boolean replaceSub = false;
        for (int i = s.length - 1; i >= 0; i--) {
            boolean flag = true;
            if (i + t.length > s.length) {
                flag = false;
            } else {
                for (int j = i; j < i + t.length; j++) {
                    if (s[j] != t[j - i] && s[j] != '?') {
                        flag = false;
                        break;
                    }
                }
            }
            if (flag) {
                for (int j = i; j < i + t.length; j++) {
                    ans[j] = t[j - i];
                }
                replaceSub = true;
                break;
            }
        }
        if (replaceSub) {
            System.out.println((new String(ans)).replace('?', 'a'));
        } else {
            System.out.println("UNRESTORABLE");
        }
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt()
        {
            return Integer.parseInt(next());
        }

        long nextLong()
        {
            return Long.parseLong(next());
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
    }
}
//  [java]
import java.io.IOException;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import java.io.PrintWriter;

@SuppressWarnings("unchecked")
public class Main {
    static final char Q = '?';
    static final char A = 'a';

    public static void main(String[] args) throws IOException {
        final String S;
        final String T;

        StringBuilder sb = new StringBuilder();

        try (
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(System.in))) {
            S = reader.readLine();
            T = reader.readLine();
            sb.append(S);
        }

        PrintWriter out = new PrintWriter(System.out);

        int sl = sb.length();
        int tl = T.length();

        boolean flg = false;
        for (int i = sl - tl; 0 <= i; i--) {
            flg = true;

            for (int j = 0; j < tl; j++) {
                char sat = sb.charAt(i + j);
                char tat = T.charAt(j);
                if ((Q != sat) && sat != tat) {
                    flg = false;
                    break;
                }
            }

            if (flg) {
                sb.replace(i, i + tl, T);
                break;
            }
        }

        for (int i = 0; i < sl; i++)
            if (Q == sb.charAt(i)) sb.setCharAt(i, A);

        out.println(flg ? sb : "UNRESTORABLE");

        out.flush();
    }
}
//  [java]
import java.io.InputStream;
import java.io.PrintStream;
import java.util.*;

public class Main {

  public static void main(String[] args) {
    solve(System.in, System.out);
  }

  static void solve(InputStream is, PrintStream os) {
    Scanner sc = new Scanner(is);

    /* read */
    String s = sc.next();
    String t = sc.next();

    String ans = "";

    List<String> candidate = new ArrayList<>();
    for (int i = 0; i + t.length() <= s.length(); i++) {
      if (ok(s.substring(i, i + t.length()), t)) {
        candidate.add(generateCandidate(s, t, i));
      }
    }

    candidate.sort(String::compareTo);

    if (candidate.isEmpty()) {
      os.println("UNRESTORABLE");
    } else {
      os.println(candidate.get(0));
    }
  }

  private static boolean ok(String s, String t) {
    for (int i = 0; i < t.length(); i++) {
      if (s.charAt(i) != t.charAt(i) && s.charAt(i) != '?') return false;
    }
    return true;
  }

  private static String generateCandidate(String s, String t, int start) {
    String ans = "";
    for (int i = 0; i < start; i++) {
      if (s.charAt(i) == '?') ans += "a";
      else ans += String.valueOf(s.charAt(i));
    }
    ans += t;
    for (int i = start + t.length(); i < s.length(); i++) {
      if (s.charAt(i) == '?') ans += "a";
      else ans += String.valueOf(s.charAt(i));
    }
    return ans;
  }
}
//  [java]
import java.util.Scanner;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String Sp = sc.next();
        String T = sc.next();

        System.out.println(solve(Sp, T));

        sc.close();
    }

    static String solve(String Sp, String T) {
        for (int i = Sp.length() - T.length(); i >= 0; --i) {
            int i_ = i;
            if (IntStream.range(0, T.length())
                    .allMatch(j -> Sp.charAt(i_ + j) == '?' || Sp.charAt(i_ + j) == T.charAt(j))) {
                return String.format("%s%s%s", Sp.substring(0, i), T, Sp.substring(i + T.length())).replace('?', 'a');
            }
        }

        return "UNRESTORABLE";
    }
}
//  [java]
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		String sd = sc.nextLine();
		String t = sc.nextLine();
		int ls = sd.length();
		int lt = t.length();
		String S = "";
		int k = -1;

		LOOP: for (int i = ls - lt; i >= 0; i--) {
			for (int j = 0; j < lt; j++) {
				char sdi = sd.charAt(i + j);
				if (sdi != '?' && sdi != t.charAt(j)) {
					continue LOOP;
				}

			}
			k=i;
			break;
		}
		if(k==-1) {
			System.out.println("UNRESTORABLE");
			return;
		}
		S=S.concat(sd.substring(0, k));
		S=S.concat(t);
		S=S.concat(sd.substring(k + lt));
		S=S.replace('?', 'a');
		System.out.println(S);
	}
}
//  [cpp]
#include <cstdio>
#include <cstring>
char s[100], t[100];
int main() {
  scanf("%s%s", s, t);
  int n = strlen(s), m = strlen(t);
  for (int i = n - m; ~i; --i) {
    int j;
    for (j = 0; j < m; ++j)
      if (s[i + j] != t[j] && s[i + j] != '?') break;
    if (j >= m) {
      for (int j = 0; j < i; ++j) putchar((s[j] == '?') ? 'a' : s[j]);
      for (int j = 0; j < m; ++j) putchar(t[j]);
      for (int j = i + m; j < n; ++j) putchar((s[j] == '?') ? 'a' : s[j]);
      return 0;
    }
  }
  puts("UNRESTORABLE");
  return 0;
}
//  [cpp]
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
char s[100],t[100];
int main()
{
	scanf("%s",s);
	n=strlen(s);
	scanf("%s",t);
	m=strlen(t);
	for(int i=n-m;i>=0;i--)
	{
		for(int j=0;j<=m;j++)
		{
			if(j==m)
			{
				for(int l=0;l<i;l++)
				{
					if(s[l]!='?')
						printf("%c",s[l]);
					else
						printf("a");
				}
				for(int l=0;l<m;l++)
					printf("%c",t[l]);
				for(int l=i+m;l<n;l++)
				{
					if(s[l]!='?')
						printf("%c",s[l]);
					else
						printf("a");
				}
				return 0;
			}
			if(s[i+j]=='?')
				continue;
			else
				if(s[i+j]!=t[j])
					break;
		}
	}
	printf("UNRESTORABLE");
	return 0;
}
//  [cpp]
#include <bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
#define reps(i,s,n) for(int (i)=(s);(i)<(n);++(i))
#define rep(i,n) reps(i,0,n)
#define reptr(i,n) for(int (i)=(n);(i)>=0;--(i))
#define All(x) (x).begin(),(x).end()
#define mp make_pair
#define pb push_back
const ll MOD=1e9+7;
using namespace std;

int main(){
  string s,t;
  cin >> s >> t;
  bool flag = false;
  //答えとなりそうな文字列
  vector<string> ans;
  rep(i,s.size()-t.size()+1){
    string tmp = s.substr(i,t.size());
    int j = 0;
    while(j < t.size()){
      if(tmp[j]==t[j] || tmp[j]=='?'){
        j++;
      }else{
        break;
      }
    }
    if(j==t.size()){
      string key = s;
      for(int k=i;k<i+t.size();k++){
        if(key[k]=='?'){
          key[k] = t[k-i];
        }
      }
      for(int k=0;k<key.size();k++){
        if(key[k]=='?'){
          key[k] = 'a';
        }
      }
      ans.push_back(key);
      flag = true;
    }
  }
  if(!flag){
    cout << "UNRESTORABLE" << endl;
    return 0;
  }
  sort(All(ans));
  cout << ans[0] << endl;
}
//  [cpp]
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <map>
#include <algorithm>

using namespace std;

bool match(const string& S_, const string& T, size_t pos)
{
  for (size_t i = 0, j = pos; i < T.size(); ++i, ++j) {
    if (S_[j] != '?' and S_[j] != T[i]) return false;
  }
  return true;
}

bool larger(const string& S1, const string& S2)
{
  if (S1 == "") return true;
  for (size_t i = 0; i < S1.size(); ++i) if (S1[i] > S2[i]) return true;
  return false;
}

string generate(string S, const string& T, size_t pos)
{
  size_t i = 0;
  for (; i < pos; ++i) if (S[i] == '?') S[i] = 'a';
  for (size_t j = 0; j < T.size(); ++i, ++j) S[i] = T[j];
  for (; i < S.size(); ++i) if (S[i] == '?') S[i] = 'a';
  return S;
}

string solve(const string& S_, const string& T)
{
  if (T.size() > S_.size()) return "UNRESTORABLE";
  string S = "";
  for (size_t i = 0; i <= S_.size() - T.size(); ++i) {
    if (match(S_, T, i)) {
      string s = generate(S_, T, i);
      if (larger(S, s)) S = s;
    }
  }
  if (S == "") return "UNRESTORABLE";
  return S;
}

int main()
{
  string S_, T;
  cin >> S_ >> T;
  cout << solve(S_, T) << endl;
  return 0;
}
//  [cpp]
#include <bits/stdc++.h>
#define fast ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL)
#define ll long long int
using namespace std;
const int N= 1e5;

bool check(string s, string cs){
  if((int)s.size() != (int)cs.size())
    return 0;
  for(int i = 0; i < (int)s.size(); i++){
    if(s[i] != '?' && s[i] != cs[i]){
      return 0;
    }
  }
  return 1;
}
int main(){ 
    fast;
    string s, t, cs, ans;
    cin >> s >> t;
    ans += '{';
    for(int i = 0; i < (int)s.size(); i++){
      cs.clear();
      for(int j = 0; j < i; j++){
        if(s[j] == '?')
          cs += 'a';
        else
          cs += s[j];
      }
      cs += t;
      for(int j = (int)cs.size(); j < (int)s.size(); j++){
        if(s[j] == '?')
          cs += 'a';
        else
          cs += s[j];
      }
      //cout << cs << "\n";
      if(check(s, cs))
        ans = min (ans, cs);
    }
    //cout << ans;
    if(ans != "{")
    cout << ans;
    else
      cout << "UNRESTORABLE";
    return 0;
}
//  [c]
#include<stdio.h>

int sl=0, tl=0;
char s[51], t[51];

void restore(int idx){
        for(int i=0; i<sl; i++){
                if(idx<=i && i<idx+tl) s[i] = t[i-idx];
                else if(s[i]=='?') s[i] = 'a';
        }
}

int main(void){
        while((s[sl]=getchar())!='\n') sl++;
        while((t[tl]=getchar())!='\n') tl++;

        int idx = -1;
        for(int i=0; i<=sl-tl; i++){
                int can = 1;
                for(int j=0; j<tl; j++){
                        if(s[i+j]!=t[j] && s[i+j]!='?') can = 0;
                }
                if(can) idx = i;
        }

        if(idx>=0){
                restore(idx);
                printf("%s", s);
        }else puts("UNRESTORABLE");
        return 0;
}
//  [c]
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void){
    char sd[52] = "0000000000000000000000000000000000000000000000000000";
    char t[52] = "0000000000000000000000000000000000000000000000000000";
    scanf("%s",sd);
    scanf("%s",t);
    int i;
    int lent;
    for(i=0;i<52;i++){
        if(t[i]<'a' || t[i]>'z'){
            lent = i;
            break;
        }
    }
    int lensd;
    for(i=0;i<52;i++){
        if((sd[i]<'a' || sd[i]>'z') && (sd[i] != '?')){
            lensd = i;
            break;
        }
    }
    int j;
    int hairu = 0;
    for(i=lensd-lent;i>=0;i--){
        int muri = 0;
        for(j=i;j<i+lent;j++){
            if(sd[j] != '?'){
                if(sd[j] != t[j-i]){
                    muri++;
                }
            }
        }
        if(muri == 0){
            hairu = i;
            goto UNKO;
        }
    }
    printf("UNRESTORABLE");
    printf("\n");
    return 0;
UNKO:
    for(i = hairu; i<hairu+lent;i++){
        sd[i] = t[i-hairu];
    }
    for(i=0;i<52;i++){
        if(sd[i] == '?'){
            sd[i] = 'a';
        }
    }
    printf("%s",sd);
    printf("\n");
    return 0;
}
//  [c]
#include <stdio.h>
#include <string.h>

int main() {

	char s_dash[51];
	char s[51];
	char t[51];

	int i = 0;
	int j = 0;
	int k = 0;
	int l = 0;
	int m = 0; // iは文章中の位置、jは検索文字列中の位置
	int flag = 0;
	int len_s = 0;
	int len_t = 0;

	scanf("%s", s_dash);
	scanf("%s", t);
	
	//printf("%s", s_dash);

	strcpy(s, s_dash);


	len_s = strlen(s_dash);
	len_t = strlen(t);

	//printf("%d\n", len_s);
	//printf("%d\n", len_t);
	//printf("%d", i);

	while (i <= (len_s - len_t)) {
		//printf("%d", i);
		j = 0;
		while (j < len_t && (s_dash[i+j] == t[j] || s_dash[i+j] == '?')) {
			//printf("%d", j);
			j += 1;
			if (j == len_t) {
				k = i;
				flag = 1;
			}
		}
		i++;
	}

	if (flag == 0) {
		printf("UNRESTORABLE\n");
	}
	
	if (flag == 1) {
		for (m = k; m < k+len_t; m++) {
			s[m] = t[m-k];
		}


		for (l = 0; l < len_s; l++) {
			if (s[l] == '?') {
				s[l] = 'a';
			}
		}
		printf("%s\n", s);
	}

	return 0;

}
//  [c]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>

int main(void){

    char SS[51], T[51];

    scanf("%s%s", SS, T);

    int lenS = strlen(SS);
    int lenT = strlen(T);

    int s = 0;
    int t = 0;

    for(int i = 0; i <= lenS - lenT; i++){
        int f = 0;
        for(int j = 0; j < lenT; j++){
            if(SS[lenS - i - 1 - j] != '?' && SS[lenS-i-1-j] != T[lenT-j-1]){
                f = 1;
                break;
            }
        }
        if(f == 0){
            s = lenS-i-lenT;
            t = 1;
            break;
        }
    }

    if(t == 0){
        printf("UNRESTORABLE\n");
    }else{
        for(int i = 0; i < s; i++){
            if(SS[i] == '?'){
                printf("a");
            }else{
                printf("%c", SS[i]);
            }
        }
        for(int i = s; i < s + lenT; i++){
            printf("%c", T[i-s]);
        }
        for(int i = s + lenT; i < lenS; i++){
            if(SS[i] == '?'){
                printf("a");
            }else{
                printf("%c", SS[i]);
            }
        }
        printf("\n");
    }

    return 0;
}
//  [c]
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int if_coinside(char Sd[64], char T[64], int lengthT, int st){
	int i;
	for(i = 0; i < lengthT; i += 1) {
		if(Sd[i + st] != T[i] && Sd[i + st] != '?') {
			return 0;
		}
	}
	return 1;
}

int compare_renew_candidate(char old[64], char new[64], int lengthS) {
	int i;
	int if_swap;
	if_swap = 0;
	for(i = 0; i < lengthS; i += 1) {
		if((int)old[i] < (int)new[i]) {
			if_swap = 0;
			break;
		} else if((int)old[i] > (int)new[i]) {
			if_swap = 1;
			break;
		}
	}
	if(if_swap == 1) {
		sprintf(old, "%s", new);
	}
	return 0;
}

int gen_candidate(char Sd[64], char T[64], char candidate[64], int lengthS, int lengthT, int st){
	int i;
	for(i = 0; i < st; i += 1) {
		if(Sd[i] == '?') {
			candidate[i] = 'a';
		} else {
			candidate[i] = Sd[i];
		}
	}
	for(i = st; i < st + lengthT; i += 1) {
		candidate[i] = T[i - st];
	}
	for(i = st + lengthT; i < lengthS; i += 1) {
		if(Sd[i] == '?') {
			candidate[i] = 'a';
		} else {
			candidate[i] = Sd[i];
		}
	}
	return 0;
}

int main(void) {
	int i, j;
	int lengthS, lengthT;
	int exist_candidate, match;
	char Sd[64], T[64];
	char new_candidate[64] = {'\0'};
	char old_candidate[64] = {'\0'};
	char buf[128], *ch;

	fgets(Sd, sizeof(buf), stdin);
	fgets(T, sizeof(buf), stdin);

	lengthS = strlen(Sd) - 1;
	lengthT = strlen(T) - 1;
	//delete '\n'
	if(Sd[lengthS] == '\n') {
		Sd[lengthS] = '\0';
		T[lengthT] = '\0';
	}

	if(lengthS < lengthT) {
		printf("UNRESTORABLE\n");
		return 0;
	}
	exist_candidate = 0;
	for(i = 0; i < lengthS - lengthT + 1; i += 1) {
		match = if_coinside(Sd, T, lengthT, i);
		if(match == 1) {
			if(exist_candidate == 0) {
				gen_candidate(Sd, T, old_candidate, lengthS, lengthT, i);
				exist_candidate = 1;
			} else {
				gen_candidate(Sd, T, new_candidate, lengthS, lengthT, i);
				compare_renew_candidate(old_candidate, new_candidate, lengthS);
			}
		}
	}

	if(exist_candidate == 0) {
		printf("UNRESTORABLE\n");
	} else {
		printf("%s\n", old_candidate);
	}
	return 0;
}
//  [c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define NOANSWER "UNRESTORABLE"

int             check_hint(char *key, char *hint)
{
        int i = 0;

        while (hint[i])
        {
                if (key[i] != '?' && key[i] != hint[i])
                        return (0);
                i++;
        }
        return (1);
}

void    print_answer(char *key, char *hint, int first)
{
        int i;

        for (i = 0; i < first; i++)
        {
                if (key[i] == '?')
                        write(1, "a", 1);
                else
                        write(1, &key[i], 1);
        }
        while (*hint)
        {
                write(1, hint, 1);
                hint++;
                i++;
        }
        while (key[i])
        {
                if (key[i] == '?')
                        write(1, "a", 1);
                else
                        write(1, &key[i], 1);
                i++;
        }
        write(1, "\n", 1);
}



int             main(void)
{
        char    key[51];
        char    hint[51];
        int             first = -1;
        int             max;
        int             i;

        scanf("%s%s", key, hint);
        max = strlen(key) - strlen(hint);
        for (i = 0; i <= max; i++)
        {
                if (check_hint(&key[i], hint))
                        first = i;
        }
        if (first == -1)
        {
                printf("%s\n", NOANSWER);
                return (0);
        }
        print_answer(key, hint, first);
        return (0);
}
//  [javascript]
"use strict";
    
const main = arg => {
    arg = arg.trim().split("\n");
    const S = arg[0];
    const T = arg[1];
    
    for(let i=S.length - T.length; i>=0; i--) {
        let flag = true;
        let sub  = S.substr(i, T.length);

        for(let j=0; j<T.length; j++) {
            if(sub.charAt(j) !== T.charAt(j) && sub.charAt(j) !== "?") {
                flag = false;
                break;
            }
        }
        
        if(flag === true) {
            let answer = S.substring(0, i) + T + S.substring(parseInt(i) + T.length);
            answer = answer.replace(/\?/g, "a");
            console.log(answer);
            return;
        }
    }
    
    console.log("UNRESTORABLE");
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
//  [javascript]
inp = require('fs').readFileSync('/dev/stdin', 'utf8').trim().split('\n')
S = inp.shift()
T = inp.shift()
for (i=S.length-1; i>=0; i--) {
    f = 1
    for (j=0; j<T.length; j++) {
        if (!(S[i+j] == T[j] || S[i+j] == '?')) {
            f = 0
        }
    }
    if (f==1) {
        break;
    }
}
if (f==1) {
    ans = ''
    for (k=0; k<S.length; k++) {
        if (k == i) {
            ans += T
            k += T.length - 1
        } else {
            ans += S[k] == '?' ? 'a' : S[k]
        }
    }
} else {
    ans = 'UNRESTORABLE'
}
console.log(ans)
//  [javascript]
"use strict"

function main(input) {
  input = input.split(/\n/)
  let S = input[0].split("")
  const T = input[1].split("")
  const us = "UNRESTORABLE"
  // if (S.length < T.length) {
  //   console.log(us)
  //   return
  // } else {
  for (let i = S.length - T.length; i >= 0; i--) {
    //
    let x = 0
    for (let j = 0; j < T.length; j++) {
      //Tの区間の中で合致するかどうか
      if (S[i + j] == T[j] || S[i + j] == "?") {
        //この文字は合致、または?だからパス
      } else {
        //合致しない＞この区間は合致しない
        x++
        continue
      }
      //
    }
    //合致しなかったら次のforへ、合致したら次のステップへ
    if (x > 0) continue

    //Tで埋める
    for (let k = 0; k < T.length; k++) {
      S[i + k] = T[k]
    }
    //残りの?をaに変換 <todo> : 正規表現などで
    // S = S.replace(/(.+)/, "a")
    for (let i = 0; i < S.length; i++) {
      S[i] = S[i] == "?" ? "a" : S[i]
    }
    console.log((S = S.join("")))
    return
  }
  // }
  //
  console.log(us)
  //
}
main(require("fs").readFileSync("/dev/stdin", "utf8"))
//  [javascript]
function getChangeIndex(input, containText) {
  var index = -1;
  var cIndex = -1;

  for (var i = input.length - containText.length; i >= 0; i--) {
    if (input[i] !== containText[0] && input[i] !== '?') {
      // console.log(input[i]);
      // console.log(containText[0]);
      continue;
    }
    var slicedInput = input.slice(i, i + containText.length);
    // console.log({ slicedInput });

    var result = true;
    for (var j = 0; j < containText.length; j++) {
      if (slicedInput[j] !== containText[j] && slicedInput[j] !== '?') {
        // console.log(slicedInput[j], containText[j]);
        result = false;
        break;
      }
    }

    if (result) {
      index = i;
      break;
    }
  }
  // console.log(index);
  return index;
}

function solve(inputRaw) {
  var row = inputRaw.trim().split('\n');
  var input = row[0];
  var containText = row[1];

  var index = getChangeIndex(input, containText, 0);

  if (index >= 0) {
    var result = input.substr(0, index) + containText + input.substr(index + containText.length, input.length);
    result = result.split('?').join('a');
    return result;
  }

  return 'UNRESTORABLE';
}

console.log(solve(require('fs').readFileSync('/dev/stdin', 'utf8')));
//  [javascript]
"use strict";
    
const main = arg => {
    arg = arg.trim().split("\n");
    const S = arg[0];
    const T = arg[1];
    
    for(let i=S.length - T.length; i>=0; i--) {
        let flag = true;
        let sub  = S.substr(i, T.length);
 
        for(let j=0; j<T.length; j++) {
            if(sub.charAt(j) !== T.charAt(j) && sub.charAt(j) !== "?") {
                flag = false;
                break;
            }
        }
        
        if(flag === true) {
            let answer = S.substring(0, i) + T + S.substring(parseInt(i) + T.length);
            answer = answer.replace(/\?/g, "a");
            console.log(answer);
            return;
        }
    }
    
    console.log("UNRESTORABLE");
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
//  [javascript]
function getChangeIndex(input, containText) {
  var index = -1;

  for (var i = input.length - containText.length; i >= 0; i--) {
    if (input[i] !== containText[0] && input[i] !== '?') {
      continue;
    }
    var slicedInput = input.slice(i, i + containText.length);

    var result = true;
    for (var j = 0; j < containText.length; j++) {
      if (slicedInput[j] !== containText[j] && slicedInput[j] !== '?') {
        result = false;
        break;
      }
    }

    if (result) {
      index = i;
      break;
    }
  }
  return index;
}

function solve(inputRaw) {
  var row = inputRaw.trim().split('\n');
  var input = row[0];
  var containText = row[1];

  var index = getChangeIndex(input, containText, 0);

  if (index >= 0) {
    var result = input.substr(0, index) + containText + input.substr(index + containText.length, input.length);
    result = result.split('?').join('a');
    return result;
  }

  return 'UNRESTORABLE';
}

console.log(solve(require('fs').readFileSync('/dev/stdin', 'utf8')));
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func out(x ...interface{}) {
	fmt.Println(x...)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

// min, max, asub, absなど基本関数
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func asub(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

func lowerBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] >= x
	})
	return idx
}

func upperBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] > x
	})
	return idx
}

func check(s, t string) bool {
	for i := 0; i < len(s); i++ {
		if s[i] == '?' {
			continue
		}
		if s[i] != t[i] {
			return false
		}
	}
	return true
}

func main() {
	sc.Split(bufio.ScanWords)
	s := getString()
	t := getString()

	x := make([]string, 0)
	for i := len(s) - len(t); i >= 0; i-- {
		flg := check(s[i:i+len(t)], t)
		if flg {
			o := []byte(s[0:i] + t + s[i+len(t):])
			for j := 0; j < len(o); j++ {
				if o[j] == '?' {
					o[j] = 'a'
				}
			}
			x = append(x, string(o))
		}
	}

	sort.Strings(x)
	if len(x) > 0 {
		out(x[0])
	} else {
		out("UNRESTORABLE")
	}
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

var (
	ans string
)

func main() {
	s := readString()
	t := readString()

	if includes(s, t) {
		fmt.Println(strings.Replace(ans, "?", "a", -1))
	} else {
		fmt.Println("UNRESTORABLE")
	}
}

func includes(s, t string) bool {
	for i := len(s) - len(t); i >= 0; i-- {
		c := 0
		for ii := 0; ii < len(t); ii++ {
			if s[i+ii] == t[ii] || string(s[i+ii]) == "?" {
				c++
			}
			if c == len(t) {
				ans = s[:i] + t + s[i+len(t):]
				return true
			}
		}
	}
	return false
}

/*-------------------utilities-------------------*/

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func chmin(x *int, y int) bool {
	if *x > y {
		*x = y
		return true
	}
	return false
}

func chmax(x *int, y int) bool {
	if *x < y {
		*x = y
		return true
	}
	return false
}

// 最大公約数
func gcd(a, b int) int {
	if b == 0 {
		return a
	}
	return gcd(b, a%b)
}

// 最小公倍数
func lcm(a, b int) int {
	return (a * b) / gcd(a, b)
}

func comb(n, k int) int {
	if n < k {
		return 0
	}
	if n < 0 || k < 0 {
		return 0
	}
	return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD
}

func factorical(n int) int {
	if n > 0 {
		return n * factorical(n-1)
	}
	return 1
}

/*-------------------init-------------------*/

const (
	INF = 1000000000000000000
	MOD = 1e9 + 7

	COMB_MAX = 510000
)

var (
	readString func() string
)

var (
	fac  = [COMB_MAX]int{}
	finv = [COMB_MAX]int{}
	inv  = [COMB_MAX]int{}
)

func init() {
	readString = newReadString(os.Stdin)
}

func combInit() {
	fac[0] = 1
	fac[1] = 1
	finv[0] = 1
	finv[1] = 1
	inv[1] = 1
	for i := 2; i < COMB_MAX; i++ {
		fac[i] = fac[i-1] * i % MOD
		inv[i] = MOD - inv[MOD%i]*(MOD/i)%MOD
		finv[i] = finv[i-1] * inv[i] % MOD
	}
}

/*-------------------inputs-------------------*/

func readi() int {
	return int(readi64())
}

func readi64() int64 {
	i, err := strconv.ParseInt(readString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

func readf() float64 {
	f, err := strconv.ParseFloat(readString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

func newReadString(ior io.Reader) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+11))
	r.Split(bufio.ScanWords)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}
//  [go]
// Nが小さいので適当に頭から探索してTを埋め込めたところで余った?はaにでもしておけ
package main

import (
	"fmt"
	"strings"
)

func main() {
	var S, T string
	fmt.Scan(&S, &T)
	SS, TT := make([]string, len(S)), make([]string, len(T))
	for i, c := range []rune(S) {
		SS[i] = string(c)
	}
	for i, c := range []rune(T) {
		TT[i] = string(c)
	}
	reverse(SS)
	reverse(TT)
	idx := -1
	for i := 0; i <= len(SS)-len(TT); i++ {
		if SS[i] == TT[0] || SS[i] == "?" {
			flag := true
			for j := 1; j < len(TT); j++ {
				if SS[i+j] == TT[j] || SS[i+j] == "?" {
					continue
				} else {
					flag = false
				}
			}
			if flag {
				idx = i
				break
			}
		}
	}
	if idx == -1 {
		fmt.Println("UNRESTORABLE")
	} else {
		for i := 0; i < len(SS); i++ {
			if idx <= i && i < idx+len(TT) {
				SS[i] = TT[i-idx]
			} else {
				if SS[i] == "?" {
					SS[i] = "a"
				}
			}
		}
		reverse(SS)
		fmt.Println(strings.Join(SS, ""))
	}
}

func reverse(arr []string) {
	for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 {
		arr[i], arr[j] = arr[j], arr[i]
	}
}
//  [go]
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
	"strings"
)

func configure(scanner *bufio.Scanner) {
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1000005), 1000005)
}
func getNextString(scanner *bufio.Scanner) string {
	scanned := scanner.Scan()
	if !scanned {
		panic("scan failed")
	}
	return scanner.Text()
}
func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}
func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}
func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}
func main() {
	fp := os.Stdin
	wfp := os.Stdout
	extra := 0
	if os.Getenv("I") == "IronMan" {
		fp, _ = os.Open(os.Getenv("END_GAME"))
		extra = 100
	}
	scanner := bufio.NewScanner(fp)
	configure(scanner)
	writer := bufio.NewWriter(wfp)
	defer func() {
		r := recover()
		if r != nil {
			fmt.Fprintln(writer, r)
		}
		writer.Flush()
	}()
	solve(scanner, writer)
	for i := 0; i < extra; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
}
func solve(scanner *bufio.Scanner, writer *bufio.Writer) {
	s := getNextString(scanner)
	t := getNextString(scanner)
	n := len(s)
	m := len(t)
	ss := make([]string, 0)
	for i := 0; i < n-m+1; i++ {
		if ok(s[i:], t) {
			temp := make([]string, 0)
			for j := 0; j < i; j++ {
				if s[j] == '?' {
					temp = append(temp, "a")
					continue
				}
				temp = append(temp, fmt.Sprintf("%c", s[j]))
			}
			temp = append(temp, t)
			for j := i + m; j < n; j++ {
				if s[j] == '?' {
					temp = append(temp, "a")
					continue
				}
				temp = append(temp, fmt.Sprintf("%c", s[j]))
			}
			ss = append(ss, strings.Join(temp, ""))
			continue
		}
	}
	if len(ss) == 0 {
		fmt.Fprintln(writer, "UNRESTORABLE")
		return
	}
	sort.Strings(ss)
	fmt.Fprintln(writer, ss[0])
}
func ok(s, t string) bool {
	n := len(t)
	for i := 0; i < n; i++ {
		if s[i] == '?' {
			continue
		}
		if s[i] != t[i] {
			return false
		}
	}
	return true
}
//  [ruby]
S=gets.chomp
T=gets.chomp
s = S.chars.map {|c| c == '?' ? '.' : c}
l=T.length

(S.length - l).downto(0) do |i|
    if T.match(/#{s[i...i+l].join}/)
        s = S
        s[i...i+l] = T
        puts s.tr('?','a')
        exit 0
    end
end

puts 'UNRESTORABLE'
//  [ruby]
S, T = gets.chomp, gets.chomp

A = (0..S.size-T.size).each_with_object([]){|i, a|
    s = S.slice(i...i+T.size)
    t = S.dup
    
    if s.chars.each_with_index.all?{|e, j| e == T[j] || e == "?"} then
        t[i...i+T.size] = T
        a << t.gsub("?", "a")
    end
}

puts A.empty? ? :UNRESTORABLE : A.min
//  [ruby]
s = gets.chomp
t = gets.chomp
ans = 'UNRESTORABLE'
array = []
(s.size - t.size + 1).times do |i|
	ss = s.slice(i,t.size)
	flag = true
	t.size.times do |j|
		flag = false if ss[j] != "?" && ss[j] != t[j]
	end
	array << i if flag
end

if !array.empty?
	if !array.any?{|a| s.slice(a,t.size) == t}
		s[array[-1],t.size] = t
	end
	s.size.times do |i|
		s[i] = "a" if s[i] == "?"
	end
	ans = s
end

puts ans
//  [ruby]
sp = gets.chomp
t = gets.chomp
n = sp.size
m = t.size

if n < m
  puts "UNRESTORABLE"
else
  res = -1
  i = 0
  while i <= n - m
    cnt = 0
    while cnt < m && (sp[i + cnt] == "?" || sp[i + cnt] == t[cnt])
      cnt += 1
    end
    
    if cnt == m
      res = i
    elsif sp[i] == "?"
      sp[i] = "a"
    end
    i += 1
  end
  
  if res == -1
    puts "UNRESTORABLE"
  else
    res = sp[0...res] + t + sp[(res + m)...n]
    res.gsub!(/\?/, "a")
    puts res
  end
end
//  [ruby]
s = gets.chomp
t = gets.chomp
x = []
(0..s.size - t.size).each do |i|
  start = i
  finish = i + t.size - 1
  u = s[start..finish]
  is_sub_string = true
  t.size.times do |j|
    next if t[j] == u[j] || u[j] == '?'

    is_sub_string = false
    break
  end

  next unless is_sub_string

  if i == 0
    s_pre = ''
  else
    s_pre = s[0...i]
  end
  if i == s.size - t.size
    s_post = ''
  else
    s_post = s[finish+1..-1]
  end

  x << "#{s_pre}#{t}#{s_post}".gsub('?', 'a')

end

if x.empty?
  puts 'UNRESTORABLE'
else
  puts x.sort.first
end
//  [ruby]
S=gets.chomp
T=gets.chomp
r=nil
(S.size-T.size+1).times{|i|
    f=true
    T.size.times{|j|
        next if S[i+j]=="?"
        if S[i+j]!=T[j]
            f=false
            break
        end
    }
    if f
        s=S.tr("?","a")
        s[i,T.size]=T
        #warn s
        if !r||s<r
            r=s
        end
    end
}
if r
    puts r
else
    puts "UNRESTORABLE"
end
//  [rust]
use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("faild to read char") as char)
        .take_while(|c| !c.is_whitespace())
        .collect();
    token
        .parse()
        .ok()
        .expect("faild to parse token")
}

fn main(){
    let s: Vec<char> = read::<String>().chars().collect();
    let t: Vec<char> = read::<String>().chars().collect();
    let mut ret: Vec<String> = Vec::new();

    for i in 0..(s.len()) {
        if s.len() - i < t.len() {
            continue;
        }
        let mut is_valid = true;
        for j in 0..(t.len()) {
            if s[i + j] != t[j] && s[i + j] != '?' {
                is_valid = false;
                break;
            }
        }

        if !is_valid {
            continue;
        }
        ret.push((0..(s.len())).map(|j| if i <= j && j < t.len() + i { t[j - i] } else if s[j] == '?'{ 'a' } else { s[j] }).collect());
    }
    ret.sort();

    if ret.len() == 0 {
        println!("UNRESTORABLE");
    } else {
        println!("{}", ret[0]);
    }
}
//  [rust]
fn main() {
    let mut s = String::new();
    let mut t = String::new();
    std::io::stdin().read_line(&mut s).ok();
    std::io::stdin().read_line(&mut t).ok();
    let a = s.trim_right().as_bytes();
    let b = t.trim_right().as_bytes();
    for i in (0..a.len()).rev() {
        if i + b.len() > a.len() { continue; }
        let mut valid = true;
        for j in 0..b.len() {
            if a[i+j] != '?' as u8 && a[i+j] != b[j] {
                valid = false;
                break;
            }
        }
        if valid {
            for j in 0..i {
                print!("{}", if a[j] == '?' as u8 {"a"} else { &s[j..j+1] } )
            }
            print!("{}", t.trim_right());
            for j in i+b.len()..a.len() {
                print!("{}",  if a[j] == '?' as u8 {"a"} else { &s[j..j+1] } )
            }
            println!("");
            return;
        }
    }
    println!("UNRESTORABLE");
}
//  [rust]
pub fn read1<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn main() {
    let s = read1::<String>().chars().collect::<Vec<char>>();
    let t = read1::<String>().chars().collect::<Vec<char>>();
    let s_len = s.len();
    let t_len = t.len();
    if s_len < t_len {
        println!("UNRESTORABLE");
        return;
    }
    let mut pos = s_len;
    for i in 0..(s_len - t_len + 1) {
        let mut flg = true;
        for j in 0..t_len {
            if s[i+j] != t[j] && s[i+j] != '?' {
                flg = false;
                break;
            }
        }
        if flg {
            pos = i;
        }
    }
    if pos != s_len {
        let ans = s.iter().enumerate().map(|(i, &c)| {
            if i >= pos && i < pos + t_len {
                t[i - pos]
            } else {
                if c == '?' {
                    'a'
                } else {
                    s[i]
                }
            }
        }).collect::<Vec<char>>();
        println!("{}", ans.into_iter().collect::<String>());
    } else {
        println!("UNRESTORABLE");
    }
}
//  [rust]
use proconio::{input, marker::Chars};

fn main() {
    input!{
        mut s: Chars,
        t: Chars,
    }

    let mut ok = false;

    'next: for i in (t.len()-1..s.len()).rev() {
        for (j, &c) in t.iter().rev().enumerate() {
            if s[i-j] != c && s[i-j] != '?' {
                continue 'next;
            }
        }
        ok = true;
        for (j, &c) in t.iter().rev().enumerate() {
            s[i-j] = c;
        }
        break;
    }
    
    if !ok {
        println!("UNRESTORABLE");
        return;
    }

    for c in s.iter_mut() {
        if *c == '?' {
            *c = 'a';
        }
    }

    let s = s.iter().collect::<String>();

    println!("{}", s);
}
//  [rust]
#![allow(unused_macros)]
#![allow(dead_code)]
#![allow(unused_imports)]

use itertools::Itertools;
use proconio::*;
use text_io::*;

const U_INF: usize = 1 << 60;
const I_INF: isize = 1 << 60;

fn main() {
    let s: String = read!();
    let t: String = read!();
    let s = s.chars().collect_vec();
    let t = t.chars().collect_vec();

    for i in (0..s.len()).rev() {
        if check(&s[i..], &t) {
            println!("{}", cross(&s, &t, i));
            return;
        }
    }
    
    println!("UNRESTORABLE");
}

fn check(s: &[char], t: &[char]) -> bool {
    if s.len() < t.len() {
        return false;
    }

    for i in 0..t.len() {
        if s[i] != '?' && s[i] != t[i] {
            return false;
        }
    }

    true
}

fn cross(s: &[char], t: &[char], start: usize) -> String {
    let mut ss = String::new();

    for i in 0..s.len() {
        if i < start {
            ss.push(if s[i] != '?' { s[i] } else { 'a' });
        } else if i < start + t.len() {
            ss.push(t[i - start]);
        } else {
            ss.push(if s[i] != '?' { s[i] } else { 'a' });
        }
    }

    ss
}
//  [rust]
use proconio::input;
fn main() {
    input!{
        mut s: String,
        t: String
    }
    let ns = s.len();
    let nt = t.len();
    let mut j = -1;
    for i in 0..ns-nt+1{
        if s[i..i+nt].chars().zip(t.chars()).filter(|&(x, y)| {x == '?' || x == y} ).count() == nt{
            j = i as i32;
        }
    }
    if j == -1 {
        println!("UNRESTORABLE")
    }
    else{
        let j = j as usize;
        s.replace_range(j..j+nt, &t);
        let ans: String = s.chars().map(|x| if x=='?' {'a'} else {x}).collect();
        println!("{}", ans);
    }
}
//  [typescript]
function main(input) {
  input = input.trim().split("\n");
  const [s, t] = input;
  let result;
  for(let i = 0; i <= s.length - t.length; i++) {
    let isPossible = true;
    for(let j = 0; j < t.length; j++) {
      const sChar = s[i + j];
      const tChar = t[j];
      if (sChar !== "?" && sChar !== tChar) {
        isPossible = false;
        break;
      }
    }
    if(isPossible) {
      const str = s.substr(0, i) + t + s.substr(t.length + i);
      const replacedStr = str.replace(/\?/g, "a");
      if (!result || replacedStr < result) {
        result = replacedStr;
      }
    }
  }
  result = result || "UNRESTORABLE";
  console.log(result);
}
main(require("fs").readFileSync("/dev/stdin", "utf8"));
//  [python]
import sys, re
from math import ceil, floor, sqrt, pi, factorial, gcd
from copy import deepcopy
from collections import Counter, deque
from heapq import heapify, heappop, heappush
from itertools import accumulate, product, combinations, combinations_with_replacement
from bisect import bisect, bisect_left, bisect_right
from functools import reduce
from decimal import Decimal, getcontext
# input = sys.stdin.readline 
def i_input(): return int(input())
def i_map(): return map(int, input().split())
def i_list(): return list(i_map())
def i_row(N): return [i_input() for _ in range(N)]
def i_row_list(N): return [i_list() for _ in range(N)]
def s_input(): return input()
def s_map(): return input().split()
def s_list(): return list(s_map())
def s_row(N): return [s_input for _ in range(N)]
def s_row_str(N): return [s_list() for _ in range(N)]
def s_row_list(N): return [list(s_input()) for _ in range(N)]
def lcm(a, b): return a * b // gcd(a, b)
sys.setrecursionlimit(10 ** 6)
INF = float('inf')
MOD = 10 ** 9 + 7
num_list = []
str_list = []

def main():
    x, y = i_map()

    if x == 2 or y == 2:
        print('No')
        exit()

    al = [1, 3, 5, 7, 8, 10, 12]
    bl = [4, 6, 9, 11]

    if x in al and y in al:
        print('Yes')
    elif x in bl and y in bl:
        print('Yes')
    else:
        print('No')

if __name__ == '__main__':
    main()
//  [python]
import numpy as np

data = input()
data = data.split()
x = int(data[0])
y = int(data[1])

vec_1 = []
vec_2 = []
group = [[1, 3, 5, 7, 8, 10, 12], [4, 6, 9, 11], [2]]


for i in range(3):
	if x in group[i]:
		vec_1.append(1)
	else:
		vec_1.append(0)

for i in range(3):
	if y in group[i]:
		vec_2.append(1)
	else:
		vec_2.append(0)

vec_1 = np.array(vec_1)
vec_2 = np.array(vec_2)


if sum(vec_1 * vec_2) == 1:
	print("Yes")
else:
	print("No")
//  [python]
import math
import string
import collections
from collections import Counter
from collections import deque
from decimal import Decimal
import sys
import fractions


def readints():
    return list(map(int, input().split()))


def nCr(n, r):
    return math.factorial(n)//(math.factorial(n-r)*math.factorial(r))


def has_duplicates2(seq):
    seen = []
    for item in seq:
        if not(item in seen):
            seen.append(item)
    return len(seq) != len(seen)


def divisor(n):
    divisor = []
    for i in range(1, n+1):
        if n % i == 0:
            divisor.append(i)
    return divisor


# coordinates
dx = [-1, -1, -1, 0, 0, 1, 1, 1]
dy = [-1, 0, 1, -1, 1, -1, 0, 1]
a = [1, 3, 5, 7, 8, 10, 12]
b = [4, 6, 9, 11]
c = [2]
x, y = map(int, input().split())
if (x in a and y in a) or(x in b and y in b) or(x in c and y in c):
    print('Yes')
else:
    print('No')
//  [java]
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
import java.util.stream.IntStream;

public class Main {

	private static final int N = 3;

	@SuppressWarnings("unchecked")
	private static final Set<Integer>[] SETS = new Set[N];

	static {
		IntStream.range(0, N).forEach(i -> SETS[i] = new HashSet<>());
	}

	static {
		SETS[0].add(1);
		SETS[0].add(3);
		SETS[0].add(5);
		SETS[0].add(7);
		SETS[0].add(8);
		SETS[0].add(10);
		SETS[0].add(12);
	}

	static {
		SETS[1].add(4);
		SETS[1].add(6);
		SETS[1].add(9);
		SETS[1].add(11);
	}

	static {
		SETS[2].add(2);
	}

	public static void main(String[] args) {
		try (Scanner scanner = new Scanner(System.in)) {
			int x = scanner.nextInt();
			int y = scanner.nextInt();
			System.out.println((getSet(x) == getSet(y)) ? "Yes" : "No");
		}
	}

	/**
	 * @param n 入力数字
	 * @return 入力数字を含まれるセット
	 */
	private static Set<Integer> getSet(int n) {
		for (Set<Integer> set : SETS) {
			if (set.contains(n)) {
				return set;
			}
		}
		return null;
	}
}
//  [java]
import java.util.Scanner;
import java.util.Set;
import java.util.HashSet;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> set2 = new HashSet<>();
        Set<Integer> set3 = new HashSet<>();
        set1.add(1);
        set1.add(3);
        set1.add(5);
        set1.add(7);
        set1.add(8);
        set1.add(10);
        set1.add(12);

        set2.add(4);
        set2.add(6);
        set2.add(9);
        set2.add(11);


        set3.add(2);
        if(set1.contains(x) && set1.contains(y)){
            System.out.println("Yes");
            return;
        }
        if(set2.contains(x) && set2.contains(y)){
            System.out.println("Yes");
            return;
        }
        if(set3.contains(x) && set3.contains(y)){
            System.out.println("Yes");
            return;
        }
            System.out.println("No");
    }
}
//  [cpp]
#include <bits/stdc++.h>
using namespace std;
 
#define rep(i, n) for (int i = (int)(0); i < (int)(n); ++i)
#define reps(i, n) for (int i = (int)(1); i <= (int)(n); ++i)
#define rrep(i, n) for (int i = ((int)(n)-1); i >= 0; i--)
#define rreps(i, n) for (int i = ((int)(n)); i > 0; i--)
#define irep(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define ireps(i, m, n) for (int i = (int)(m); i <= (int)(n); ++i)
#define FOR(e, c) for (auto &e : c)
#define SORT(v, n) sort(v, v + n);
#define vsort(v) sort(v.begin(), v.end());
#define rvisort(v) sort(v.begin(), v.end(), greater<int>());
#define all(v) v.begin(), v.end()
#define mp(n, m) make_pair(n, m);
#define cout(d) cout<<d<<endl;
#define coutd(d) cout<<std::setprecision(10)<<d<<endl;
#define cinline(n) getline(cin,n);
 
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;
using vpii = vector<pii>;
using vs = vector<string>;
using vd = vector<double>;
using ul = unsigned long;
 
template<class T, class C> void chmax(T& a, C b){ a>b?:a=b; }
template<class T, class C> void chmin(T& a, C b){ a<b?:a=b; }
 
const int mod=1e9+7;
 
struct mint {
  ll x;
  mint(ll x=0):x(x%mod){}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res+=a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res-=a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res*=a;
  }
};
 
mint c[4005][4005];
void init() {
  c[0][0] = 1;
  for (int i = 0; i <= 4000; i++) {
    for (int j = 0; j <= i; j++) {
      c[i+1][j] += c[i][j];
      c[i+1][j+1] += c[i][j];
    }
  }
}
mint comb(int n, int k) {
  return c[n][k];
}
 
bool IsPrime(int num)
{
    if (num < 2) return false;
    else if (num == 2) return true;
    else if (num % 2 == 0) return false;
 
    double sqrtNum = sqrt(num);
    for (int i = 3; i <= sqrtNum; i += 2)
    {
        if (num % i == 0)
        {
            return false;
        }
    }
 
    return true;
}
 
map<ll, ll> primeFact(ll n) {
  map<ll, ll> res;
  for (ll i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      res[i]++;
      n /= i;
    }
  }
  if (n != 1) res[n]++;
  return res;
}
 
void printv(vi& v){
  rep(i,v.size()) cout << v[i] << " ";
  cout << endl;
}
void printv(vll& v){
  rep(i,v.size()) cout << v[i] << " ";
  cout << endl;
}
int vtotal(vi& v){
  int total=0;
  rep(i,v.size()) total+=v[i];
  return total;
}
 
int main()
{
  //init(); // mint初期化
  cin.tie( 0 );
  ios::sync_with_stdio( false );
  
  int x,y;cin>>x>>y;
  vi v{0,1,3,1,2,1,2,1,1,2,1,2,1};
  
  string ans="No";
  if(v[x]==v[y])ans="Yes";
  cout(ans);
  
  return 0;
}
//  [cpp]
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <ctype.h>
#include <cmath>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define inf 0x3f3f3f3f
#define PI acos(-1.0)
#define me(x) memset(x,0,sizeof(x))
#define scan(x) scanf("%d",&x)
#define scan2(x,y) scanf("%d%d",&x,&y)
#define STR(s) strlen(s)
#define FOR(i,sta,n) for(i=sta;i<n;i++)
#define FOR1(i,sta,n) for(i=sta;i<=n;i++)

typedef long long ll;
int vis[20]={0,1,3,1,2,1,2,1,1,2,1,2,1};

int main()
{
    int x,y;
    scanf("%d%d",&x,&y);
    if(vis[x]==vis[y])
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return 0;
}