#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;

//READ THE PROBLEM!
//ll or int?

//Template contributed by GitHub user bqi343

const int MAXN = 100000;

int maxH[MAXN], regen[MAXN], startH[MAXN];
bool canKill[MAXN];
int N, M, damage, numKillable; int curU = 0; ll best = 0;
ll bounty, increase;
int lastProcessed = -100;

struct update {
    int id;
    int time;
    int health;
    bool operator <(const update& rhs) const {
        return time > rhs.time;
    }
};

priority_queue<update> keyTimes;
vector<priority_queue<update> > uTimes;

void updateBest(int time) {
    ll cur = (bounty + increase * time) * numKillable;
    //cout << "Can earn " << cur << " at " << time << endl;
    best = max(cur, best);

}

void init() {
    cin >> N >> M >> bounty >> increase >> damage;
    priority_queue<update> pq;
    F0R(i, N) {
        cin >> maxH[i] >> startH[i] >> regen[i];

        uTimes.pb(pq);
    }

    F0R(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
        update u = { b - 1, a, c };
        uTimes.at(i).push(u);
    }

    numKillable = 0;

    F0R(i, N) {
        if (maxH[i] <= damage) {
            canKill[i] = true;
            numKillable++;
        } else {
            if (startH[i] > damage) {
                canKill[i] = false;
                if (!uTimes.at(i).empty()) {
                    keyTimes.push(uTimes.at(i).top());
                    uTimes.at(i).pop();
                }
            } else {
                canKill[i] = true;
                numKillable++;
                int t = -1;
                if (regen[i] != 0) t = ceil(((double) damage + 1 - (double) startH[i]) / (double) regen[i]);
                int h = -1;

                if (!uTimes.at(i).empty()) {
                    if (uTimes.at(i).top().time < t) {
                        t = uTimes.at(i).top().time;
                        h = uTimes.at(i).top().health;
                        uTimes.at(i).pop();
                    }
                }
                update u = { i, t, h };
                if (t != -1) keyTimes.push(u);

            }
        }
    }

    updateBest(0);
}

void processHealthChange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
    }

    if (canKill[u.id] && u.health > damage) {
        canKill[u.id] = false;
        numKillable--;
    } else if (!canKill[u.id] && u.health < damage) {
        canKill[u.id] = true;
        numKillable++;
    }

    int t = -1;
    int h = -1;
    if (u.health <= damage && regen[u.id] != 0) {
        t = u.time + ceil(((double) damage + 1 - (double) u.health) / (double) regen[u.id]);
        //cout << "Enemy " << u.id << " will be unkillable at time " << t << endl;
    }

    //cout << "About to check change " << u.id << endl;
    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        if (t == -1 || u2.time < t) {
            uTimes.at(u.id).pop();
            t = u2.time;
            h = u2.health;
        }
    }
    //cout << "Success" << endl;
    update u2 = {u.id, t, h};
    if (t != -1) keyTimes.push(u2);

    if (!keyTimes.empty() && keyTimes.top().time > u.time) {
        updateBest(u.time);
    }
}

void processRegenOutOfRange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
    }

    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        uTimes.at(u.id).pop();
        keyTimes.push(u2);
    }

    if (canKill[u.id]) {
        canKill[u.id] = false;
        numKillable--;
    }

    if (!keyTimes.empty() && keyTimes.top().time > u.time) {
        updateBest(u.time);
    }

}

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

    init();

    while (!keyTimes.empty()) {
        update u = keyTimes.top();
        keyTimes.pop();
        if (u.health == -1) {
            processRegenOutOfRange(u);
        } else {
            processHealthChange(u);
        }
    }

    if (numKillable == N) {
        cout << -1 << endl;
        return 0;
    }

    cout << best << endl;

	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;

//READ THE PROBLEM!
//ll or int?

//Template contributed by GitHub user bqi343

const int MAXN = 100000;

int maxH[MAXN], regen[MAXN], startH[MAXN];
bool canKill[MAXN];
int N, M, damage, numKillable; int curU = 0; ll best = 0;
ll bounty, increase;
int lastProcessed = -100;

struct update {
    int id;
    int time;
    int health;
    bool operator <(const update& rhs) const {
        return time > rhs.time;
    }
};

priority_queue<update> keyTimes;
vector<priority_queue<update> > uTimes;

void updateBest(int time) {
    ll cur = (bounty + increase * time) * numKillable;
    //cout << "Can earn " << cur << " at " << time << endl;
    best = max(cur, best);

}

void init() {
    cin >> N >> M >> bounty >> increase >> damage;
    priority_queue<update> pq;
    F0R(i, N) {
        cin >> maxH[i] >> startH[i] >> regen[i];

        uTimes.pb(pq);
    }

    F0R(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
        update u = { b - 1, a, c };
        uTimes.at(b-1).push(u);
    }

    numKillable = 0;

    F0R(i, N) {
        if (maxH[i] <= damage) {
            canKill[i] = true;
            numKillable++;
        } else {
            if (startH[i] > damage) {
                canKill[i] = false;
                if (!uTimes.at(i).empty()) {
                    keyTimes.push(uTimes.at(i).top());
                    uTimes.at(i).pop();
                }
            } else {
                canKill[i] = true;
                numKillable++;
                int t = -1;
                if (regen[i] != 0) t = ceil(((double) damage + 1 - (double) startH[i]) / (double) regen[i]);
                int h = -1;

                if (!uTimes.at(i).empty()) {
                    if (uTimes.at(i).top().time < t) {
                        t = uTimes.at(i).top().time;
                        h = uTimes.at(i).top().health;
                        uTimes.at(i).pop();
                    }
                }
                update u = { i, t, h };
                if (t != -1) keyTimes.push(u);

            }
        }
    }

    updateBest(0);
}

void processHealthChange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
        lastProcessed = u.time - 1;
    }

    if (canKill[u.id] && u.health > damage) {
        canKill[u.id] = false;
        numKillable--;
    } else if (!canKill[u.id] && u.health <= damage) {
        canKill[u.id] = true;
        numKillable++;
    }

    int t = -1;
    int h = -1;
    if (u.health <= damage && regen[u.id] != 0) {
        t = u.time + ceil(((double) damage + 1 - (double) u.health) / (double) regen[u.id]);
        //cout << "Enemy " << u.id << " will be unkillable at time " << t << endl;
    }

    //cout << "About to check change " << u.id << " at time " << u.time << endl;
    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        if (t == -1 || u2.time < t) {
            uTimes.at(u.id).pop();
            t = u2.time;
            h = u2.health;
        }
    }
    //cout << "Success" << endl;
    update u2 = {u.id, t, h};
    if (t != -1) keyTimes.push(u2);

    if (keyTimes.empty() || keyTimes.top().time > u.time) {
        updateBest(u.time);
        lastProcessed = u.time;
    }
}

void processRegenOutOfRange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
        lastProcessed = u.time - 1;
    }

    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        uTimes.at(u.id).pop();
        keyTimes.push(u2);
    }

    //cout << u.id << " becomes unkillable at time " << u.time << endl;

    if (canKill[u.id]) {
        canKill[u.id] = false;
        numKillable--;
    }

    if (keyTimes.empty() || keyTimes.top().time > u.time) {
        updateBest(u.time);
        lastProcessed = u.time;
    }

}

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

    init();

    while (!keyTimes.empty()) {
        update u = keyTimes.top();
        keyTimes.pop();
        if (u.health == -1) {
            processRegenOutOfRange(u);
        } else {
            processHealthChange(u);
        }
    }

    //cout << numKillable << " killable in the end." << endl;
    if (numKillable > 0 && increase > 0) {
        cout << -1 << endl;
        return 0;
    }

    cout << best << endl;

	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;

//READ THE PROBLEM!
//ll or int?

//Template contributed by GitHub user bqi343

const int MAXN = 100000;

int maxH[MAXN], regen[MAXN], startH[MAXN];
bool canKill[MAXN];
int N, M, damage, numKillable; int curU = 0; ll best = 0;
ll bounty, increase;
int lastProcessed = -100;

struct update {
    int id;
    int time;
    int health;
    bool operator <(const update& rhs) const {
        return time > rhs.time;
    }
};

priority_queue<update> keyTimes;
vector<priority_queue<update> > uTimes;

void updateBest(int time) {
    ll cur = (bounty + increase * time) * numKillable;
    //cout << "Can earn " << cur << " at " << time << endl;
    best = max(cur, best);

}

void init() {
    cin >> N >> M >> bounty >> increase >> damage;
    priority_queue<update> pq;
    F0R(i, N) {
        cin >> maxH[i] >> startH[i] >> regen[i];

        uTimes.pb(pq);
    }

    F0R(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
        update u = { b - 1, a, c };
        uTimes.at(i).push(u);
    }

    numKillable = 0;

    F0R(i, N) {
        if (maxH[i] <= damage) {
            canKill[i] = true;
            numKillable++;
        } else {
            if (startH[i] > damage) {
                canKill[i] = false;
                if (!uTimes.at(i).empty()) {
                    keyTimes.push(uTimes.at(i).top());
                    uTimes.at(i).pop();
                }
            } else {
                canKill[i] = true;
                numKillable++;
                int t = -1;
                if (regen[i] != 0) t = ceil(((double) damage + 1 - (double) startH[i]) / (double) regen[i]);
                int h = -1;

                if (!uTimes.at(i).empty()) {
                    if (uTimes.at(i).top().time < t) {
                        t = uTimes.at(i).top().time;
                        h = uTimes.at(i).top().health;
                        uTimes.at(i).pop();
                    }
                }
                update u = { i, t, h };
                if (t != -1) keyTimes.push(u);

            }
        }
    }

    updateBest(0);
}

void processHealthChange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
    }

    if (canKill[u.id] && u.health > damage) {
        canKill[u.id] = false;
        numKillable--;
    } else if (!canKill[u.id] && u.health < damage) {
        canKill[u.id] = true;
        numKillable++;
    }

    int t = -1;
    int h = -1;
    if (u.health <= damage && regen[u.id] != 0) {
        t = u.time + ceil(((double) damage + 1 - (double) u.health) / (double) regen[u.id]);
        //cout << "Enemy " << u.id << " will be unkillable at time " << t << endl;
    }

    //cout << "About to check change " << u.id << endl;
    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        if (t == -1 || u2.time < t) {
            uTimes.at(u.id).pop();
            t = u2.time;
            h = u2.health;
        }
    }
    //cout << "Success" << endl;
    update u2 = {u.id, t, h};
    if (t != -1) keyTimes.push(u2);

    if (keyTimes.top().time > u.time) {
        updateBest(u.time);
    }
}

void processRegenOutOfRange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
    }

    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        uTimes.at(u.id).pop();
        keyTimes.push(u2);
    }

    assert(canKill[u.id]);
    canKill[u.id] = false;
    numKillable--;

    if (keyTimes.top().time > u.time) {
        updateBest(u.time);
    }

}

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

    init();

    while (!keyTimes.empty()) {
        update u = keyTimes.top();
        keyTimes.pop();
        if (u.health == -1) {
            processRegenOutOfRange(u);
        } else {
            processHealthChange(u);
        }
    }

    if (numKillable == N) {
        cout << -1 << endl;
        return 0;
    }

    cout << best << endl;

	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;

//READ THE PROBLEM!
//ll or int?

//Template contributed by GitHub user bqi343

const int MAXN = 100000;

int maxH[MAXN], regen[MAXN], startH[MAXN];
bool canKill[MAXN];
int N, M, damage, numKillable; int curU = 0; ll best = 0;
ll bounty, increase;
int lastProcessed = -100;

struct update {
    int id;
    int time;
    int health;
    bool operator <(const update& rhs) const {
        return time > rhs.time;
    }
};

priority_queue<update> keyTimes;
vector<priority_queue<update> > uTimes;

void updateBest(int time) {
    ll cur = (bounty + increase * time) * numKillable;
    //cout << "Can earn " << cur << " at " << time << endl;
    best = max(cur, best);

}

void init() {
    cin >> N >> M >> bounty >> increase >> damage;
    priority_queue<update> pq;
    F0R(i, N) {
        cin >> maxH[i] >> startH[i] >> regen[i];

        uTimes.pb(pq);
    }

    F0R(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
        update u = { b - 1, a, c };
        uTimes.at(b-1).push(u);
    }

    numKillable = 0;

    F0R(i, N) {
        if (maxH[i] <= damage) {
            canKill[i] = true;
            numKillable++;
        } else {
            if (startH[i] > damage) {
                canKill[i] = false;
                if (!uTimes.at(i).empty()) {
                    keyTimes.push(uTimes.at(i).top());
                    uTimes.at(i).pop();
                }
            } else {
                canKill[i] = true;
                numKillable++;
                int t = -1;
                if (regen[i] != 0) t = ceil(((double) damage + 1 - (double) startH[i]) / (double) regen[i]);
                int h = -1;

                if (!uTimes.at(i).empty()) {
                    if (uTimes.at(i).top().time < t) {
                        t = uTimes.at(i).top().time;
                        h = uTimes.at(i).top().health;
                        uTimes.at(i).pop();
                    }
                }
                update u = { i, t, h };
                if (t != -1) keyTimes.push(u);

            }
        }
    }

    updateBest(0);
}

void processHealthChange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
    }

    if (canKill[u.id] && u.health > damage) {
        canKill[u.id] = false;
        numKillable--;
    } else if (!canKill[u.id] && u.health < damage) {
        canKill[u.id] = true;
        numKillable++;
    }

    int t = -1;
    int h = -1;
    if (u.health <= damage && regen[u.id] != 0) {
        t = u.time + ceil(((double) damage + 1 - (double) u.health) / (double) regen[u.id]);
        //cout << "Enemy " << u.id << " will be unkillable at time " << t << endl;
    }

    //cout << "About to check change " << u.id << endl;
    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        if (t == -1 || u2.time < t) {
            uTimes.at(u.id).pop();
            t = u2.time;
            h = u2.health;
        }
    }
    //cout << "Success" << endl;
    update u2 = {u.id, t, h};
    if (t != -1) keyTimes.push(u2);

    if (keyTimes.empty() || keyTimes.top().time > u.time) {
        updateBest(u.time);
    }
}

void processRegenOutOfRange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
    }

    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        uTimes.at(u.id).pop();
        keyTimes.push(u2);
    }

    if (canKill[u.id]) {
        canKill[u.id] = false;
        numKillable--;
    }

    if (keyTimes.empty() || keyTimes.top().time > u.time) {
        updateBest(u.time);
    }

}

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

    init();

    while (!keyTimes.empty()) {
        update u = keyTimes.top();
        keyTimes.pop();
        if (u.health == -1) {
            processRegenOutOfRange(u);
        } else {
            processHealthChange(u);
        }
    }

    if (numKillable == N) {
        cout << -1 << endl;
        return 0;
    }

    cout << best << endl;

	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;

//READ THE PROBLEM!
//ll or int?

//Template contributed by GitHub user bqi343

const int MAXN = 100000;

int maxH[MAXN], regen[MAXN], startH[MAXN];
bool canKill[MAXN];
int N, M, damage, numKillable; int curU = 0; ll best = 0;
ll bounty, increase;
int lastProcessed = -100;

struct update {
    int id;
    int time;
    int health;
    bool operator <(const update& rhs) const {
        return time > rhs.time;
    }
};

priority_queue<update> keyTimes;
vector<priority_queue<update> > uTimes;

void updateBest(int time) {
    ll cur = (bounty + increase * time) * numKillable;
    //cout << "Can earn " << cur << " at " << time << endl;
    best = max(cur, best);

}

void init() {
    cin >> N >> M >> bounty >> increase >> damage;
    priority_queue<update> pq;
    F0R(i, N) {
        cin >> maxH[i] >> startH[i] >> regen[i];

        uTimes.pb(pq);
    }

    F0R(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
        update u = { b - 1, a, c };
        uTimes.at(b-1).push(u);
    }

    numKillable = 0;

    F0R(i, N) {
        if (maxH[i] <= damage) {
            canKill[i] = true;
            numKillable++;
        } else {
            if (startH[i] > damage) {
                canKill[i] = false;
                if (!uTimes.at(i).empty()) {
                    keyTimes.push(uTimes.at(i).top());
                    uTimes.at(i).pop();
                }
            } else {
                canKill[i] = true;
                numKillable++;
                int t = -1;
                if (regen[i] != 0) t = ceil(((double) damage + 1 - (double) startH[i]) / (double) regen[i]);
                int h = -1;

                if (!uTimes.at(i).empty()) {
                    if (uTimes.at(i).top().time < t) {
                        t = uTimes.at(i).top().time;
                        h = uTimes.at(i).top().health;
                        uTimes.at(i).pop();
                    }
                }
                update u = { i, t, h };
                if (t != -1) keyTimes.push(u);

            }
        }
    }

    updateBest(0);
}

void processHealthChange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
    }

    if (canKill[u.id] && u.health > damage) {
        canKill[u.id] = false;
        numKillable--;
    } else if (!canKill[u.id] && u.health < damage) {
        canKill[u.id] = true;
        numKillable++;
    }

    int t = -1;
    int h = -1;
    if (u.health <= damage && regen[u.id] != 0) {
        t = u.time + ceil(((double) damage + 1 - (double) u.health) / (double) regen[u.id]);
        //cout << "Enemy " << u.id << " will be unkillable at time " << t << endl;
    }

    //cout << "About to check change " << u.id << endl;
    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        if (t == -1 || u2.time < t) {
            uTimes.at(u.id).pop();
            t = u2.time;
            h = u2.health;
        }
    }
    //cout << "Success" << endl;
    update u2 = {u.id, t, h};
    if (t != -1) keyTimes.push(u2);

    if (keyTimes.empty() || keyTimes.top().time > u.time) {
        updateBest(u.time);
    }
}

void processRegenOutOfRange(update u) {
    if (lastProcessed + 1 < u.time) {
        updateBest(u.time - 1);
    }

    if (!uTimes.at(u.id).empty()) {
        update u2 = uTimes.at(u.id).top();
        uTimes.at(u.id).pop();
        keyTimes.push(u2);
    }

    if (canKill[u.id]) {
        canKill[u.id] = false;
        numKillable--;
    }

    if (keyTimes.empty() || keyTimes.top().time > u.time) {
        updateBest(u.time);
    }

}

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

    init();

    while (!keyTimes.empty()) {
        update u = keyTimes.top();
        keyTimes.pop();
        if (u.health == -1) {
            processRegenOutOfRange(u);
        } else {
            processHealthChange(u);
        }
    }

    if (numKillable == N && increase > 0) {
        cout << -1 << endl;
        return 0;
    }

    cout << best << endl;

	return 0;
}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        String l = sc.next();
        String r = sc.next();

        int[] lidx = new int[N];
        Arrays.fill(lidx,-1);

        //right boot map
        Map<Character, List<Integer>> rmap = new HashMap<>();
        for (int i = 0; i < N ; i++) {
            char c = r.charAt(i);
            if(!rmap.containsKey(c)){
                List<Integer> list = new LinkedList<>();
                rmap.put(c,list);
                list.add(i);
            }else{
                List<Integer> list = rmap.get(c);
                list.add(i);
            }
        }
        //loop left boot
        for (int i = 0; i < N ; i++) {
            char c = l.charAt(i);
            if(c == '?') continue; // skip wildcard at this moment
            if(rmap.containsKey(c)){
                List<Integer> list = rmap.get(c);
                lidx[i] = list.get(0);
                //clean up
                list.remove(0);
                if(list.size()==0){
                    rmap.remove(c);
                }
            }else if(rmap.containsKey('?')){
                List<Integer> list = rmap.get('?');
                lidx[i] = list.get(0);
                //clean up
                list.remove(0);
                if(list.size()==0){
                    rmap.remove(c);
                }
            }
        }

        for (int i = 0; i < N ; i++) {
            char c = l.charAt(i);
            if(c =='?'){
                for(Iterator<Map.Entry<Character,List<Integer>>> it = rmap.entrySet().iterator();it.hasNext() ;){
                    Map.Entry<Character,List<Integer>> e = it.next();
                    List<Integer> list = e.getValue();
                    Integer idx = list.get(0);
                    lidx[i] = idx;
                    list.remove(0);
                    if(list.size()==0){
                        it.remove();
                    }
                    break;
                }
            }
        }
        int count =0;
        for (int i = 0; i < N; i++) {
            if(lidx[i] != -1 ){
                count ++;
            }
        }
        System.out.println(count);
        for (int i = 0; i < N; i++) {
            if(lidx[i] != -1 )
            System.out.println((i+1)+" " + (lidx[i]+1));
        }

    }}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        String l = sc.next();
        String r = sc.next();

        int[] lidx = new int[N];
        Arrays.fill(lidx,-1);

        //right boot map
        Map<Character, List<Integer>> rmap = new HashMap<>();
        for (int i = 0; i < N ; i++) {
            char c = r.charAt(i);
            if(!rmap.containsKey(c)){
                List<Integer> list = new LinkedList<>();
                rmap.put(c,list);
                list.add(i);
            }else{
                List<Integer> list = rmap.get(c);
                list.add(i);
            }
        }
        //loop left boot
        for (int i = 0; i < N ; i++) {
            char c = l.charAt(i);
            if(c == '?') continue; // skip wildcard at this moment
            if(rmap.containsKey(c)){
                List<Integer> list = rmap.get(c);
                lidx[i] = list.get(0);
                //clean up
                list.remove(0);
                if(list.size()==0){
                    rmap.remove(c);
                }
            }else if(rmap.containsKey('?')){
                List<Integer> list = rmap.get('?');
                lidx[i] = list.get(0);
                //clean up
                list.remove(0);
                if(list.size()==0){
                    rmap.remove('?');
                }
            }
        }

        for (int i = 0; i < N ; i++) {
            char c = l.charAt(i);
            if(c =='?'){
                for(Iterator<Map.Entry<Character,List<Integer>>> it = rmap.entrySet().iterator();it.hasNext() ;){
                    Map.Entry<Character,List<Integer>> e = it.next();
                    List<Integer> list = e.getValue();
                    Integer idx = list.get(0);
                    lidx[i] = idx;
                    list.remove(0);
                    if(list.size()==0){
                        it.remove();
                    }
                    break;
                }
            }
        }
        int count =0;
        for (int i = 0; i < N; i++) {
            if(lidx[i] != -1 ){
                count ++;
            }
        }
        System.out.println(count);
        for (int i = 0; i < N; i++) {
            if(lidx[i] != -1 )
            System.out.println((i+1)+" " + (lidx[i]+1));
        }

    }}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        String l = sc.next();
        String r = sc.next();

        int[] lidx = new int[N];
        Arrays.fill(lidx,-1);

        //right boot map
        Map<Character, List<Integer>> rmap = new HashMap<>();
        for (int i = 0; i < N ; i++) {
            char c = r.charAt(i);
            if(!rmap.containsKey(c)){
                List<Integer> list = new LinkedList<>();
                rmap.put(c,list);
                list.add(i);
            }else{
                List<Integer> list = rmap.get(c);
                list.add(i);
            }
        }
        //loop left boot
        for (int i = 0; i < N ; i++) {
            char c = l.charAt(i);
            if(c == '?') continue; // skip wildcard at this moment
            if(rmap.containsKey(c)){
                List<Integer> list = rmap.get(c);
                lidx[i] = list.get(0);
                //clean up
                list.remove(0);
                if(list.size()==0){
                    rmap.remove(c);
                }
            }else if(rmap.containsKey('?')){
                List<Integer> list = rmap.get('?');
                lidx[i] = list.get(0);
                //clean up
                list.remove(0);
                if(list.size()==0){
                    rmap.remove(c);
                }
            }
        }

        for (int i = 0; i < N ; i++) {
            char c = l.charAt(i);
            if(c =='?'){
                for (Map.Entry<Character,List<Integer>> e : rmap.entrySet()){
                    List<Integer> list = e.getValue();
                    Integer idx = list.get(0);
                    lidx[i] = idx;
                    list.remove(0);
                    if(list.size()==0){
                        rmap.remove(e.getKey());
                    }
                    break;
                }
            }
        }
        int count =0;
        for (int i = 0; i < N; i++) {
            if(lidx[i] != -1 ){
                count ++;
            }
        }
        System.out.println(count);
        for (int i = 0; i < N; i++) {
            if(lidx[i] != -1 )
            System.out.println((i+1)+" " + (lidx[i]+1));
        }

    }}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        String l = sc.next();
        String r = sc.next();

        int[] lidx = new int[N];
        Arrays.fill(lidx,-1);

        //right boot map
        Map<Character, List<Integer>> rmap = new HashMap<>();
        for (int i = 0; i < N ; i++) {
            char c = r.charAt(i);
            if(!rmap.containsKey(c)){
                List<Integer> list = new ArrayList<>();
                rmap.put(c,list);
                list.add(i);
            }else{
                List<Integer> list = rmap.get(c);
                list.add(i);
            }
        }
        //loop left boot
        for (int i = 0; i < N ; i++) {
            char c = l.charAt(i);
            if(c == '?') continue; // skip wildcard at this moment
            if(rmap.containsKey(c)){
                List<Integer> list = rmap.get(c);
                lidx[i] = list.get(0);
                //clean up
                list.remove(0);
                if(list.size()==0){
                    rmap.remove(c);
                }
            }else if(rmap.containsKey('?')){
                List<Integer> list = rmap.get('?');
                lidx[i] = list.get(0);
                //clean up
                list.remove(0);
                if(list.size()==0){
                    rmap.remove(c);
                }
            }
        }

        for (int i = 0; i < N ; i++) {
            char c = l.charAt(i);
            if(c =='?'){
                for (Map.Entry<Character,List<Integer>> e : rmap.entrySet()){
                    List<Integer> list = e.getValue();
                    Integer idx = list.get(0);
                    lidx[i] = idx;
                    list.remove(0);
                    if(list.size()==0){
                        rmap.remove(e.getKey());
                    }
                    break;
                }
            }
        }
        int count =0;
        for (int i = 0; i < N; i++) {
            if(lidx[i] != -1 ){
                count ++;
            }
        }
        System.out.println(count);
        for (int i = 0; i < N; i++) {
            if(lidx[i] != -1 )
            System.out.println((i+1)+" " + (lidx[i]+1));
        }

    }}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Washoum
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        inputClass in = new inputClass(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DColoredBoots solver = new DColoredBoots();
        solver.solve(1, in, out);
        out.close();
    }

    static class DColoredBoots {
        public void solve(int testNumber, inputClass sc, PrintWriter out) {
            int n = sc.nextInt();
            String l = sc.nextLine();
            String r = sc.nextLine();

            HashMap<Character, ArrayList<Integer>> mapl = new HashMap<>();

            for (int i = 0; i < n; i++) {
                mapl.putIfAbsent(l.charAt(i), new ArrayList<>());
                mapl.get(l.charAt(i)).add(i);
            }

            HashMap<Character, ArrayList<Integer>> mapr = new HashMap<>();
            for (int i = 0; i < n; i++) {
                mapr.putIfAbsent(r.charAt(i), new ArrayList<>());
                mapr.get(r.charAt(i)).add(i);
            }

            for (char i = 'a'; i <= 'z'; i++) {
                mapl.putIfAbsent(i, new ArrayList<>());
                mapr.putIfAbsent(i, new ArrayList<>());
            }
            mapl.putIfAbsent('?', new ArrayList<>());
            mapr.putIfAbsent('?', new ArrayList<>());
            ArrayList<Integer> ans1 = new ArrayList<>();
            ArrayList<Integer> ans2 = new ArrayList<>();

            for (char i = 'a'; i <= 'z'; i++) {
                while (mapl.get(i).size() > 0 && mapr.get(i).size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                }
                while (mapl.get(i).size() > 0 && mapr.get('?').size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get('?').remove(mapr.get('?').size() - 1);
                }
                while (mapr.get(i).size() > 0 && mapl.get('?').size() > 0) {
                    ans1.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                    mapl.get('?').remove(mapl.get('?').size() - 1);
                }
            }

            while (mapl.get('?').size() > 0 && mapr.get('?').size() > 0) {
                ans1.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                ans2.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                mapr.get('?').remove(mapr.get('?').size() - 1);
                mapl.get('?').remove(mapl.get('?').size() - 1);
            }
            out.println(ans1.size());
            for (int i = 0; i < ans1.size(); i++) {
                out.println(ans1.get(i) + " " + ans2.get(i));
            }
        }

    }

    static class inputClass {
        BufferedReader br;
        StringTokenizer st;

        public inputClass(InputStream in) {

            br = new BufferedReader(new InputStreamReader(in));
        }

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

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

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Washoum
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        inputClass in = new inputClass(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DColoredBoots solver = new DColoredBoots();
        solver.solve(1, in, out);
        out.close();
    }

    static class DColoredBoots {
        public void solve(int testNumber, inputClass sc, PrintWriter out) {
            int n = sc.nextInt();
            String l = sc.nextLine();
            String r = sc.nextLine();

            HashMap<Character, ArrayList<Integer>> mapl = new HashMap<>();

            for (int i = 0; i < n; i++) {
                mapl.putIfAbsent(l.charAt(i), new ArrayList<>());
                mapl.get(l.charAt(i)).add(i);
            }

            HashMap<Character, ArrayList<Integer>> mapr = new HashMap<>();
            for (int i = 0; i < n; i++) {
                mapr.putIfAbsent(r.charAt(i), new ArrayList<>());
                mapr.get(r.charAt(i)).add(i);
            }

            for (char i = 'a'; i < 'z'; i++) {
                mapl.putIfAbsent(i, new ArrayList<>());
                mapr.putIfAbsent(i, new ArrayList<>());
            }
            mapl.putIfAbsent('?', new ArrayList<>());
            mapr.putIfAbsent('?', new ArrayList<>());
            ArrayList<Integer> ans1 = new ArrayList<>();
            ArrayList<Integer> ans2 = new ArrayList<>();

            for (char i = 'a'; i < 'z'; i++) {
                while (mapl.get(i).size() > 0 && mapr.get(i).size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                }
                while (mapl.get(i).size() > 0 && mapr.get('?').size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get('?').remove(mapr.get('?').size() - 1);
                }
                while (mapr.get(i).size() > 0 && mapl.get('?').size() > 0) {
                    ans1.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                    mapl.get('?').remove(mapl.get('?').size() - 1);
                }
            }

            while (mapl.get('?').size() > 0 && mapr.get('?').size() > 0) {
                ans1.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                ans2.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                mapr.get('?').remove(mapr.get('?').size() - 1);
                mapl.get('?').remove(mapl.get('?').size() - 1);
            }
            out.println(ans1.size());
            for (int i = 0; i < ans1.size(); i++) {
                out.println(ans1.get(i) + " " + ans2.get(i));
            }
        }

    }

    static class inputClass {
        BufferedReader br;
        StringTokenizer st;

        public inputClass(InputStream in) {

            br = new BufferedReader(new InputStreamReader(in));
        }

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

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

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Washoum
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        inputClass in = new inputClass(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DColoredBoots solver = new DColoredBoots();
        solver.solve(1, in, out);
        out.close();
    }

    static class DColoredBoots {
        public void solve(int testNumber, inputClass sc, PrintWriter out) {
            int n = sc.nextInt();
            String l = sc.nextLine();
            String r = sc.nextLine();

            HashMap<Character, ArrayList<Integer>> mapl = new HashMap<>();

            for (int i = 0; i < n; i++) {
                mapl.putIfAbsent(l.charAt(i), new ArrayList<>());
                mapl.get(l.charAt(i)).add(i);
            }

            HashMap<Character, ArrayList<Integer>> mapr = new HashMap<>();
            for (int i = 0; i < n; i++) {
                mapr.putIfAbsent(r.charAt(i), new ArrayList<>());
                mapr.get(r.charAt(i)).add(i);
            }

            for (char i = 'a'; i < 'z'; i++) {
                mapl.putIfAbsent(i, new ArrayList<>());
                mapr.putIfAbsent(i, new ArrayList<>());
            }
            mapl.putIfAbsent('?', new ArrayList<>());
            mapr.putIfAbsent('?', new ArrayList<>());
            ArrayList<Integer> ans1 = new ArrayList<>();
            ArrayList<Integer> ans2 = new ArrayList<>();

            for (char i = 'a'; i <= 'z'; i++) {
                while (mapl.get(i).size() > 0 && mapr.get(i).size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                }
                while (mapl.get(i).size() > 0 && mapr.get('?').size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get('?').remove(mapr.get('?').size() - 1);
                }
                while (mapr.get(i).size() > 0 && mapl.get('?').size() > 0) {
                    ans1.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                    mapl.get('?').remove(mapl.get('?').size() - 1);
                }
            }

            while (mapl.get('?').size() > 0 && mapr.get('?').size() > 0) {
                ans1.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                ans2.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                mapr.get('?').remove(mapr.get('?').size() - 1);
                mapl.get('?').remove(mapl.get('?').size() - 1);
            }
            out.println(ans1.size());
            for (int i = 0; i < ans1.size(); i++) {
                out.println(ans1.get(i) + " " + ans2.get(i));
            }
        }

    }

    static class inputClass {
        BufferedReader br;
        StringTokenizer st;

        public inputClass(InputStream in) {

            br = new BufferedReader(new InputStreamReader(in));
        }

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

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

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Washoum
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        inputClass in = new inputClass(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DColoredBoots solver = new DColoredBoots();
        solver.solve(1, in, out);
        out.close();
    }

    static class DColoredBoots {
        public void solve(int testNumber, inputClass sc, PrintWriter out) {
            int n = sc.nextInt();
            String l = sc.nextLine();
            String r = sc.nextLine();

            HashMap<Character, ArrayList<Integer>> mapl = new HashMap<>();

            for (int i = 0; i < n; i++) {
                mapl.putIfAbsent(l.charAt(i), new ArrayList<>());
                mapl.get(l.charAt(i)).add(i);
            }

            HashMap<Character, ArrayList<Integer>> mapr = new HashMap<>();
            for (int i = 0; i < n; i++) {
                mapr.putIfAbsent(r.charAt(i), new ArrayList<>());
                mapr.get(r.charAt(i)).add(i);
            }

            for (char i = 'a'; i < 'z'; i++) {
                mapl.putIfAbsent(i, new ArrayList<>());
                mapr.putIfAbsent(i, new ArrayList<>());
            }
            mapl.putIfAbsent('?', new ArrayList<>());
            mapr.putIfAbsent('?', new ArrayList<>());
            ArrayList<Integer> ans1 = new ArrayList<>();
            ArrayList<Integer> ans2 = new ArrayList<>();

            for (char i = 'a'; i < 'z'; i++) {
                while (mapl.get(i).size() > 0 && mapr.get(i).size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                }
                while (mapl.get(i).size() > 0 && mapr.get('?').size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get('?').remove(mapr.get('?').size() - 1);
                }
                while (mapr.get(i).size() > 0 && mapl.get('?').size() > 0) {
                    ans1.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    ans2.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                    mapl.get('?').remove(mapl.get('?').size() - 1);
                }
            }

            while (mapl.get('?').size() > 0 && mapr.get('?').size() > 0) {
                ans1.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                ans2.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                mapr.get('?').remove(mapr.get('?').size() - 1);
                mapl.get('?').remove(mapl.get('?').size() - 1);
            }
            out.println(ans1.size());
            for (int i = 0; i < ans1.size(); i++) {
                out.println(ans1.get(i) + " " + ans2.get(i));
            }
        }

    }

    static class inputClass {
        BufferedReader br;
        StringTokenizer st;

        public inputClass(InputStream in) {

            br = new BufferedReader(new InputStreamReader(in));
        }

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

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

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Washoum
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        inputClass in = new inputClass(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DColoredBoots solver = new DColoredBoots();
        solver.solve(1, in, out);
        out.close();
    }

    static class DColoredBoots {
        public void solve(int testNumber, inputClass sc, PrintWriter out) {
            int n = sc.nextInt();
            String l = sc.nextLine();
            String r = sc.nextLine();

            HashMap<Character, ArrayList<Integer>> mapl = new HashMap<>();

            for (int i = 0; i < n; i++) {
                mapl.putIfAbsent(l.charAt(i), new ArrayList<>());
                mapl.get(l.charAt(i)).add(i);
            }

            HashMap<Character, ArrayList<Integer>> mapr = new HashMap<>();
            for (int i = 0; i < n; i++) {
                mapr.putIfAbsent(r.charAt(i), new ArrayList<>());
                mapr.get(r.charAt(i)).add(i);
            }

            for (char i = 'a'; i < 'z'; i++) {
                mapl.putIfAbsent(i, new ArrayList<>());
                mapr.putIfAbsent(i, new ArrayList<>());
            }
            mapl.putIfAbsent('?', new ArrayList<>());
            mapr.putIfAbsent('?', new ArrayList<>());
            ArrayList<Integer> ans1 = new ArrayList<>();
            ArrayList<Integer> ans2 = new ArrayList<>();

            for (char i = 'a'; i < 'z'; i++) {
                while (mapl.get(i).size() > 0 && mapr.get(i).size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                }
                while (mapl.get(i).size() > 0 && mapr.get('?').size() > 0) {
                    ans1.add(mapl.get(i).get(mapl.get(i).size() - 1) + 1);
                    ans2.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                    mapl.get(i).remove(mapl.get(i).size() - 1);
                    mapr.get('?').remove(mapr.get('?').size() - 1);
                }
                while (mapr.get(i).size() > 0 && mapl.get('?').size() > 0) {
                    ans1.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                    ans2.add(mapr.get(i).get(mapr.get(i).size() - 1) + 1);
                    mapr.get(i).remove(mapr.get(i).size() - 1);
                    mapl.get('?').remove(mapl.get('?').size() - 1);
                }
            }

            while (mapl.get('?').size() > 0 && mapr.get('?').size() > 0) {
                ans1.add(mapr.get('?').get(mapr.get('?').size() - 1) + 1);
                ans2.add(mapl.get('?').get(mapl.get('?').size() - 1) + 1);
                mapr.get('?').remove(mapr.get('?').size() - 1);
                mapl.get('?').remove(mapl.get('?').size() - 1);
            }
            out.println(ans1.size());
            for (int i = 0; i < ans1.size(); i++) {
                out.println(ans1.get(i) + " " + ans2.get(i));
            }
        }

    }

    static class inputClass {
        BufferedReader br;
        StringTokenizer st;

        public inputClass(InputStream in) {

            br = new BufferedReader(new InputStreamReader(in));
        }

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

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

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;

public class D1141 {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(f.readLine());
		String l = f.readLine(); String r = f.readLine();

		HashMap<Character,LinkedList<Integer>> lmap = new HashMap<Character,LinkedList<Integer>>();
		HashMap<Character,LinkedList<Integer>> rmap = new HashMap<Character,LinkedList<Integer>>();
		boolean lq = false; boolean rq = false;
		for (int i=0; i<n; i++) {
			if (l.charAt(i)=='?') lq=true;
			if (r.charAt(i)=='?') rq=true;
			if (lmap.containsKey(l.charAt(i))) {
				LinkedList<Integer> al = lmap.get(l.charAt(i));
				al.add(i+1);
				lmap.put(l.charAt(i),al);
			}
			else {
				LinkedList<Integer> al = new LinkedList<Integer>(); al.add(i+1); lmap.put(l.charAt(i),al);
			}
			if (rmap.containsKey(r.charAt(i))) {
				LinkedList<Integer> ar = rmap.get(r.charAt(i));
				ar.add(i+1);
				rmap.put(r.charAt(i),ar);
			}
			else {
				LinkedList<Integer> ar = new LinkedList<Integer>(); ar.add(i+1); rmap.put(r.charAt(i),ar);
			}

		}
		LinkedList<Integer> lflex = new LinkedList<Integer>();
		LinkedList<Integer> rflex = new LinkedList<Integer>();
		if (lq) {
			lflex = lmap.get('?'); rflex = rmap.get('?');
		}
		//System.out.println(lflex.size() + " " + rflex.size());

		int compatible = 0;
		ArrayList<Integer> leftIndex = new ArrayList<Integer>();
		ArrayList<Integer> rightIndex = new ArrayList<Integer>();

		//Object[] x = rmap.get('e').toArray();
		//for (int i=0; i<x.length; i++) System.out.println(x[i]);

		for (int i=97; i<123; i++) {
			char c = (char) i;
			if (c=='?') continue;
			if (lmap.containsKey(c) && rmap.containsKey(c)) {
				//System.out.println(c);
				LinkedList<Integer> left = lmap.get(c);
				LinkedList<Integer> right = rmap.get(c);
				//if (c=='e') System.out.println(left.size() + " " + right.size());
				//if (c=='e') System.out.println(Math.min(left.size(),right.size()));
				int s1 = left.size(); int s2 = right.size();
				for (int j=0; j<Math.min(s1, s2); j++) {
					int a = left.removeLast(); int b = right.removeLast();
					//if (c=='e') System.out.println(j);
					leftIndex.add(a);
					rightIndex.add(b);
					compatible++;
				}
			}
			else if (lmap.containsKey(c)) {
				LinkedList<Integer> left = lmap.get(c);
				while (rflex.size()!=0 && left.size()!=0) {
					leftIndex.add(left.removeLast());
					rightIndex.add(rflex.removeLast());
					compatible++;
				}
			}
			else if (rmap.containsKey(c)) {
				LinkedList<Integer> right = rmap.get(c);
				while (lflex.size()!=0 && right.size()!=0) {
					leftIndex.add(lflex.removeLast());
					rightIndex.add(right.removeLast());
					compatible++;
				}
			}
		}

		while (lflex.size()!=0 && rflex.size()!=0) {
			leftIndex.add(lflex.removeLast());
			rightIndex.add(rflex.removeLast());
			compatible++;
		}

		System.out.println(compatible);
		for (int i=0; i<leftIndex.size(); i++) {
			System.out.println(leftIndex.get(i) + " " + rightIndex.get(i));
		}
		/*
		int[] lmap = new int[26]; int[] rmap = new int[26];
		int lq = 0; int rq = 0;

		for (int i=0; i<n; i++) {
			if (l.charAt(i)=='?') lq++;
			else lmap[((int) l.charAt(i))-97] += 1;
			if (r.charAt(i)=='?') rq++;
			else rmap[((int) r.charAt(i))-97] += 1;
		}*/
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;

public class D1141 {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(f.readLine());
		String l = f.readLine(); String r = f.readLine();

		HashMap<Character,LinkedList<Integer>> lmap = new HashMap<Character,LinkedList<Integer>>();
		HashMap<Character,LinkedList<Integer>> rmap = new HashMap<Character,LinkedList<Integer>>();
		boolean lq = false; boolean rq = false;
		for (int i=0; i<n; i++) {
			if (l.charAt(i)=='?') lq=true;
			if (r.charAt(i)=='?') rq=true;
			if (lmap.containsKey(l.charAt(i))) {
				LinkedList<Integer> al = lmap.get(l.charAt(i));
				al.add(i+1);
				lmap.put(l.charAt(i),al);
			}
			else {
				LinkedList<Integer> al = new LinkedList<Integer>(); al.add(i+1); lmap.put(l.charAt(i),al);
			}
			if (rmap.containsKey(r.charAt(i))) {
				LinkedList<Integer> ar = rmap.get(r.charAt(i));
				ar.add(i+1);
				rmap.put(r.charAt(i),ar);
			}
			else {
				LinkedList<Integer> ar = new LinkedList<Integer>(); ar.add(i+1); rmap.put(r.charAt(i),ar);
			}

		}
		LinkedList<Integer> lflex = new LinkedList<Integer>();
		LinkedList<Integer> rflex = new LinkedList<Integer>();
		if (lq) {
			lflex = lmap.get('?');
		}
		if (rq) {
			rflex = rmap.get('?');
		}
		//System.out.println(lflex.size() + " " + rflex.size());

		int compatible = 0;
		ArrayList<Integer> leftIndex = new ArrayList<Integer>();
		ArrayList<Integer> rightIndex = new ArrayList<Integer>();

		//Object[] x = rmap.get('e').toArray();
		//for (int i=0; i<x.length; i++) System.out.println(x[i]);

		for (int i=97; i<123; i++) {
			char c = (char) i;
			if (c=='?') continue;
			if (lmap.containsKey(c) && rmap.containsKey(c)) {
				//System.out.println(c);
				LinkedList<Integer> left = lmap.get(c);
				LinkedList<Integer> right = rmap.get(c);
				//if (c=='e') System.out.println(left.size() + " " + right.size());
				//if (c=='e') System.out.println(Math.min(left.size(),right.size()));
				int s1 = left.size(); int s2 = right.size();
				for (int j=0; j<Math.min(s1, s2); j++) {
					int a = left.removeLast(); int b = right.removeLast();
					//if (c=='e') System.out.println(j);
					leftIndex.add(a);
					rightIndex.add(b);
					compatible++;
				}
			}
			if (lmap.containsKey(c)) {
				LinkedList<Integer> left = lmap.get(c);
				while (rflex.size()!=0 && left.size()!=0) {
					leftIndex.add(left.removeLast());
					rightIndex.add(rflex.removeLast());
					compatible++;
				}
			}
			if (rmap.containsKey(c)) {
				LinkedList<Integer> right = rmap.get(c);
				while (lflex.size()!=0 && right.size()!=0) {
					leftIndex.add(lflex.removeLast());
					rightIndex.add(right.removeLast());
					compatible++;
				}
			}
		}

		while (lflex.size()!=0 && rflex.size()!=0) {
			leftIndex.add(lflex.removeLast());
			rightIndex.add(rflex.removeLast());
			compatible++;
		}

		System.out.println(compatible);
		for (int i=0; i<leftIndex.size(); i++) {
			System.out.println(leftIndex.get(i) + " " + rightIndex.get(i));
		}
		/*
		int[] lmap = new int[26]; int[] rmap = new int[26];
		int lq = 0; int rq = 0;

		for (int i=0; i<n; i++) {
			if (l.charAt(i)=='?') lq++;
			else lmap[((int) l.charAt(i))-97] += 1;
			if (r.charAt(i)=='?') rq++;
			else rmap[((int) r.charAt(i))-97] += 1;
		}*/
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.util.LinkedList;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jenish
 */
public class Main {

    public static void main(String[] args) {
        new Thread(null, new Runnable() {
            public void run() {
                new Main().solve();
            }
        }, "1", 1 << 26).start();
    }

    void solve() {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DColoredBoots solver = new DColoredBoots();
        solver.solve(1, in, out);
        out.close();
    }

    static class DColoredBoots {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            LinkedList<Integer>[] arrayListsL = new LinkedList[27];
            LinkedList<Integer>[] arrayListsR = new LinkedList[27];
            for (int i = 0; i <= 26; i++) {
                arrayListsL[i] = new LinkedList<>();
                arrayListsR[i] = new LinkedList<>();
            }

            char arr[] = in.scanString().toCharArray();
            for (int i = 0; i < n; i++) {
                if (arr[i] == '?') arrayListsL[26].add(i + 1);
                else arrayListsL[arr[i] - 'a'].add(i + 1);
            }

            arr = in.scanString().toCharArray();
            for (int i = 0; i < n; i++) {
                if (arr[i] == '?') arrayListsR[26].add(i + 1);
                else arrayListsR[arr[i] - 'a'].add(i + 1);
            }

            ArrayList<pair> ans = new ArrayList<>();
            for (int i = 0; i < 26; i++) {
                while (arrayListsR[i].size() > 0) {
                    if (arrayListsL[i].size() > 0) {
                        int l = arrayListsL[i].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[i].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                    } else if (arrayListsL[26].size() > 0) {
                        int l = arrayListsL[26].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[26].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                    } else {
                        break;
                    }
                }
            }

            while (arrayListsR[26].size() > 0) {
                for (int i = 0; i <= 26; i++) {
                    while (arrayListsL[i].size() > 0) {
                        int l = arrayListsL[i].getLast();
                        int r = arrayListsR[26].getLast();
                        arrayListsL[i].removeLast();
                        arrayListsR[26].removeLast();
                        ans.add(new pair(l, r));
                        if (arrayListsR[26].size() <= 0) {
                            break;
                        }
                    }
                }
            }

            while (arrayListsL[26].size() > 0) {
                for (int i = 0; i <= 26; i++) {
                    while (arrayListsR[i].size() > 0) {
                        int l = arrayListsL[26].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[26].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                        if (arrayListsL[26].size() <= 0) {
                            break;
                        }
                    }
                }
            }

            out.println(ans.size());
            for (int i = 0; i < ans.size(); i++) {
                out.println(ans.get(i).x + " " + ans.get(i).y);
            }

        }

        class pair {
            int x;
            int y;

            public pair(int x, int y) {
                this.x = x;
                this.y = y;
            }

        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        public String scanString() {
            int c = scan();
            while (isWhiteSpace(c)) c = scan();
            StringBuilder RESULT = new StringBuilder();
            do {
                RESULT.appendCodePoint(c);
                c = scan();
            } while (!isWhiteSpace(c));
            return RESULT.toString();
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.util.LinkedList;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jenish
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DColoredBoots solver = new DColoredBoots();
        solver.solve(1, in, out);
        out.close();
    }

    static class DColoredBoots {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            LinkedList<Integer>[] arrayListsL = new LinkedList[27];
            LinkedList<Integer>[] arrayListsR = new LinkedList[27];
            for (int i = 0; i <= 26; i++) {
                arrayListsL[i] = new LinkedList<>();
                arrayListsR[i] = new LinkedList<>();
            }

            char arr[] = in.scanString().toCharArray();
            for (int i = 0; i < n; i++) {
                if (arr[i] == '?') arrayListsL[26].add(i + 1);
                else arrayListsL[arr[i] - 'a'].add(i + 1);
            }

            arr = in.scanString().toCharArray();
            for (int i = 0; i < n; i++) {
                if (arr[i] == '?') arrayListsR[26].add(i + 1);
                else arrayListsR[arr[i] - 'a'].add(i + 1);
            }

            ArrayList<pair> ans = new ArrayList<>();
            for (int i = 0; i < 26; i++) {
                while (arrayListsR[i].size() > 0) {
                    if (arrayListsL[i].size() > 0) {
                        int l = arrayListsL[i].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[i].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                    } else if (arrayListsL[26].size() > 0) {
                        int l = arrayListsL[26].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[26].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                    } else {
                        break;
                    }
                }
            }

            while (arrayListsR[26].size() > 0) {
                for (int i = 0; i <= 26; i++) {
                    while (arrayListsL[i].size() > 0) {
                        int l = arrayListsL[i].getLast();
                        int r = arrayListsR[26].getLast();
                        arrayListsL[i].removeLast();
                        arrayListsR[26].removeLast();
                        ans.add(new pair(l, r));
                        if (arrayListsR[26].size() == 0) {
                            break;
                        }
                    }
                }
            }

            while (arrayListsL[26].size() > 0) {
                for (int i = 0; i <= 26; i++) {
                    while (arrayListsR[i].size() > 0) {
                        int l = arrayListsL[26].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[26].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                        if (arrayListsL[26].size() == 0) {
                            break;
                        }
                    }
                }
            }

            out.println(ans.size());
            for (int i = 0; i < ans.size(); i++) {
                out.println(ans.get(i).x + " " + ans.get(i).y);
            }

        }

        class pair {
            int x;
            int y;

            public pair(int x, int y) {
                this.x = x;
                this.y = y;
            }

        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        public String scanString() {
            int c = scan();
            while (isWhiteSpace(c)) c = scan();
            StringBuilder RESULT = new StringBuilder();
            do {
                RESULT.appendCodePoint(c);
                c = scan();
            } while (!isWhiteSpace(c));
            return RESULT.toString();
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.util.LinkedList;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jenish
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DColoredBoots solver = new DColoredBoots();
        solver.solve(1, in, out);
        out.close();
    }

    static class DColoredBoots {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            LinkedList<Integer>[] arrayListsL = new LinkedList[27];
            LinkedList<Integer>[] arrayListsR = new LinkedList[27];
            for (int i = 0; i < 27; i++) {
                arrayListsL[i] = new LinkedList<>();
                arrayListsR[i] = new LinkedList<>();
            }

            char arr[] = in.scanString().toCharArray();
            for (int i = 0; i < n; i++) {
                if (arr[i] == '?') arrayListsL[26].add(i + 1);
                else arrayListsL[arr[i] - 'a'].add(i + 1);
            }

            arr = in.scanString().toCharArray();
            for (int i = 0; i < n; i++) {
                if (arr[i] == '?') arrayListsR[26].add(i + 1);
                else arrayListsR[arr[i] - 'a'].add(i + 1);
            }

            ArrayList<pair> ans = new ArrayList<>();

            for (int i = 0; i < 26; i++) {
                while (arrayListsR[i].size() > 0) {
                    if (arrayListsL[i].size() > 0) {
                        int l = arrayListsL[i].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[i].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                    } else if (arrayListsL[26].size() > 0) {
                        int l = arrayListsL[26].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[26].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                    } else {
                        break;
                    }
                }
            }

            while (arrayListsR[26].size() > 0) {
                for (int i = 0; i <= 26; i++) {
                    boolean f = false;
                    while (arrayListsL[i].size() > 0) {
                        int l = arrayListsL[i].getLast();
                        int r = arrayListsR[26].getLast();
                        arrayListsL[i].removeLast();
                        arrayListsR[26].removeLast();
                        ans.add(new pair(l, r));
                        if (arrayListsR[26].size() <= 0) {
                            f = true;
                            break;
                        }
                    }
                    if (f) {
                        break;
                    }
                }
            }

            while (arrayListsL[26].size() > 0) {
                for (int i = 0; i <= 26; i++) {
                    boolean f = false;
                    while (arrayListsR[i].size() > 0) {
                        int l = arrayListsL[26].getLast();
                        int r = arrayListsR[i].getLast();
                        arrayListsL[26].removeLast();
                        arrayListsR[i].removeLast();
                        ans.add(new pair(l, r));
                        if (arrayListsL[26].size() <= 0) {
                            f = true;
                            break;
                        }
                    }
                    if (f) {
                        break;
                    }
                }
            }

            out.println(ans.size());
            for (int i = 0; i < ans.size(); i++) {
                out.println(ans.get(i).x + " " + ans.get(i).y);
            }

        }

        class pair {
            int x;
            int y;

            public pair(int x, int y) {
                this.x = x;
                this.y = y;
            }

        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        public String scanString() {
            int c = scan();
            while (isWhiteSpace(c)) c = scan();
            StringBuilder RESULT = new StringBuilder();
            do {
                RESULT.appendCodePoint(c);
                c = scan();
            } while (!isWhiteSpace(c));
            return RESULT.toString();
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}


import java.io.*;
import java.util.*;

public class tr3 {
    static ArrayList<Integer>[]ed;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n=sc.nextInt();
		String s=sc.nextLine();
		String h=sc.nextLine();
		int [] ss=new int [26];
		int [] hh=new int [26];
		ArrayList <Integer> []ad=new ArrayList[26];
		for(int i=0;i<26;i++)
			ad[i]=new ArrayList();
		for(int i=0;i<n;i++) {
			int t=(h.charAt(i)-'a');
			if(h.charAt(i)!='?')
			ad[t].add(i+1);
		}
		Queue <pair> ans=new LinkedList();
		ArrayList <Integer> pp=new ArrayList();
		ArrayList <Integer> oo=new ArrayList();
		boolean [] H=new boolean[n];
		boolean [] S=new boolean[n];
		int sn=0;
		int hn=0;
		for(int i=0;i<n;i++) {
			if(s.charAt(i)!='?')
				ss[s.charAt(i)-'a']++;
			else {
				sn++;
				pp.add(i+1);
			}
		}
		for(int i=0;i<n;i++) {
			if(h.charAt(i)!='?')
				hh[h.charAt(i)-'a']++;
			else {
				hn++;
				oo.add(i+1);
			}
		}
		for(int i=0;i<n;i++) {
			int t=s.charAt(i)-'a';
			if(s.charAt(i)!='?' &&ad[t].size()!=0) {
				ans.add(new pair(i+1,ad[t].get(0)));
				H[ad[t].get(0)-1]=true;
				S[i]=true;
				ad[t].remove(0);
				}
		}
		for(int i=0;i<n;i++) {
			if(!H[i] && sn!=0 && h.charAt(i)!='?') {
				sn--;
				H[i]=true;
				ans.add(new pair(pp.get(0),i+1));
				S[pp.get(0)-1]=true;
				pp.remove(0);
			}
		}
		for(int i=0;i<n;i++) {
			if(!S[i] && hn!=0 && s.charAt(i)!='?') {
				hn--;
				S[i]=true;
				ans.add(new pair(i+1,oo.get(0)));
				H[oo.get(0)-1]=true;
				oo.remove(0);
			}
		}
		int i=0;
		int j=0;
		while(i<pp.size() || j<oo.size()) {
		ans.add(new pair(pp.get(i),oo.get(j)));
		i++;
		j++;
		}
		out.println(ans.size());
		for(pair kk:ans) {
			out.println(kk);
		}
		out.flush();
	}
	static final long mod=(long)1e9+7;
	static long fac(long n) {
		if(n==0 || n==1)
			return 1;
		long a=1;
		while(n>0) {
			a*=n;
			n--;
		}
		return a;
	}
	static boolean io=false;
	static boolean []vis;
    static void dfs(int u,int w) {
    	vis[u]=true;
    	if(u==w)
    		 io=true;
    	for(int v:ed[u]) {
    		if(!vis[v]) {
    	   dfs(v,w);
    		}
    	}
    	//return false;
    }
	static int gcd(int a, int b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	static class pair{
		int a;
	    int b;

		pair(int a,int b) {
			this.a = a;
			this.b = b;
		}

		public String toString() {
			return a + " " + b;
			}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

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

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

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}


import java.io.*;
import java.util.*;

public class tr3 {
    static ArrayList<Integer>[]ed;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n=sc.nextInt();
		String s=sc.nextLine();
		String h=sc.nextLine();
		int [] ss=new int [26];
		int [] hh=new int [26];
		ArrayList <Integer> []ad=new ArrayList[26];
		for(int i=0;i<26;i++)
			ad[i]=new ArrayList();
		for(int i=0;i<n;i++) {
			int t=(h.charAt(i)-'a');
			if(h.charAt(i)!='?')
			ad[t].add(i+1);
		}
		Queue <pair> ans=new LinkedList();
		ArrayList <Integer> pp=new ArrayList();
		ArrayList <Integer> oo=new ArrayList();
		boolean [] H=new boolean[n];
		boolean [] S=new boolean[n];
		int sn=0;
		int hn=0;
		for(int i=0;i<n;i++) {
			if(s.charAt(i)!='?')
				ss[s.charAt(i)-'a']++;
			else {
				sn++;
				pp.add(i+1);
			}
		}
		for(int i=0;i<n;i++) {
			if(h.charAt(i)!='?')
				hh[h.charAt(i)-'a']++;
			else {
				hn++;
				oo.add(i+1);
			}
		}
		for(int i=0;i<n;i++) {
			int t=s.charAt(i)-'a';
			if(s.charAt(i)!='?' &&ad[t].size()!=0) {
				ans.add(new pair(i+1,ad[t].get(0)));
				H[ad[t].get(0)-1]=true;
				S[i]=true;
				ad[t].remove(0);
				}
		}
		int p=0;
		for(int i=0;i<n;i++) {
			if(!H[i] && sn!=0 && h.charAt(i)!='?') {
				sn--;
				H[i]=true;
				ans.add(new pair(pp.get(p),i+1));
				S[pp.get(p)-1]=true;
			}
		}
		int o=0;
		for(int i=0;i<n;i++) {
			if(!S[i] && hn!=0 && s.charAt(i)!='?') {
				hn--;
				S[i]=true;
				ans.add(new pair(i+1,oo.get(o)));
				H[oo.get(o)-1]=true;

			}
		}
		int i=0;
		int j=0;
		while(i<pp.size() || j<oo.size()) {
		ans.add(new pair(pp.get(i),oo.get(j)));
		i++;
		j++;
		}
		out.println(ans.size());
		for(pair kk:ans) {
			out.println(kk);
		}
		out.flush();
	}
	static final long mod=(long)1e9+7;
	static long fac(long n) {
		if(n==0 || n==1)
			return 1;
		long a=1;
		while(n>0) {
			a*=n;
			n--;
		}
		return a;
	}
	static boolean io=false;
	static boolean []vis;
    static void dfs(int u,int w) {
    	vis[u]=true;
    	if(u==w)
    		 io=true;
    	for(int v:ed[u]) {
    		if(!vis[v]) {
    	   dfs(v,w);
    		}
    	}
    	//return false;
    }
	static int gcd(int a, int b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	static class pair{
		int a;
	    int b;

		pair(int a,int b) {
			this.a = a;
			this.b = b;
		}

		public String toString() {
			return a + " " + b;
			}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

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

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

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}


import java.io.*;
import java.util.*;

public class tr3 {
    static ArrayList<Integer>[]ed;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n=sc.nextInt();
		String s=sc.nextLine();
		String h=sc.nextLine();
		int [] ss=new int [26];
		int [] hh=new int [26];
		ArrayList <Integer> []ad=new ArrayList[26];
		for(int i=0;i<26;i++)
			ad[i]=new ArrayList();
		for(int i=0;i<n;i++) {
			int t=(h.charAt(i)-'a');
			if(h.charAt(i)!='?')
			ad[t].add(i+1);
		}
		Queue <pair> ans=new LinkedList();
		ArrayList <Integer> pp=new ArrayList();
		ArrayList <Integer> oo=new ArrayList();
		boolean [] H=new boolean[n];
		boolean [] S=new boolean[n];
		int sn=0;
		int hn=0;
		for(int i=0;i<n;i++) {
			if(s.charAt(i)!='?')
				ss[s.charAt(i)-'a']++;
			else {
				sn++;
				pp.add(i+1);
			}
		}
		for(int i=0;i<n;i++) {
			if(h.charAt(i)!='?')
				hh[h.charAt(i)-'a']++;
			else {
				hn++;
				oo.add(i+1);
			}
		}
		for(int i=0;i<n;i++) {
			int t=s.charAt(i)-'a';
			if(s.charAt(i)!='?' &&ad[t].size()!=0) {
				ans.add(new pair(i+1,ad[t].get(0)));
				H[ad[t].get(0)-1]=true;
				S[i]=true;
				ad[t].remove(0);
				}
		}
		for(int i=0;i<n;i++) {
			if(!H[i] && sn!=0 && h.charAt(i)!='?') {
				sn--;
				H[i]=true;
				ans.add(new pair(pp.get(0),i+1));
				S[pp.get(0)-1]=true;
				pp.remove(0);
			}
		}
		for(int i=0;i<n;i++) {
			if(!S[i] && hn!=0 && s.charAt(i)!='?') {
				hn--;
				S[i]=true;
				ans.add(new pair(i+1,oo.get(0)));
				H[oo.get(0)-1]=true;
				oo.remove(0);
			}
		}
		while(!pp.isEmpty() || !oo.isEmpty()) {
		ans.add(new pair(pp.get(0),oo.get(0)));
		pp.remove(0);
		oo.remove(0);
		}
		out.println(ans.size());
		for(pair kk:ans) {
			out.println(kk);
		}
		out.flush();
	}
	static final long mod=(long)1e9+7;
	static long fac(long n) {
		if(n==0 || n==1)
			return 1;
		long a=1;
		while(n>0) {
			a*=n;
			n--;
		}
		return a;
	}
	static boolean io=false;
	static boolean []vis;
    static void dfs(int u,int w) {
    	vis[u]=true;
    	if(u==w)
    		 io=true;
    	for(int v:ed[u]) {
    		if(!vis[v]) {
    	   dfs(v,w);
    		}
    	}
    	//return false;
    }
	static int gcd(int a, int b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	static class pair{
		int a;
	    int b;

		pair(int a,int b) {
			this.a = a;
			this.b = b;
		}

		public String toString() {
			return a + " " + b;
			}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

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

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

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}


import java.io.*;
import java.util.*;

public class tr3 {
    static ArrayList<Integer>[]ed;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n=sc.nextInt();
		String s=sc.nextLine();
		String h=sc.nextLine();
		int [] ss=new int [26];
		int [] hh=new int [26];
		Queue <Integer> []ad=new LinkedList[26];
		for(int i=0;i<26;i++)
			ad[i]=new LinkedList();
		for(int i=0;i<n;i++) {
			int t=(h.charAt(i)-'a');
			if(h.charAt(i)!='?')
			ad[t].add(i+1);
		}
		Queue <pair> ans=new LinkedList();
		Queue <Integer> pp=new LinkedList();
		Queue <Integer> oo=new LinkedList();
		boolean [] H=new boolean[n];
		boolean [] S=new boolean[n];
		int sn=0;
		int hn=0;
		for(int i=0;i<n;i++) {
			if(s.charAt(i)!='?')
				ss[s.charAt(i)-'a']++;
			else {
				sn++;
				pp.add(i+1);
			}
		}
		for(int i=0;i<n;i++) {
			if(h.charAt(i)!='?')
				hh[h.charAt(i)-'a']++;
			else {
				hn++;
				oo.add(i+1);
			}
		}
		for(int i=0;i<n;i++) {
			int t=s.charAt(i)-'a';
			if(s.charAt(i)!='?' &&ad[t].size()!=0) {
				int ad1=ad[t].remove();
				ans.add(new pair(i+1,ad1));
				H[ad1-1]=true;
				S[i]=true;
				}
		}
		for(int i=0;i<n;i++) {
			if(!H[i] && sn!=0 && h.charAt(i)!='?') {
				sn--;
				int p=pp.remove();
				H[i]=true;
				ans.add(new pair(p,i+1));
				S[p-1]=true;
			}
		}
		for(int i=0;i<n;i++) {
			if(!S[i] && hn!=0 && s.charAt(i)!='?') {
				hn--;
				int o=oo.remove();
				S[i]=true;
				ans.add(new pair(i+1,o));
				H[o-1]=true;

			}
		}
		int i=0;
		int j=0;
		while(!pp.isEmpty() || !oo.isEmpty()) {
		ans.add(new pair(pp.remove(),oo.remove()));
		}
		out.println(ans.size());
		for(pair kk:ans) {
			out.println(kk);
		}
		out.flush();
	}
	static final long mod=(long)1e9+7;
	static long fac(long n) {
		if(n==0 || n==1)
			return 1;
		long a=1;
		while(n>0) {
			a*=n;
			n--;
		}
		return a;
	}
	static boolean io=false;
	static boolean []vis;
    static void dfs(int u,int w) {
    	vis[u]=true;
    	if(u==w)
    		 io=true;
    	for(int v:ed[u]) {
    		if(!vis[v]) {
    	   dfs(v,w);
    		}
    	}
    	//return false;
    }
	static int gcd(int a, int b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	static class pair{
		int a;
	    int b;

		pair(int a,int b) {
			this.a = a;
			this.b = b;
		}

		public String toString() {
			return a + " " + b;
			}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

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

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

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}


import java.util.*;
import java.io.*;

public class D1141 {

	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			int n = Integer.parseInt(br.readLine());

			ArrayList<Pair> ans = new ArrayList<>();
			String s1 = br.readLine();
			String s2 = br.readLine();
			for(int i = 0;i < n; i++) {
				if(s1.charAt(i) != '?' && s1.charAt(i) != '1') {
					String ch = s1.charAt(i) + "";
					if(s2.contains(ch)) {
						int y = s2.indexOf(ch);
						Pair p = new Pair();
						p.x = i + 1; p.y = y + 1;
						ans.add(p);
						s2 = s2.replaceFirst(ch, "1");
						s1 = s1.replaceFirst(ch, "1");
					}
					else {
						if(s2.indexOf("?") >= 0) {
							int y = s2.indexOf("?");
							Pair p = new Pair();
							p.x = i + 1; p.y = y + 1;
							ans.add(p);
							s2 = s2.replaceFirst("\\?", "1");//Regex
							s1 = s1.replaceFirst(ch, "1");

						}

					}

				}
				if(s2.charAt(i) != '?' && s2.charAt(i) != '1') {
					String ch = s2.charAt(i) + "";
					if(s1.contains(ch)) {
						int y = s1.indexOf(ch);
						Pair p = new Pair();
						p.x = y + 1; p.y = i + 1;
						ans.add(p);
						s1 = s1.replaceFirst(ch, "1");
						s2 = s2.replaceFirst(ch, "1");

					}
					else {
						if(s1.indexOf("?") >= 0) {
							int y = s1.indexOf("?");
							Pair p = new Pair();
							p.x = y + 1; p.y = i + 1;
							ans.add(p);
							s1 = s1.replaceFirst("\\?", "1");
							s2 = s2.replaceFirst(ch, "1");

						}

					}

				}

			}
			//Till here all the definite colors finished
			for(int i = 0;i < n; i++) {
				if(s1.charAt(i) == '?') {
					if(s2.indexOf("?") >= 0) {
						int y = s2.indexOf("?");
						Pair p = new Pair();
						p.x = i + 1; p.y = y + 1;
						ans.add(p);
						s2 = s2.replaceFirst("\\?", "1");
						s1 = s1.replaceFirst("\\?", "1");

					}
				}
			}
			System.out.println(ans.size());
			if(ans.size() > 0) {
				for(Pair p : ans) {
					System.out.println(p.x + " " + p.y);
				}
			}

	}

}
class Pair {
	int x;
	int y;
}


import java.util.*;
import java.io.*;

public class D1141 {

	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			int n = Integer.parseInt(br.readLine());

			ArrayList<Pair> ans = new ArrayList<>();
			String s1 = br.readLine();
			String s2 = br.readLine();
			for(int i = 0;i < n; i++) {
				if(s1.charAt(i) != '?' && s1.charAt(i) != '1') {
					String ch = s1.charAt(i) + "";
					if(s2.contains(ch)) {
						int y = s2.indexOf(ch);
						Pair p = new Pair();
						p.x = i + 1; p.y = y + 1;
						ans.add(p);
						s2 = s2.replaceFirst(ch, "1");
						s1 = s1.replaceFirst(ch, "1");
						System.out.println(s1 + " " + s2);
					}
					else {
						if(s2.indexOf("?") >= 0) {
							int y = s2.indexOf("?");
							Pair p = new Pair();
							p.x = i + 1; p.y = y + 1;
							ans.add(p);
							s2 = s2.replaceFirst("\\?", "1");//Regex
							s1 = s1.replaceFirst(ch, "1");
							System.out.println(s1 + " " + s2);

						}

					}

				}
				if(s2.charAt(i) != '?' && s2.charAt(i) != '1') {
					String ch = s2.charAt(i) + "";
					if(s1.contains(ch)) {
						int y = s1.indexOf(ch);
						Pair p = new Pair();
						p.x = y + 1; p.y = i + 1;
						ans.add(p);
						s1 = s1.replaceFirst(ch, "1");
						s2 = s2.replaceFirst(ch, "1");
						System.out.println(s1 + " " + s2);

					}
					else {
						if(s1.indexOf("?") >= 0) {
							int y = s1.indexOf("?");
							Pair p = new Pair();
							p.x = y + 1; p.y = i + 1;
							ans.add(p);
							s1 = s1.replaceFirst("\\?", "1");
							s2 = s2.replaceFirst(ch, "1");
							System.out.println(s1 + " " + s2);

						}

					}

				}

			}
			//Till here all the definite colors finished
			for(int i = 0;i < n; i++) {
				if(s1.charAt(i) == '?') {
					if(s2.indexOf("?") >= 0) {
						int y = s2.indexOf("?");
						Pair p = new Pair();
						p.x = i + 1; p.y = y + 1;
						ans.add(p);
						s2 = s2.replaceFirst("\\?", "1");
						s1 = s1.replaceFirst("\\?", "1");

					}
				}
			}
			System.out.println(ans.size());
			if(ans.size() > 0) {
				for(Pair p : ans) {
					System.out.println(p.x + " " + p.y);
				}
			}

	}

}
class Pair {
	int x;
	int y;
}