#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <bits/stdc++.h>
#include <set>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <map>
#define ll long long
using namespace __gnu_pbds;
using namespace std;
template <class T>
using ordered_set = tree<T , null_type , less<T> , rb_tree_tag , tree_order_statistics_node_update>;
template <class T>
using ordered_set1 = tree<T , null_type , greater<T> , rb_tree_tag , tree_order_statistics_node_update>;
// less<T>/greater<T> = ascending/descending.
// less_equal<>/greater_equal<> for ordered multiset
// ordered_multiset note : s.find(), s.erase() don't work + s.upper_bound() and s.lower_bound() swap jobs;
void fastIO(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
}

int main() {
    fastIO();
    string s; cin>>s;
    ll size = s.size();
    ll l = 0, r=l;
    int freq[26]={0};
    while (r<s.size() && r-l<=25) {
        while (r<s.size() && s[r]=='?' && r-l<=25) {
            r++;
        }
        if (r==s.size() || r-l>25) break;
        freq[s[r]-'A']++;
        while (freq[s[r]-'A']>1) {
            if (s[l]!='?') {
                freq[s[l]-'A']--;
            }
                l++;
        }
        r++;
    }
    string sub = s.substr(l,26);
    if (r>l+25 && (s.size()-l>=26)) {
        for (ll i = 0; i<sub.size(); i++) {
            if (sub[i]=='?') {
                for (ll j = 0; j<26; j++) {
                    if (freq[j]==0) {
                        freq[j]++;
                        sub[i]='A'+j;
                        break;
                    }
                }
            }
        }
        s.replace(l,26,sub);
        for (ll i = 0; i<s.size(); i++) {
            if (s[i]=='?') {
                s[i]='A';
            }
        }
        cout<<s;
    }
    else {
        cout<<-1;
    }
}