#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define PER(I, N) for (int I = (N); I >= 0; --I)
#define PERR(I, A, B) for (int I = (A); I >= B; --I)
#define ITR(I, A) for (__typeof((A).begin()) I=(A).begin(), _##i=(A).end(); I!=_##i; ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define F first
#define S second
#define LB(X) __builtin_ctz((X))
#define ONES(X) __builtin_popcount((X))
typedef long long LL;
using namespace std;
template <class T>  inline void smax(T &x,T y){ x = max((x), (y));}
template <class T>  inline void smin(T &x,T y){ x = min((x), (y));}
const int MOD = 1e9+7;
const int MOD2 = 1e9+9;
const int MOD3 = 1e9+21;
const int SIZE = 2*1e5+10;
const int INF = 0x3f3f3f3f;
const int MN = 300;
#define LOCALTEST 0 // change this to 1 to perform localtest on "in.txt"
int e,s,n,m;
vector<PII> v, V[4];
PII dp[SIZE];
PII go(int idx) {
    //printf("trying dp[%d]\n", idx);
    PII &ret = dp[idx];
    if (ret.F != -2) return ret;
    if (v[idx].F == e) return ret = MP(0, 0);
    if (v[idx+1].F > v[idx].F + s) return ret = MP(-1, -1);

    ret = MP(-1,-1);

    int pos = v[idx].F, x = v[idx].S;
    bool done = false;
    REPP(i,x,4) {
        if (done) break;
        vector<PII>::iterator it = lower_bound(ALL(V[i]), MP(pos+1,0));
        if (it != V[i].end() && v[it->S].F <= pos + s) {
            PII k = go(it->S);
            if (k.F >= 0) {
                int need = it->F - pos;
                if (x == 1) {
                    k.F += need;
                } else if (x == 2) {
                    k.S += need;
                }
            }
            ret = k;
            done = true;
        }
    }
    PERR(i,x-1,1) {
        if (done) break;
        vector<PII>::iterator it = upper_bound(ALL(V[i]), MP(pos+s+1,-1));
        if (it == V[i].begin()) continue;
        it--;
        //printf("v[%d].F = %d\n", it->S, v[it->S].F);
        if (v[it->S].F > pos && v[it->S].F <= pos + s) {
            PII k = go(it->S);
            if (k.F >= 0) {
                int need = it->F - pos;
                if (x == 2) {
                    k.S += s;
                    k.F -= s - need;
                } else if (x == 3) {
                    if (i == 2) {
                        k.S -= s - need;
                    } else if (i == 1) {
                        k.F -= s - need;
                    }
                }
            }
            ret = k;
            done = true;
        }
    }
    //printf("dp[%d] = %d %d\n", idx, ret.F, ret.S);
    return ret;
}
int main(){
    if (LOCALTEST) {
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    }
    while (RII(e,s) == 2) {
        RII(n,m);
        v.clear();
        v.PB(MP(e,3));
        REP(i,n) {
            DRII(t,x);
            if (x >= e) continue;
            v.PB(MP(x,t));
        }
        sort(ALL(v));
        //REP(i,SZ(v)) printf("(%d,%d)%c",v[i].F,v[i].S,i==SZ(v)-1?'\n':' ');
        REP(i,4) V[i].clear();
        REP(i,SZ(v)) V[v[i].S].PB(MP(v[i].F, i));

        REP(i,SIZE) dp[i] = MP(-2,-2);

        REP(i,m) {
            DRI(st);
            if (st + s >= e) {
                printf("0 0\n");
                continue;
            }

            PII ret = MP(-1,-1);
            int pos = st, x = 3;
            bool done = false;
            REPP(i,x,4) {
                if (done) break;
                vector<PII>::iterator it = lower_bound(ALL(V[i]), MP(pos+1,0));
                if (it != V[i].end() && v[it->S].F <= pos + s) {
                    //if (it != V[i].end()) printf("iterator %d, v[%d].F = %d\n", it - V[i].begin(), it->S, v[it->S].F);
                    PII k = go(it->S);
                    if (k.F >= 0) {
                        int need = it->F - pos;
                        if (x == 1) {
                            k.F += need;
                        } else if (x == 2) {
                            k.S += need;
                        }
                    }
                    ret = k;
                    done = true;
                }
            }
            PERR(i,x-1,1) {
                if (done) break;
                vector<PII>::iterator it = upper_bound(ALL(V[i]), MP(pos+s+1,-1));
                if (it == V[i].begin()) continue;
                it--;
                if (v[it->S].F > pos && v[it->S].F <= pos + s) {
                    //printf("iterator %d, v[%d].F = %d\n", it - V[i].begin(), it->S, v[it->S].F);
                    PII k = go(it->S);
                    if (k.F >= 0) {
                        int need = it->F - pos;
                        if (x == 2) {
                            k.S += need;
                        } else if (x == 3) {
                            if (i == 2) {
                                k.S -= s - need;
                            } else if (i == 1) {
                                k.F -= s - need;
                            }
                        }
                    }
                    ret = k;
                    done = true;
                }
            }
            printf("%d %d\n", ret.F, ret.S);
        }
    }
    return 0;
}

// 0010011110
// answer 3


#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define PER(I, N) for (int I = (N); I >= 0; --I)
#define PERR(I, A, B) for (int I = (A); I >= B; --I)
#define ITR(I, A) for (__typeof((A).begin()) I=(A).begin(), _##i=(A).end(); I!=_##i; ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define F first
#define S second
#define LB(X) __builtin_ctz((X))
#define ONES(X) __builtin_popcount((X))
typedef long long LL;
using namespace std;
template <class T>  inline void smax(T &x,T y){ x = max((x), (y));}
template <class T>  inline void smin(T &x,T y){ x = min((x), (y));}
const int MOD = 1e9+7;
const int MOD2 = 1e9+9;
const int MOD3 = 1e9+21;
const int SIZE = 2*1e5+10;
const int INF = 0x3f3f3f3f;
const int MN = 300;
#define LOCALTEST 0 // change this to 1 to perform localtest on "in.txt"
int e,s,n,m;
vector<PII> v, V[4];
PII dp[SIZE];
PII go(int idx) {
    //printf("trying dp[%d]\n", idx);
    PII &ret = dp[idx];
    if (ret.F != -2) return ret;
    if (v[idx].F == e) return ret = MP(0, 0);
    if (v[idx+1].F > v[idx].F + s) return ret = MP(-1, -1);

    ret = MP(-1,-1);

    int pos = v[idx].F, x = v[idx].S;
    bool done = false;
    REPP(i,x,4) {
        if (done) break;
        vector<PII>::iterator it = lower_bound(ALL(V[i]), MP(pos+1,0));
        if (it != V[i].end() && v[it->S].F <= pos + s) {
            PII k = go(it->S);
            if (k.F >= 0) {
                int need = it->F - pos;
                if (x == 1) {
                    k.F += need;
                } else if (x == 2) {
                    k.S += need;
                }
            }
            ret = k;
            done = true;
        }
    }
    PERR(i,x-1,1) {
        if (done) break;
        vector<PII>::iterator it = upper_bound(ALL(V[i]), MP(pos+s+1,-1));
        if (it == V[i].begin()) continue;
        it--;
        //printf("v[%d].F = %d\n", it->S, v[it->S].F);
        if (v[it->S].F > pos && v[it->S].F <= pos + s) {
            PII k = go(it->S);
            if (k.F >= 0) {
                int need = it->F - pos;
                if (x == 2) {
                    k.S += s;
                    k.F -= s - need;
                } else if (x == 3) {
                    if (i == 2) {
                        k.S -= s - need;
                    } else if (i == 1) {
                        k.F -= s - need;
                    }
                }
            }
            ret = k;
            done = true;
        }
    }
    //printf("dp[%d] = %d %d\n", idx, ret.F, ret.S);
    return ret;
}
int main(){
    if (LOCALTEST) {
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    }
    while (RII(e,s) == 2) {
        RII(n,m);
        v.clear();
        v.PB(MP(e,3));
        REP(i,n) {
            DRII(t,x);
            if (x >= e) continue;
            v.PB(MP(x,t));
        }
        sort(ALL(v));
        //REP(i,SZ(v)) printf("(%d,%d)%c",v[i].F,v[i].S,i==SZ(v)-1?'\n':' ');
        REP(i,4) V[i].clear();
        REP(i,SZ(v)) V[v[i].S].PB(MP(v[i].F, i));

        REP(i,SIZE) dp[i] = MP(-2,-2);

        REP(i,m) {
            DRI(st);
            if (st + s >= e) {
                printf("0 0\n");
                continue;
            }

            PII ret = MP(-1,-1);
            int pos = st, x = 3;
            bool done = false;
            REPP(i,x,4) {
                if (done) break;
                vector<PII>::iterator it = lower_bound(ALL(V[i]), MP(pos+1,0));
                if (it != V[i].end() && v[it->S].F <= pos + s) {
                    //if (it != V[i].end()) printf("iterator %d, v[%d].F = %d\n", it - V[i].begin(), it->S, v[it->S].F);
                    PII k = go(it->S);
                    if (k.F >= 0) {
                        int need = it->F - pos;
                        if (x == 1) {
                            k.F += need;
                        } else if (x == 2) {
                            k.S += need;
                        }
                    }
                    ret = k;
                    done = true;
                }
            }
            PERR(i,x-1,1) {
                if (done) break;
                vector<PII>::iterator it = upper_bound(ALL(V[i]), MP(pos+s+1,-1));
                if (it == V[i].begin()) continue;
                it--;
                if (v[it->S].F >= pos && v[it->S].F <= pos + s) {
                    //printf("iterator %d, v[%d].F = %d\n", it - V[i].begin(), it->S, v[it->S].F);
                    PII k = go(it->S);
                    if (k.F >= 0) {
                        int need = it->F - pos;
                        if (x == 2) {
                            k.S += need;
                        } else if (x == 3) {
                            if (i == 2) {
                                k.S -= s - need;
                            } else if (i == 1) {
                                k.F -= s - need;
                            }
                        }
                    }
                    ret = k;
                    done = true;
                }
            }
            printf("%d %d\n", ret.F, ret.S);
        }
    }
    return 0;
}

// 0010011110
// answer 3


#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define PER(I, N) for (int I = (N); I >= 0; --I)
#define PERR(I, A, B) for (int I = (A); I >= B; --I)
#define ITR(I, A) for (__typeof((A).begin()) I=(A).begin(), _##i=(A).end(); I!=_##i; ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define F first
#define S second
#define LB(X) __builtin_ctz((X))
#define ONES(X) __builtin_popcount((X))
typedef long long LL;
using namespace std;
template <class T>  inline void smax(T &x,T y){ x = max((x), (y));}
template <class T>  inline void smin(T &x,T y){ x = min((x), (y));}
const int MOD = 1e9+7;
const int MOD2 = 1e9+9;
const int MOD3 = 1e9+21;
const int SIZE = 2*1e5+10;
const int INF = 0x3f3f3f3f;
const int MN = 300;
#define LOCALTEST 0 // change this to 1 to perform localtest on "in.txt"
int e,s,n,m;
vector<PII> v, V[4];
PII dp[SIZE];
PII go(int idx) {
    //printf("trying dp[%d]\n", idx);
    PII &ret = dp[idx];
    if (ret.F != -2) return ret;
    if (v[idx].F == e) return ret = MP(0, 0);
    if (v[idx+1].F > v[idx].F + s) return ret = MP(-1, -1);

    ret = MP(-1,-1);

    int pos = v[idx].F, x = v[idx].S;
    bool done = false;

    REPP(i,x,4) {
        vector<PII>::iterator it = lower_bound(ALL(V[i]), MP(pos+1,0));
        if (it != V[i].end() && v[it->S].F <= pos + s) {
            PII k = go(it->S);
            if (k.F >= 0) {
                int need = it->F - pos;
                if (x == 1) {
                    k.F += need;
                } else if (x == 2) {
                    k.S += need;
                }
            }
            if (ret.F < 0) ret = k;
            else if (ret.F > k.F) ret = k;
            else if (ret.F == k.F && ret.S > k.S) ret = k;
            done = true;
        }
    }
    PERR(i,x-1,1) {
        if (done) break;
        vector<PII>::iterator it = upper_bound(ALL(V[i]), MP(pos+s+1,-1));
        if (it == V[i].begin()) continue;
        it--;
        //printf("v[%d].F = %d\n", it->S, v[it->S].F);
        if (v[it->S].F > pos && v[it->S].F <= pos + s) {
            PII k = go(it->S);
            if (k.F >= 0) {
                int need = it->F - pos;
                if (x == 2) {
                    k.S += s;
                    k.F -= s - need;
                } else if (x == 3) {
                    if (i == 2) {
                        k.S -= s - need;
                    } else if (i == 1) {
                        k.F -= s - need;
                    }
                }
            }
            ret = k;
            done = true;
        }
    }
    //printf("dp[%d] = %d %d\n", idx, ret.F, ret.S);
    return ret;
}
int main(){
    if (LOCALTEST) {
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    }
    while (RII(e,s) == 2) {
        RII(n,m);
        v.clear();
        v.PB(MP(e,3));
        REP(i,n) {
            DRII(t,x);
            if (x >= e) continue;
            v.PB(MP(x,t));
        }
        sort(ALL(v));
        //REP(i,SZ(v)) printf("(%d,%d)%c",v[i].F,v[i].S,i==SZ(v)-1?'\n':' ');
        REP(i,4) V[i].clear();
        REP(i,SZ(v)) V[v[i].S].PB(MP(v[i].F, i));

        REP(i,SIZE) dp[i] = MP(-2,-2);

        REP(i,m) {
            DRI(st);
            if (st + s >= e) {
                printf("0 0\n");
                continue;
            }

            PII ret = MP(-1,-1);
            int pos = st, x = 3;
            bool done = false;
            REPP(i,x,4) {
                vector<PII>::iterator it = lower_bound(ALL(V[i]), MP(pos+1,0));
                if (it != V[i].end() && v[it->S].F <= pos + s) {
                    //if (it != V[i].end()) printf("iterator %d, v[%d].F = %d\n", it - V[i].begin(), it->S, v[it->S].F);
                    PII k = go(it->S);
                    if (k.F >= 0) {
                        int need = it->F - pos;
                        if (x == 1) {
                            k.F += need;
                        } else if (x == 2) {
                            k.S += need;
                        }
                    }
                    if (ret.F < 0) ret = k;
                    else if (ret.F > k.F) ret = k;
                    else if (ret.F == k.F && ret.S > k.S) ret = k;
                    done = true;
                }
            }
            PERR(i,x-1,1) {
                if (done) break;
                vector<PII>::iterator it = upper_bound(ALL(V[i]), MP(pos+s+1,-1));
                if (it == V[i].begin()) continue;
                it--;
                if (v[it->S].F > pos && v[it->S].F <= pos + s) {
                    //printf("iterator %d, v[%d].F = %d\n", it - V[i].begin(), it->S, v[it->S].F);
                    PII k = go(it->S);
                    if (k.F >= 0) {
                        int need = it->F - pos;
                        if (x == 2) {
                            k.S += need;
                        } else if (x == 3) {
                            if (i == 2) {
                                k.S -= s - need;
                            } else if (i == 1) {
                                k.F -= s - need;
                            }
                        }
                    }
                    ret = k;
                    done = true;
                }
            }
            printf("%d %d\n", ret.F, ret.S);
        }
    }
    return 0;
}

// 0010011110
// answer 3


#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define PER(I, N) for (int I = (N); I >= 0; --I)
#define PERR(I, A, B) for (int I = (A); I >= B; --I)
#define ITR(I, A) for (__typeof((A).begin()) I=(A).begin(), _##i=(A).end(); I!=_##i; ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define F first
#define S second
#define LB(X) __builtin_ctz((X))
#define ONES(X) __builtin_popcount((X))
typedef long long LL;
using namespace std;
template <class T>  inline void smax(T &x,T y){ x = max((x), (y));}
template <class T>  inline void smin(T &x,T y){ x = min((x), (y));}
const int MOD = 1e9+7;
const int MOD2 = 1e9+9;
const int MOD3 = 1e9+21;
const int SIZE = 1e5+10;
const int INF = 0x3f3f3f3f;
const int MN = 300;
#define LOCALTEST 0 // change this to 1 to perform localtest on "in.txt"
int e,s,n,m;
vector<PII> v, V[4];
PII dp[SIZE];
PII go(int idx) {
    //printf("trying dp[%d]\n", idx);
    PII &ret = dp[idx];
    if (ret.F != -2) return ret;
    if (v[idx].F == e) return ret = MP(0, 0);
    if (v[idx+1].F > v[idx].F + s) return ret = MP(-1, -1);

    ret = MP(-1,-1);

    int pos = v[idx].F, x = v[idx].S;
    bool done = false;
    REPP(i,x,4) {
        if (done) break;
        vector<PII>::iterator it = lower_bound(ALL(V[i]), MP(pos+1,0));
        if (it != V[i].end() && v[it->S].F <= pos + s) {
            PII k = go(it->S);
            if (k.F >= 0) {
                int need = it->F - pos;
                if (x == 1) {
                    k.F += need;
                } else if (x == 2) {
                    k.S += need;
                }
            }
            ret = k;
            done = true;
        }
    }
    PERR(i,x-1,1) {
        if (done) break;
        vector<PII>::iterator it = upper_bound(ALL(V[i]), MP(pos+s,4));
        if (it == V[i].begin()) continue;
        it--;
        if (v[it->S].F <= pos + s) {
            PII k = go(it->S);
            if (k.F >= 0) {
                int need = it->F - pos;
                if (x == 2) {
                    k.S += s;
                    k.F -= s - need;
                } else if (x == 3) {
                    if (i == 2) {
                        k.S -= s - need;
                    } else if (i == 1) {
                        k.F -= s - need;
                    }
                }
            }
            ret = k;
            done = true;
        }
    }
    //printf("dp[%d] = %d %d\n", idx, ret.F, ret.S);
    return ret;
}
int main(){
    if (LOCALTEST) {
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    }
    while (RII(e,s) == 2) {
        RII(n,m);
        v.clear();
        v.PB(MP(e,3));
        REP(i,n) {
            DRII(t,x);
            if (x >= e) continue;
            v.PB(MP(x,t));
        }
        sort(ALL(v));
        //REP(i,SZ(v)) printf("(%d,%d)%c",v[i].F,v[i].S,i==SZ(v)-1?'\n':' ');
        REP(i,4) V[i].clear();
        REP(i,SZ(v)) V[v[i].S].PB(MP(v[i].F, i));

        REP(i,SIZE) dp[i] = MP(-2,-2);

        REP(i,m) {
            DRI(st);
            if (st + s >= e) {
                printf("0 0\n");
                continue;
            }

            PII ret = MP(-1,-1);
            int pos = st, x = 3;
            bool done = false;
            REPP(i,x,4) {
                if (done) break;
                vector<PII>::iterator it = lower_bound(ALL(V[i]), MP(pos+1,0));
                //if (it != V[i].end()) printf("iterator %d, v[%d].F = %d\n", it - V[i].begin(), it->S, v[it->S].F);
                if (it != V[i].end() && v[it->S].F <= pos + s) {
                    PII k = go(it->S);
                    if (k.F >= 0) {
                        int need = it->F - pos;
                        if (x == 1) {
                            k.F += need;
                        } else if (x == 2) {
                            k.S += need;
                        }
                    }
                    ret = k;
                    done = true;
                }
            }
            PERR(i,x-1,1) {
                if (done) break;
                vector<PII>::iterator it = upper_bound(ALL(V[i]), MP(pos+s,4));
                if (it == V[i].begin()) continue;
                it--;
                //printf("iterator %d, v[%d].F = %d\n", it - V[i].begin(), it->S, v[it->S].F);
                if (v[it->S].F <= pos + s) {
                    PII k = go(it->S);
                    if (k.F >= 0) {
                        int need = it->F - pos;
                        if (x == 2) {
                            k.S += need;
                        } else if (x == 3) {
                            if (i == 2) {
                                k.S -= s - need;
                            } else if (i == 1) {
                                k.F -= s - need;
                            }
                        }
                    }
                    ret = k;
                    done = true;
                }
            }
            printf("%d %d\n", ret.F, ret.S);
        }
    }
    return 0;
}

// 0010011110
// answer 3


//*
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <functional>
#define MOD 1000000007
#define MAX ((1<<30)-1)
#define MAX2 ((1ll<<62)-1)
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
typedef long double ldb;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

int en, s, n, m;
pii a[300000];
vector<pii> c[5];

struct DAT
{
	int t1, t2, t3;
	DAT(){t1=t2=t3=0;}
	DAT(int t1, int t2, int t3)
	{
		this->t1=t1, this->t2=t2, this->t3=t3;
	}
	DAT operator+(const DAT &p) const
	{
		DAT res;
		if(p.t1 < 0 || t1 < 0) return DAT(-1, -1, -1);
		res.t1=t1+p.t1, res.t2=t2+p.t2, res.t3=t3+p.t3;
		return res;
	}
};

DAT d[300000];

int find(int x, int y, int ty)
{
	int idx=lower_bound(all(c[ty]), pii(x+1, -1))-c[ty].begin();
	if(idx >= c[ty].size() || c[ty][idx].first > y) return -1;
	return c[ty][idx].second;
}

int find2(int x, int y) // 2, 3의 type를 찾아줌
{
	int u, v;
	u=find(x, y, 2);
	v=find(x, y, 3);
	if(u < 0) return v;
	if(v < 0) return u;
	return min(u, v);
}

int find3(int x, int y) // 1, 2, 3의 type를 찾아줌
{
	int u, v;
	u=find2(x, y);
	v=find(x, y, 1);
	if(u < 0) return v;
	if(v < 0) return u;
	return min(u, v);
}

DAT calcf(int x, int y)
{
	int u;
	if(a[x].first+y >= en) return DAT();
	if(a[x].first+s >= en)
	{
		if(a[x].second == 3) return DAT(0, 0, en-a[x].first-y);
		else if(a[x].second == 2)
		{
			if((u=find(a[x].first, en, 3)) < 0) return DAT(0, en-a[x].first-y, 0);
			else return DAT(0, max(0, a[u].first-(a[x].first+y)), 0)+calcf(u, max(0, y-(a[u].first-a[x].first)));
		}
		else
		{
			if((u=find2(a[x].first, en)) < 0) return DAT(en-a[x].first-y, 0, 0);
			else return DAT(max(0, a[u].first-(a[x].first+y)), 0, 0)+calcf(u, max(0, y-(a[u].first-a[x].first)));
		}
	}
	else
	{
		if(a[x].second == 3) return DAT(0, 0, s-y)+d[x];
		else if(a[x].second == 2)
		{
			if((u=find(a[x].first, a[x].first+s, 3)) < 0) return DAT(0, s-y, 0)+d[x];
			else return DAT(0, max(0, a[u].first-(a[x].first+y)), 0)+calcf(u, max(0, y-(a[u].first-a[x].first)));
		}
		else
		{
			if((u=find2(a[x].first, a[x].first+s)) < 0) return DAT(s-y, 0, 0)+d[x];
			else return DAT(max(0, a[u].first-(a[x].first+y)), 0, 0)+calcf(u, max(0, y-(a[u].first-a[x].first)));
		}
	}
}

void calcd(int x)
{
	if(a[x].first+s >= en) return;
	// 안 닿는 경우만 고려
	int u;
	if((u=find3(a[x].first, a[x].first+s)) < 0)
	{
		d[x]=DAT(-1, -1, -1);
	}
	else
	{
		d[x]=calcf(u, s-(a[u].first-a[x].first));
	}
}

int main()
{
	int i, j, k;
	cin>>en>>s>>n>>m;
	for(i=0;i<n;i++)
	{
		scanf("%d%d", &a[i].second, &a[i].first);
		if(a[i].second >= en) i--, n--;
	}
	sort(a, a+n);
	for(i=0;i<n;i++) c[a[i].second].push_back(pii(a[i].first, i));
	for(i=n-1;i>=0;i--)
	{
		calcd(i);
	}
	for(i=0;i<m;i++)
	{
		int x;
		scanf("%d", &x);
		DAT res;
		if(x+s < en)
		{
			int u;
			if((u=find3(x-1, x+s)) < 0) res=DAT(-1, -1, -1);
			else res=calcf(u, s-(a[u].first-x));
		}
		printf("%d %d\n", res.t1, res.t2);
	}
	return 0;
}
//*/


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

#define FOR(i, n) for (int i = 0; i < n; i++)

using namespace std;

const int m = 3;

struct Station{
    int x;
    pair<int, int> best;

    Station(int x){
        this->x = x;
        best = {-1, -1};
    }

    Station(){}

    const bool operator<(const Station &other)const{
        return x < other.x;
    }
};

int Binary_search(int coord, vector<Station> &stat){
    int min_i = 0, max_i = (int)stat.size() - 1;
    while (min_i < max_i){
        int mid_i = (min_i + max_i) / 2;
        if (coord < stat[mid_i].x)
            max_i = mid_i;
        else
            min_i = mid_i + 1;
    }
    return min_i;
}

int main(){
    cin.tie(NULL);
    cout.tie(NULL);
    ios_base::sync_with_stdio(false);
//    ifstream cin("581 E.in");
    int finish, max_fuel, n, test_count;
    cin >> finish >> max_fuel >> n >> test_count;
    vector<Station> stations[m];
    FOR (i, n){
        int a, b;
        cin >> a >> b;
        a--;
        if (b >= finish)
            continue;
        stations[a].push_back(Station(b));
    }
    FOR (i, m)
        stations[i].push_back(Station(finish));
    FOR (i, m)
        sort(stations[i].begin(), stations[i].end());
    int last[m];
    FOR (i, m){
        last[i] = (int)stations[i].size() - 1;
        stations[i][last[i]].best = {0, 0};
    }
    while (true){
        int type = -1;
        FOR (i, m)
            if (last[i] > 0 && (type == -1 || stations[type][last[type] - 1] < stations[i][last[i] - 1]))
                type = i;
        if (type == -1)
            break;
        Station &cur = stations[type][last[type] - 1];
        Station c[m];
        FOR (i, m)
            c[i] = stations[i][last[i]];
        if (type == 2){
            if (c[2].x - cur.x <= max_fuel)
                cur.best = c[2].best;
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.second -= cur.x + max_fuel - c[1].x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first -= cur.x + max_fuel - c[0].x;
                    }
                    else
                        break;
                }
            }
        }
        if (type == 1){
            if (c[2].x - cur.x <= max_fuel){
                cur.best = c[2].best;
                cur.best.second += c[2].x - cur.x;
            }
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.second += c[1].x - cur.x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.second += max_fuel;
                        cur.best.first -= cur.x + max_fuel - c[0].x;
                    }
                    else
                        break;
                }
            }
        }
        if (type == 0){
            if (c[2].x - cur.x <= max_fuel){
                if (c[2].x < c[1].x){
                    cur.best = c[2].best;
                    cur.best.first += c[2].x - cur.x;
                }
                else{
                    cur.best = c[1].best;
                    cur.best.first += c[1].x - cur.x;
                }
            }
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.first += c[1].x - cur.x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first += c[0].x - cur.x;
                    }
                    else
                        break;
                }
            }
        }
        last[type]--;
    }
    FOR (test_i, test_count){
        Station cur(-1);
        cin >> cur.x;
        Station c[m];
        FOR (i, m)
            c[i] = stations[i][Binary_search(cur.x, stations[i])];
        if (c[2].x - cur.x <= max_fuel)
            cur.best = c[2].best;
        else{
            if (c[1].x - cur.x <= max_fuel){
                cur.best = c[1].best;
                cur.best.second -= cur.x + max_fuel - c[1].x;
            }
            else{
                if (c[0].x - cur.x <= max_fuel){
                    cur.best = c[0].best;
                    cur.best.first -= cur.x + max_fuel - c[0].x;
                }
            }
        }
        cout << cur.best.first << ' ' << cur.best.second << endl;
    }
}


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

#define FOR(i, n) for (int i = 0; i < n; i++)

using namespace std;

const int m = 3;

struct Station{
    int x;
    pair<int, int> best;

    Station(int x){
        this->x = x;
        best = {-1, -1};
    }

    Station(){}

    const bool operator<(const Station &other)const{
        return x < other.x;
    }
};

int Binary_search(int coord, vector<Station> &stat){
    int min_i = 0, max_i = (int)stat.size() - 1;
    while (min_i < max_i){
        int mid_i = (min_i + max_i) / 2;
        if (coord < stat[mid_i].x)
            max_i = mid_i;
        else
            min_i = mid_i + 1;
    }
    return min_i;
}

int main(){
    cin.tie(NULL);
    cout.tie(NULL);
    ios_base::sync_with_stdio(false);
//    ifstream cin("581 E.in");
    int finish, max_fuel, n, test_count;
    cin >> finish >> max_fuel >> n >> test_count;
    vector<Station> stations[m];
    FOR (i, n){
        int a, b;
        cin >> a >> b;
        a--;
        if (b >= finish)
            continue;
        stations[a].push_back(Station(b));
    }
    FOR (i, m)
        stations[i].push_back(Station(finish));
    FOR (i, m)
        sort(stations[i].begin(), stations[i].end());
    int last[m];
    FOR (i, m){
        last[i] = (int)stations[i].size() - 1;
        stations[i][last[i]].best = {0, 0};
    }
    while (true){
        int type = -1;
        FOR (i, m)
            if (last[i] > 0 && (type == -1 || stations[type][last[type] - 1] < stations[i][last[i] - 1]))
                type = i;
        if (type == -1)
            break;
        Station &cur = stations[type][last[type] - 1];
        Station c[m];
        FOR (i, m)
            c[i] = stations[i][last[i]];
        if (type == 2){
            if (c[2].x - cur.x <= max_fuel)
                cur.best = c[2].best;
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.second -= cur.x + max_fuel - c[1].x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first -= cur.x + max_fuel - c[0].x;
                    }
                    else
                        break;
                }
            }
        }
        if (type == 1){
            if (c[2].x - cur.x <= max_fuel){
                cur.best = c[2].best;
                cur.best.second += c[2].x - cur.x;
            }
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.second += c[1].x - cur.x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.second += max_fuel;
                        cur.best.first -= cur.x + max_fuel - c[0].x;
                    }
                    else
                        break;
                }
            }
        }
        if (type == 0){
            if (c[2].x - cur.x <= max_fuel){
                if (c[2].x < c[1].x){
                    cur.best = c[2].best;
                    cur.best.first += c[2].x - cur.x;
                }
                else{
                    cur.best = c[1].best;
                    cur.best.first += c[1].x - cur.x;
                }
            }
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.first += c[1].x - cur.x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first += c[0].x - cur.x;
                    }
                    else
                        break;
                }
            }
        }
        last[type]--;
    }
    FOR (test_i, test_count){
        Station cur(-1);
        cin >> cur.x;
        Station c[m];
        FOR (i, m)
            c[i] = stations[i][Binary_search(cur.x, stations[i])];
        if (c[2].x - cur.x <= max_fuel)
            cur.best = c[2].best;
        else{
            if (c[1].x - cur.x <= max_fuel){
                cur.best = c[1].best;
                cur.best.second -= cur.x + max_fuel - c[1].x;
            }
            else{
                if (c[0].x - cur.x <= max_fuel){
                    cur.best = c[0].best;
                    cur.best.first -= cur.x + max_fuel - c[0].x;
                }
            }
        }
        cout << max(cur.best.first, -1) << ' ' << max(cur.best.second, -1) << endl;
    }
}


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

#define FOR(i, n) for (int i = 0; i < n; i++)

using namespace std;

const int m = 3;

struct Station{
    int x;
    pair<int, int> best;

    Station(int x){
        this->x = x;
        best = {-1, -1};
    }

    Station(){}

    const bool operator<(const Station &other)const{
        return x < other.x;
    }
};

int Binary_search(int coord, vector<Station> &stat){
    int min_i = 0, max_i = (int)stat.size() - 1;
    while (min_i < max_i){
        int mid_i = (min_i + max_i) / 2;
        if (coord < stat[mid_i].x)
            max_i = mid_i;
        else
            min_i = mid_i + 1;
    }
    return min_i;
}

int main(){
    cin.tie(NULL);
    cout.tie(NULL);
    ios_base::sync_with_stdio(false);
    ifstream cin("581 E.in");
    int finish, max_fuel, n, test_count;
    cin >> finish >> max_fuel >> n >> test_count;
    vector<Station> stations[m];
    FOR (i, n){
        int a, b;
        cin >> a >> b;
        a--;
        if (b >= finish)
            continue;
        stations[a].push_back(Station(b));
    }
    FOR (i, m)
        stations[i].push_back(Station(finish));
    FOR (i, m)
        sort(stations[i].begin(), stations[i].end());
    int last[m];
    FOR (i, m){
        last[i] = (int)stations[i].size() - 1;
        stations[i][last[i]].best = {0, 0};
    }
    while (true){
        int type = -1;
        FOR (i, m)
            if (last[i] > 0 && (type == -1 || stations[type][last[type] - 1] < stations[i][last[i] - 1]))
                type = i;
        if (type == -1)
            break;
        Station &cur = stations[type][last[type] - 1];
        Station c[m];
        FOR (i, m)
            c[i] = stations[i][last[i]];
        if (type == 2){
            if (c[2].x - cur.x <= max_fuel)
                cur.best = c[2].best;
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.second -= cur.x + max_fuel - c[1].x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first -= cur.x + max_fuel - c[0].x;
                    }
                    else
                        break;
                }
            }
        }
        if (type == 1){
            if (c[2].x - cur.x <= max_fuel){
                cur.best = c[2].best;
                cur.best.second += c[2].x - cur.x;
            }
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.second += c[1].x - cur.x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first -= cur.x + max_fuel - c[0].x;
                    }
                    else
                        break;
                }
            }
        }
        if (type == 0){
            if (c[2].x - cur.x <= max_fuel){
                if (c[2].x < c[1].x){
                    cur.best = c[2].best;
                    cur.best.first += c[2].x - cur.x;
                }
                else{
                    cur.best = c[1].best;
                    cur.best.first += c[1].x - cur.x;
                }
            }
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.first += c[1].x - cur.x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first += c[0].x - cur.x;
                    }
                    else
                        break;
                }
            }
        }
        last[type]--;
    }
    FOR (test_i, test_count){
        Station cur(-1);
        cin >> cur.x;
        Station c[m];
        FOR (i, m)
            c[i] = stations[i][Binary_search(cur.x, stations[i])];
        if (c[2].x - cur.x <= max_fuel)
            cur.best = c[2].best;
        else{
            if (c[1].x - cur.x <= max_fuel){
                cur.best = c[1].best;
                cur.best.second -= cur.x + max_fuel - c[1].x;
            }
            else{
                if (c[0].x - cur.x <= max_fuel){
                    cur.best = c[0].best;
                    cur.best.first -= cur.x + max_fuel - c[0].x;
                }
            }
        }
        cout << cur.best.first << ' ' << cur.best.second << endl;
    }
}


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

#define FOR(i, n) for (int i = 0; i < n; i++)

using namespace std;

const int m = 3;

struct Station{
    int x, best[m];

    Station(int x){
        this->x = x;
        FOR (i, m)
            best[i] = -1;
    }

    Station(){}

    const bool operator<(const Station &other)const{
        return x < other.x;
    }
};

int Binary_search(int coord, vector<Station> &stat){
    int min_i = 0, max_i = (int)stat.size() - 1;
    while (min_i < max_i){
        int mid_i = (min_i + max_i) / 2;
        if (coord < stat[mid_i].x)
            max_i = mid_i;
        else
            min_i = mid_i + 1;
    }
    return min_i;
}

int main(){
    cin.tie(NULL);
    cout.tie(NULL);
    ios_base::sync_with_stdio(false);
    int finish, max_fuel, n, test_count;
    cin >> finish >> max_fuel >> n >> test_count;
    vector<Station> stations[m];
    FOR (i, n){
        int a, b;
        cin >> a >> b;
        a--;
        if (b >= finish)
            continue;
        stations[a].push_back(Station(b));
    }
    FOR (i, m)
        stations[i].push_back(finish);
    FOR (i, m)
        sort(stations[i].begin(), stations[i].end());
    int last[m];
    FOR (i, m){
        last[i] = (int)stations[i].size() - 1;
        FOR (j, m)
            stations[i][last[i]].best[j] = 0;
    }
    while (true){
        int type = -1;
        FOR (i, m)
            if (last[i] > 0 && (type == -1 || stations[type][last[type] - 1] < stations[i][last[i] - 1]))
                type = i;
        if (type == -1)
            break;
        Station &cur = stations[type][last[type] - 1];
        for (int i = m - 1; i >= 0; i--){
            Station c = stations[i][last[i]];
            if (max_fuel >= c.x - cur.x){
                FOR (j, m)
                    cur.best[j] = c.best[j];
                cur.best[type] += max_fuel;
                cur.best[i] -= cur.x + max_fuel - c.x;
                break;
            }
        }
        if (cur.best[0] == -1)
            break;
        last[type]--;
    }
    FOR (test_i, test_count){
        int start;
        cin >> start;
        int index[3], ans[] = {-1, -1, -1};
        FOR (i, m)
            index[i] = Binary_search(start, stations[i]);
        for (int i = m - 1; i >= 0; i--){
            Station c = stations[i][index[i]];
            if (max_fuel >= c.x - start){
                if (c.best[0] == -1)
                    break;
                FOR (j, m)
                    ans[j] = c.best[j];
                ans[2] += max_fuel;
                ans[i] -= start + max_fuel - c.x;
                break;
            }
        }
        cout << ans[0] << ' ' << ans[1] << '\n';
    }
}


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

#define FOR(i, n) for (int i = 0; i < n; i++)

using namespace std;

const int m = 3;

struct Station{
    int x;
    pair<int, int> best;

    Station(int x){
        this->x = x;
        best = {-1, -1};
    }

    Station(){}

    const bool operator<(const Station &other)const{
        return x < other.x;
    }
};

int Binary_search(int coord, vector<Station> &stat){
    int min_i = 0, max_i = (int)stat.size() - 1;
    while (min_i < max_i){
        int mid_i = (min_i + max_i) / 2;
        if (coord < stat[mid_i].x)
            max_i = mid_i;
        else
            min_i = mid_i + 1;
    }
    return min_i;
}

int main(){
    cin.tie(NULL);
    cout.tie(NULL);
    ios_base::sync_with_stdio(false);
//    ifstream cin("581 E.in");
    int finish, max_fuel, n, test_count;
    cin >> finish >> max_fuel >> n >> test_count;
    vector<Station> stations[m];
    FOR (i, n){
        int a, b;
        cin >> a >> b;
        a--;
        if (b >= finish)
            continue;
        stations[a].push_back(Station(b));
    }
    FOR (i, m)
        stations[i].push_back(Station(finish));
    FOR (i, m)
        sort(stations[i].begin(), stations[i].end());
    int last[m];
    FOR (i, m){
        last[i] = (int)stations[i].size() - 1;
        stations[i][last[i]].best = {0, 0};
    }
    while (true){
        int type = -1;
        FOR (i, m)
            if (last[i] > 0 && (type == -1 || stations[type][last[type] - 1] < stations[i][last[i] - 1]))
                type = i;
        if (type == -1)
            break;
        Station &cur = stations[type][last[type] - 1];
        Station c[m];
        FOR (i, m)
            c[i] = stations[i][last[i]];
        if (type == 2){
            if (c[2].x - cur.x <= max_fuel)
                cur.best = c[2].best;
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.second -= cur.x + max_fuel - c[1].x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first -= cur.x + max_fuel - c[0].x;
                    }
                    else
                        break;
                }
            }
        }
        if (type == 1){
            if (c[2].x - cur.x <= max_fuel){
                cur.best = c[2].best;
                cur.best.second += c[2].x - cur.x;
            }
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.second += c[1].x - cur.x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first -= cur.x + max_fuel - c[0].x;
                    }
                    else
                        break;
                }
            }
        }
        if (type == 0){
            if (c[2].x - cur.x <= max_fuel){
                if (c[2].x < c[1].x){
                    cur.best = c[2].best;
                    cur.best.first += c[2].x - cur.x;
                }
                else{
                    cur.best = c[1].best;
                    cur.best.first += c[1].x - cur.x;
                }
            }
            else{
                if (c[1].x - cur.x <= max_fuel){
                    cur.best = c[1].best;
                    cur.best.first += c[1].x - cur.x;
                }
                else{
                    if (c[0].x - cur.x <= max_fuel){
                        cur.best = c[0].best;
                        cur.best.first += c[0].x - cur.x;
                    }
                    else
                        break;
                }
            }
        }
        last[type]--;
    }
    FOR (test_i, test_count){
        Station cur(-1);
        cin >> cur.x;
        Station c[m];
        FOR (i, m)
            c[i] = stations[i][Binary_search(cur.x, stations[i])];
        if (c[2].x - cur.x <= max_fuel)
            cur.best = c[2].best;
        else{
            if (c[1].x - cur.x <= max_fuel){
                cur.best = c[1].best;
                cur.best.second -= cur.x + max_fuel - c[1].x;
            }
            else{
                if (c[0].x - cur.x <= max_fuel){
                    cur.best = c[0].best;
                    cur.best.first -= cur.x + max_fuel - c[0].x;
                }
            }
        }
        cout << cur.best.first << ' ' << cur.best.second << endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int E,S,N,M;
set<int> POS;
map<int,int> G;
map<int,vector<int> > C;
map<int,pair<ll,ll> > gas;
map<int,ll > need;
pair<ll,ll> ret[202000];
vector<int> P[4];

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>E>>S>>N>>M;
	FOR(i,N) {
		cin>>r>>x;
		if(x>=E) continue;
		G[E-x] = max(G[E-x],r);
		POS.insert(E-x);
	}

	G[0]=3;
	P[1].push_back(0);
	P[2].push_back(0);
	FORR(r,G) P[r.second].push_back(r.first);
	gas[0]={0,0};
	need[0]=0;

	FOR(i,M) {
		cin>>x;
		C[E-x].push_back(i);
		POS.insert(E-x);
	}

	vector<int>::iterator pre[4],last[4];
	for(i=1;i<=3;i++) pre[i]=last[i]=P[i].begin();

	FORR(r,POS) {
		for(i=1;i<=3;i++) while(pre[i]!=P[i].end() && r-*pre[i]>S) pre[i]++;

		int t = G[r];
		if(t) {
			gas[r]={1LL<<40,1LL<<40};

			if(t==3) {
				need[r]=0;
				if(last[3]!=P[3].end() && r-*last[3]<=S) {
					gas[r] = gas[*last[3]];
				}
				else if(pre[2]!=P[2].end() && *pre[2]<r) {
					int left=S-(r-*pre[2]);
					gas[r] = {gas[*pre[2]].first,gas[*pre[2]].second + max(0LL,need[*pre[2]]-left)};
				}
				else if(pre[1]!=P[1].end() && *pre[1]<r) {
					int left=S-(r-*pre[1]);
					gas[r] = {gas[*pre[1]].first + max(0LL,need[*pre[1]]-left) ,gas[*pre[1]].second };
				}
			}
			else if(t==2) {
				if(last[3]!=P[3].end() && r-*last[3]<=S) {
					gas[r] = gas[*last[3]];
					need[r]= r-*last[3];
				}
				else if(last[2]!=P[2].end() && r-*last[2]<=S) {
					gas[r] = gas[*last[2]];
					gas[r].second += need[*last[2]];
					need[r]= r-*last[2];
				}
				else if(pre[1]!=P[1].end() && *pre[1]<r) {
					int left=S-(r-*pre[1]);
					gas[r] = {gas[*pre[1]].first + max(0LL,need[*pre[1]]-left) ,gas[*pre[1]].second };
					need[r]= S;
				}
			}
			else if(t==1) {
				int mi=4;
				for(i=3;i>=1;i--) if(last[i]!=P[i].end() && (mi==4 || *last[i]>*last[mi]) && r-*last[i]<=S) mi=i;
				if(mi!=4) {
					gas[r] = gas[*last[mi]];
					if(mi==1) gas[r].first += need[*last[mi]];
					if(mi==2) gas[r].second += need[*last[mi]];
					need[r]= r-*last[mi];
				}

			}
			last[t]++;
		}

		if(C.count(r)) {
			pair<ll,ll> tret={1LL<<40,1LL<<40};
			if(last[3]!=P[3].end() && r-*last[3]<=S) {
				tret = gas[*last[3]];
			}
			else if(pre[2]!=P[2].end() && *pre[2]<r) {
				int left=S-(r-*pre[2]);
				tret = {gas[*pre[2]].first,gas[*pre[2]].second + max(0LL,need[*pre[2]]-left)};
			}
			else if(pre[1]!=P[1].end() && *pre[1]<r) {
				int left=S-(r-*pre[1]);
				tret = {gas[*pre[1]].first + max(0LL,need[*pre[1]]-left) ,gas[*pre[1]].second };
			}
			if(tret.first>=1LL<<40) tret.first=tret.second=-1;
			FORR(r2,C[r]) ret[r2]=tret;
		}
	}

	FOR(i,M) _P("%d %d\n",(int)ret[i].first,(int)ret[i].second);
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false);
	FOR(i,argc-1) s+=argv[i+1],s+='\n';
	FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int E,S,N,M;
set<int> POS;
map<int,int> G;
map<int,vector<int> > C;
map<int,pair<ll,ll> > gas;
map<int,ll > need;
pair<ll,ll> ret[202000];
vector<int> P[4];

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>E>>S>>N>>M;
	FOR(i,N) {
		cin>>r>>x;
		if(x>=E) continue;
		G[E-x] = max(G[E-x],r);
		POS.insert(E-x);
	}

	G[0]=3;
	P[1].push_back(0);
	P[2].push_back(0);
	FORR(r,G) P[r.second].push_back(r.first);
	gas[0]={0,0};
	need[0]=0;

	FOR(i,M) {
		cin>>x;
		C[E-x].push_back(i);
		POS.insert(E-x);
	}

	vector<int>::iterator pre[4],last[4];
	for(i=1;i<=3;i++) pre[i]=last[i]=P[i].begin();

	FORR(r,POS) {
		for(i=1;i<=3;i++) while(pre[i]!=P[i].end() && r-*pre[i]>S) pre[i]++;

		int t = G[r];
		if(t) {
			gas[r]={1LL<<40,1LL<<40};

			if(t==3) {
				need[r]=0;
				if(last[3]!=P[3].end() && r-*last[3]<=S) {
					gas[r] = gas[*last[3]];
				}
				else if(pre[2]!=P[2].end() && *pre[2]<r) {
					int left=S-(r-*pre[2]);
					//gas[r] = {gas[*pre[2]].first,gas[*pre[2]].second + max(0LL,need[*pre[2]]-left)};
					gas[r] = {gas[*pre[2]].first,gas[*pre[2]].second + (need[*pre[2]]-left)};
				}
				else if(pre[1]!=P[1].end() && *pre[1]<r) {
					int left=S-(r-*pre[1]);
					//gas[r] = {gas[*pre[1]].first + max(0LL,need[*pre[1]]-left) ,gas[*pre[1]].second };
					gas[r] = {gas[*pre[1]].first + need[*pre[1]]-left ,gas[*pre[1]].second };
				}
			}
			else if(t==2) {
				if(last[3]!=P[3].end() && r-*last[3]<=S) {
					gas[r] = gas[*last[3]];
					need[r]= r-*last[3];
				}
				else if(last[2]!=P[2].end() && r-*last[2]<=S) {
					gas[r] = gas[*last[2]];
					gas[r].second += need[*last[2]];
					need[r]= r-*last[2];
				}
				else if(pre[1]!=P[1].end() && *pre[1]<r) {
					int left=S-(r-*pre[1]);
					gas[r] = {gas[*pre[1]].first + max(0LL,need[*pre[1]]-left) ,gas[*pre[1]].second };
					need[r]= S;
				}
			}
			else if(t==1) {
				int mi=4;
				for(i=3;i>=1;i--) if(last[i]!=P[i].end() && (mi==4 || *last[i]>*last[mi]) && r-*last[i]<=S) mi=i;
				if(mi!=4) {
					gas[r] = gas[*last[mi]];
					if(mi==1) gas[r].first += need[*last[mi]];
					if(mi==2) gas[r].second += need[*last[mi]];
					need[r]= r-*last[mi];
				}

			}
			last[t]++;
		}

		if(C.count(r)) {
			pair<ll,ll> tret={1LL<<40,1LL<<40};
			if(last[3]!=P[3].end() && r-*last[3]<=S) {
				tret = gas[*last[3]];
			}
			else if(pre[2]!=P[2].end() && *pre[2]<r) {
				int left=S-(r-*pre[2]);
				tret = {gas[*pre[2]].first,gas[*pre[2]].second + max(0LL,need[*pre[2]]-left)};
			}
			else if(pre[1]!=P[1].end() && *pre[1]<r) {
				int left=S-(r-*pre[1]);
				tret = {gas[*pre[1]].first + max(0LL,need[*pre[1]]-left) ,gas[*pre[1]].second };
			}
			if(tret.first>=1LL<<40) tret.first=tret.second=-1;
			FORR(r2,C[r]) ret[r2]=tret;
		}
	}

	FOR(i,M) _P("%d %d\n",(int)ret[i].first,(int)ret[i].second);
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false);
	FOR(i,argc-1) s+=argv[i+1],s+='\n';
	FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int E,S,N,M;
set<int> POS;
map<int,int> G,P2I;
map<int,vector<int> > C;
map<int,pair<ll,ll> > gas;
map<int,ll > need;
pair<ll,ll> ret[202000];
vector<int> P[4];
int pre[4],cur[4];

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>E>>S>>N>>M;
	FOR(i,N) {
		cin>>r>>x;
		if(x>=E) continue;
		G[E-x] = max(G[E-x],r);
		POS.insert(E-x);
	}

	G[0]=3;
	P[1].push_back(0);
	P[2].push_back(0);
	FORR(r,G) {
		P2I[r.second]=P[r.second].size();
		P[r.second].push_back(r.first);
	}
	gas[0]={0,0};
	need[0]=0;

	FOR(i,M) {
		cin>>x;
		C[E-x].push_back(i);
		POS.insert(E-x);
		ret[i]={1LL<<40,1LL<<40};
	}

	FORR(r,POS) {
		for(i=1;i<=3;i++) {
			while(pre[i]<P[i].size() && r-P[i][pre[i]]>S) pre[i]++;
		}

		int t = G[r];
		if(t) {
			int prev[4];
			for(i=1;i<=3;i++) {
				prev[i]=(t>=i)?cur[i]:pre[i];
				if(prev[i]>=P[i].size() || r-P[i][prev[i]]>S) prev[i]=-1;
			}
			cur[t]++;
			gas[r]={1LL<<40,1LL<<40};

			if(t==3) {
				need[r]=0;
				if(prev[3]!=-1) {
					gas[r] = gas[P[3][prev[3]]];
				}
				else if(pre[2]<P[2].size() && P[2][pre[2]]<r) {
					int left=S-(r-P[2][pre[2]]);
					gas[r] = {gas[P[2][pre[2]]].first,gas[P[2][pre[2]]].second + max(0LL,need[P[2][pre[2]]]-left)};
				}
				else if(pre[1]<P[1].size() && P[1][pre[1]]<r) {
					int left=S-(r-P[1][pre[1]]);
					gas[r] = {gas[P[1][pre[1]]].first + max(0LL,need[P[1][pre[1]]]-left) ,gas[P[1][pre[1]]].second };
				}
			}
			else if(t==2) {
				if(prev[3]!=-1) {
					gas[r] = gas[P[3][prev[3]]];
					need[r]= r-P[3][prev[3]];
				}
				else if(prev[2]!=-1) {
					gas[r] = gas[P[2][prev[2]]];
					need[r]= r-P[2][prev[2]];
				}
				else if(pre[1]<P[1].size() && P[1][pre[1]]<r) {
					int left=S-(r-P[1][pre[1]]);
					gas[r] = {gas[P[1][pre[1]]].first + max(0LL,need[P[1][pre[1]]]-left) ,gas[P[1][pre[1]]].second};
					need[r]= r-P[1][prev[1]];
				}
			}
			else if(t==1) {
				for(i=3;i>=1;i--) if(prev[i]!=-1) {
					gas[r] = gas[P[i][prev[i]]];
					need[r]= r-P[i][prev[i]];
					break;
				}
			}
		}

		if(C.count(r)) {
			t=3;
			int prev[4];
			for(i=1;i<=3;i++) {
				prev[i]=(t>=i)?cur[i]:pre[i];
				if(prev[i]>=P[i].size() || r-P[i][prev[i]]>S) prev[i]=-1;
			}
			cur[t]++;
			pair<ll,ll> tret={1LL<<40,1LL<<40};
			if(prev[3]!=-1) {
				tret = gas[P[3][prev[3]]];
			}
			else if(pre[2]<P[2].size() && P[2][pre[2]]<r) {
				int left=S-(r-P[2][pre[2]]);
				tret = {gas[P[2][pre[2]]].first,gas[P[2][pre[2]]].second + max(0LL,need[P[2][pre[2]]]-left)};
			}
			else if(pre[1]<P[1].size() && P[1][pre[1]]<r) {
				int left=S-(r-P[1][pre[1]]);
				tret = {gas[P[1][pre[1]]].first + max(0LL,need[P[1][pre[1]]]-left) ,gas[P[1][pre[1]]].second };
			}
			FORR(r2,C[r]) ret[r2]=tret;
		}
	}

	FOR(i,M) {
		if(ret[i].first>=1LL<<40) ret[i].first=ret[i].second=-1;
		_P("%d %d\n",(int)ret[i].first,(int)ret[i].second);
	}
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false);
	FOR(i,argc-1) s+=argv[i+1],s+='\n';
	FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	solve(); return 0;
}


// SNIPPET read
pub trait Readable {
    type Output;
    fn words_count() -> usize;
    fn read_words(words: &[&str]) -> Result<Self::Output, String>;
}
#[macro_export]
macro_rules! readable {
    ( $t:ty, $words_count:expr, |$words:ident| $read_words:expr ) => {
        impl Readable for $t {
            type Output = $t;
            fn words_count() -> usize { $words_count }
            fn read_words($words: &[&str]) -> Result<$t, String> {
                Ok($read_words)
            }
        }
    };
}
readable!((), 1, |_ss| ());
readable!(String, 1, |ss| ss[0].to_string());
impl Readable for char {
    type Output = char;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<char, String> {
        let chars: Vec<char> = words[0].chars().collect();
        if chars.len() == 1 {
            Ok(chars[0])
        } else {
            Err(format!("cannot parse `{}` as a char", words[0]))
        }
    }
}
pub struct Chars();
impl Readable for Chars {
    type Output = Vec<char>;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Vec<char>, String> {
        Ok(words[0].chars().collect())
    }
}
impl Readable for i8 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<i8, String> {
        use std::str::FromStr;
        i8::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as i8", words[0])
        })
    }
}
impl Readable for u8 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<u8, String> {
        use std::str::FromStr;
        u8::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as u8", words[0])
        })
    }
}
impl Readable for i16 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<i16, String> {
        use std::str::FromStr;
        i16::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as i16", words[0])
        })
    }
}
impl Readable for u16 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<u16, String> {
        use std::str::FromStr;
        u16::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as u16", words[0])
        })
    }
}
impl Readable for i32 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<i32, String> {
        use std::str::FromStr;
        i32::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as i32", words[0])
        })
    }
}
impl Readable for u32 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<u32, String> {
        use std::str::FromStr;
        u32::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as u32", words[0])
        })
    }
}
impl Readable for i64 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<i64, String> {
        use std::str::FromStr;
        i64::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as i64", words[0])
        })
    }
}
impl Readable for u64 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<u64, String> {
        use std::str::FromStr;
        u64::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as u64", words[0])
        })
    }
}
impl Readable for isize {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<isize, String> {
        use std::str::FromStr;
        <isize>::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as isize", words[0])
        })
    }
}
impl Readable for usize {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<usize, String> {
        use std::str::FromStr;
        <usize>::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as usize", words[0])
        })
    }
}
impl Readable for f32 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<f32, String> {
        use std::str::FromStr;
        f32::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as f32", words[0])
        })
    }
}
impl Readable for f64 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<f64, String> {
        use std::str::FromStr;
        f64::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as f64", words[0])
        })
    }
}
#[allow(non_camel_case_types)]
pub struct u8_;
impl Readable for u8_ {
    type Output = u8;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        u8::read_words(words).map(|n| n-1)
    }
}
#[allow(non_camel_case_types)]
pub struct u16_;
impl Readable for u16_ {
    type Output = u16;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        u16::read_words(words).map(|n| n-1)
    }
}
#[allow(non_camel_case_types)]
pub struct u32_;
impl Readable for u32_ {
    type Output = u32;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        u32::read_words(words).map(|n| n-1)
    }
}
#[allow(non_camel_case_types)]
pub struct u64_;
impl Readable for u64_ {
    type Output = u64;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        u64::read_words(words).map(|n| n-1)
    }
}
#[allow(non_camel_case_types)]
pub struct usize_;
impl Readable for usize_ {
    type Output = usize;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        <usize>::read_words(words).map(|n| n-1)
    }
}
impl<T1: Readable, T2: Readable> Readable for (T1, T2) {
    type Output = (T1::Output, T2::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let val2 = T2::read_words(&words[start..])?;
        Ok((val1, val2))
    }
}
impl<T1: Readable, T2: Readable, T3: Readable> Readable for (T1, T2, T3) {
    type Output = (T1::Output, T2::Output, T3::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count() + T3::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let count2 = T2::words_count();
        let val2 = T2::read_words(&words[start .. start+count2])?;
        start += count2;
        let val3 = T3::read_words(&words[start..])?;
        Ok((val1, val2, val3))
    }
}
impl<T1: Readable, T2: Readable, T3: Readable, T4: Readable> Readable for (T1, T2, T3, T4) {
    type Output = (T1::Output, T2::Output, T3::Output, T4::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count() + T3::words_count() + T4::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let count2 = T2::words_count();
        let val2 = T2::read_words(&words[start .. start+count2])?;
        start += count2;
        let count3 = T3::words_count();
        let val3 = T3::read_words(&words[start .. start+count3])?;
        start += count3;
        let val4 = T4::read_words(&words[start..])?;
        Ok((val1, val2, val3, val4))
    }
}
impl<T1: Readable, T2: Readable, T3: Readable, T4: Readable, T5: Readable> Readable for (T1, T2, T3, T4, T5) {
    type Output = (T1::Output, T2::Output, T3::Output, T4::Output, T5::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count() + T3::words_count() + T4::words_count() + T5::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let count2 = T2::words_count();
        let val2 = T2::read_words(&words[start .. start+count2])?;
        start += count2;
        let count3 = T3::words_count();
        let val3 = T3::read_words(&words[start .. start+count3])?;
        start += count3;
        let count4 = T4::words_count();
        let val4 = T4::read_words(&words[start .. start+count4])?;
        start += count4;
        let val5 = T5::read_words(&words[start..])?;
        Ok((val1, val2, val3, val4, val5))
    }
}
impl<T1: Readable, T2: Readable, T3: Readable, T4: Readable, T5: Readable, T6: Readable> Readable for (T1, T2, T3, T4, T5, T6) {
    type Output = (T1::Output, T2::Output, T3::Output, T4::Output, T5::Output, T6::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count() + T3::words_count() + T4::words_count() + T5::words_count() + T6::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let count2 = T2::words_count();
        let val2 = T2::read_words(&words[start .. start+count2])?;
        start += count2;
        let count3 = T3::words_count();
        let val3 = T3::read_words(&words[start .. start+count3])?;
        start += count3;
        let count4 = T4::words_count();
        let val4 = T4::read_words(&words[start .. start+count4])?;
        start += count4;
        let count5 = T5::words_count();
        let val5 = T5::read_words(&words[start .. start+count5])?;
        start += count5;
        let val6 = T6::read_words(&words[start..])?;
        Ok((val1, val2, val3, val4, val5, val6))
    }
}
pub trait ReadableFromLine {
    type Output;
    fn read_line(line: &str) -> Result<Self::Output, String>;
}
fn split_into_words(line: &str) -> Vec<&str> {
    line.trim_end_matches('\n').split_whitespace().collect()
}
impl<T: Readable> ReadableFromLine for T {
    type Output = T::Output;
    fn read_line(line: &str) -> Result<T::Output, String> {
        let words = split_into_words(line);
        if words.len() != T::words_count() {
            return Err(format!("line `{}` has {} words, expected {}",
                               line, words.len(), T::words_count()));
        }
        T::read_words(&words)
    }
}
pub fn read_words_into_vec<T: Readable>(words: &[&str], line: &str) -> Result<Vec<T::Output>, String> {
    let n = T::words_count();
    assert_eq!(words.len() % n, 0);
    let mut result = Vec::new();
    for chunk in words.chunks(n) {
        match T::read_words(chunk) {
            Ok(v) => result.push(v),
            Err(msg) => {
                let fragment_msg = if n == 1 {
                    format!("word {}", result.len())
                } else {
                    let l = result.len();
                    format!("words {}-{}", n*l + 1, (n+1) * l)
                };
                return Err(format!(
                    "{} of line `{}`: {}", fragment_msg, line, msg
                ));
            }
        }
    }
    Ok(result)
}
pub fn split_into_words_for_collection<T: Readable>(
    line: &str, prefix_words_count: usize
) -> Result<Vec<&str>, String> {
    let n = T::words_count();
    let words = split_into_words(line);
    if words.len() < prefix_words_count {
        return Err(
            format!("line `{}` has {} words, expected at least {}",
                    line, words.len(), prefix_words_count)
        );
    }
    if (words.len() - prefix_words_count) % T::words_count() != 0 {
        return Err(
            format!("line `{}` has {} words, expected {} + {}",
                    line, words.len(), prefix_words_count, n)
        );
    }
    Ok(words)
}
#[macro_export]
macro_rules! readable_collection {
    ($u:ident => $collection_in:ty, $collection_out:ty) => {
        readable_collection!($u: => $collection_in, $collection_out);
    };
    ($u:ident : $( $bound:path ),* => $collection_in:ty, $collection_out:ty) => {
        impl<$u: Readable> ReadableFromLine for $collection_in
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = $collection_out;
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let words = split_into_words_for_collection::<$u>(line, 0)?;
                Ok(read_words_into_vec::<$u>(&words, line)?.into_iter().collect())
            }
        }
        impl<T1: Readable, $u: Readable> ReadableFromLine for (T1, $collection_in)
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = (T1::Output, $collection_out);
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let prefix_len = T1::words_count();
                let words = split_into_words_for_collection::<$u>(line, prefix_len)?;
                let val1 = T1::read_words(&words[..prefix_len])?;
                let rest = read_words_into_vec::<$u>(&words[prefix_len..], line)?;
                Ok((val1, rest.into_iter().collect()))
            }
        }
        impl<T1: Readable, T2: Readable, $u: Readable> ReadableFromLine for (T1, T2, $collection_in)
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = (T1::Output, T2::Output, $collection_out);
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let prefix_len = <(T1, T2)>::words_count();
                let words = split_into_words_for_collection::<$u>(line, prefix_len)?;
                let mut start = 0;
                let count1 = T1::words_count();
                let val1 = T1::read_words(&words[start .. start+count1])?;
                start += count1;
                let count2 = T2::words_count();
                let val2 = T2::read_words(&words[start .. start+count2])?;
                let rest = read_words_into_vec::<$u>(&words[prefix_len..], line)?;
                Ok((val1, val2, rest.into_iter().collect()))
            }
        }
        impl<T1: Readable, T2: Readable, T3: Readable, $u: Readable> ReadableFromLine for (T1, T2, T3, $collection_in)
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = (T1::Output, T2::Output, T3::Output, $collection_out);
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let prefix_len = <(T1, T2, T3)>::words_count();
                let words = split_into_words_for_collection::<$u>(line, prefix_len)?;
                let mut start = 0;
                let count1 = T1::words_count();
                let val1 = T1::read_words(&words[start .. start+count1])?;
                start += count1;
                let count2 = T2::words_count();
                let val2 = T2::read_words(&words[start .. start+count2])?;
                start += count2;
                let count3 = T3::words_count();
                let val3 = T3::read_words(&words[start .. start+count3])?;
                let rest = read_words_into_vec::<$u>(&words[prefix_len..], line)?;
                Ok((val1, val2, val3, rest.into_iter().collect()))
            }
        }
        impl<T1: Readable, T2: Readable, T3: Readable, T4: Readable, $u: Readable> ReadableFromLine for (T1, T2, T3, T4, $collection_in)
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = (T1::Output, T2::Output, T3::Output, T4::Output, $collection_out);
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let prefix_len = <(T1, T2, T3, T4)>::words_count();
                let words = split_into_words_for_collection::<$u>(line, prefix_len)?;
                let mut start = 0;
                let count1 = T1::words_count();
                let val1 = T1::read_words(&words[start .. start+count1])?;
                start += count1;
                let count2 = T2::words_count();
                let val2 = T2::read_words(&words[start .. start+count2])?;
                start += count2;
                let count3 = T3::words_count();
                let val3 = T3::read_words(&words[start .. start+count3])?;
                start += count3;
                let count4 = T4::words_count();
                let val4 = T4::read_words(&words[start .. start+count4])?;
                let rest = read_words_into_vec::<$u>(&words[prefix_len..], line)?;
                Ok((val1, val2, val3, val4, rest.into_iter().collect()))
            }
        }
    };
}
readable_collection!(U => Vec<U>, Vec<U::Output>);
pub fn read<T: ReadableFromLine>() -> T::Output {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    T::read_line(&line).unwrap()
}
#[macro_export]
macro_rules! read {
    () => {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
    };
    ( $pat:pat = $t:ty $(,)* ) => {
        let $pat = read::<$t>();
    };
    ( ! $(,)* ) => {
        let _ = read::<()>();
    };
    ( $pat:pat = $t:ty, $( $rest:tt )+ ) => {
        read_inner!($pat = $t; $($rest)+);
    };
    ( !, $( $rest:tt )+ ) => {
        read_inner!(_ = (); $($rest)+);
    };
}
#[macro_export]
#[doc(hidden)]
macro_rules! read_inner {
    ( $( $acc_pat:pat = $acc_t:ty ),+ ; $pat:pat = $t:ty, $( $rest:tt )* ) => {
        read_inner!($( $acc_pat = $acc_t ),+ , $pat = $t ; $($rest)*);
    };
    ( $( $acc_pat:pat = $acc_t:ty ),+ ; !, $( $rest:tt )* ) => {
        read_inner!($( $acc_pat = $acc_t ),+ , _ = () ; $($rest)*);
    };
    ( $( $acc_pat:pat = $acc_t:ty ),+ ; $pat:pat = $t:ty ) => {
        read_inner!($( $acc_pat = $acc_t ),+ , $pat = $t ;);
    };
    ( $( $acc_pat:pat = $acc_t:ty ),+ ; ! ) => {
        read_inner!($( $acc_pat = $acc_t ),+ , _ = () ;);
    };
    ( $( $pat:pat = $t:ty ),+ ; ) => {
        let ($($pat),+) = read::<($($t),+)>();
    };
}
pub trait ReadableFromChunk {
    type Output;
    fn lines_count() -> usize;
    fn read_chunk(lines: &[String]) -> Result<Self::Output, String>;
}
impl<T1: ReadableFromLine, T2: ReadableFromLine> ReadableFromChunk for (T1, T2) {
    type Output = (T1::Output, T2::Output);
    fn lines_count() -> usize { 2 }
    fn read_chunk(lines: &[String]) -> Result<Self::Output, String> {
        let out1 = T1::read_line(&lines[0])?;
        let out2 = T2::read_line(&lines[1])?;
        Ok((out1, out2))
    }
}
impl<T1: ReadableFromLine, T2: ReadableFromLine, T3: ReadableFromLine> ReadableFromChunk for (T1, T2, T3) {
    type Output = (T1::Output, T2::Output, T3::Output);
    fn lines_count() -> usize { 3 }
    fn read_chunk(lines: &[String]) -> Result<Self::Output, String> {
        let out1 = T1::read_line(&lines[0])?;
        let out2 = T2::read_line(&lines[1])?;
        let out3 = T3::read_line(&lines[2])?;
        Ok((out1, out2, out3))
    }
}
impl<T1: ReadableFromLine, T2: ReadableFromLine, T3: ReadableFromLine, T4: ReadableFromLine> ReadableFromChunk for (T1, T2, T3, T4) {
    type Output = (T1::Output, T2::Output, T3::Output, T4::Output);
    fn lines_count() -> usize { 4 }
    fn read_chunk(lines: &[String]) -> Result<Self::Output, String> {
        let out1 = T1::read_line(&lines[0])?;
        let out2 = T2::read_line(&lines[1])?;
        let out3 = T3::read_line(&lines[2])?;
        let out4 = T4::read_line(&lines[3])?;
        Ok((out1, out2, out3, out4))
    }
}
pub fn read_chunk<T: ReadableFromChunk>() -> T::Output {
    let stdin = std::io::stdin();
    let mut handle = stdin.lock();
    read_chunk_from_handle::<T>(&mut handle).unwrap()
}
fn read_chunk_from_handle<T: ReadableFromChunk>(handle: &mut std::io::StdinLock) -> Option<T::Output> {
    use std::io::BufRead;
    let mut lines = vec![String::new(); T::lines_count()];
    let mut first = true;
    for line in &mut lines {
        if handle.read_line(line).unwrap() == 0 && first {
            return None;
        }
        first = false;
    }
    Some(T::read_chunk(&lines).unwrap())
}
#[macro_export]
macro_rules! read_chunk {
    ( $( $pat:pat = $t:ty ),+ ) => {
        let ($($pat),+) = read_chunk::<($($t),+)>();
    };
}
static mut STDIN: Option<std::io::Stdin> = None;
pub struct ReadLines<T: ReadableFromLine> {
    lock: std::io::StdinLock<'static>,
    phantom: std::marker::PhantomData<T>
}
impl<T: ReadableFromLine> Iterator for ReadLines<T> {
    type Item = T::Output;
    fn next(&mut self) -> Option<T::Output> {
        use std::io::BufRead;
        let mut line = String::new();
        if self.lock.read_line(&mut line).unwrap() > 0 {
            Some(T::read_line(&line).unwrap())
        } else {
            None
        }
    }
}
pub fn read_lines<T: ReadableFromLine>() -> ReadLines<T> {
    unsafe {
        if STDIN.is_none() {
            STDIN = Some(std::io::stdin());
        }
    }
    ReadLines {
        lock: unsafe { STDIN.as_ref().unwrap().lock() },
        phantom: std::marker::PhantomData::<T>
    }
}
pub struct ReadChunks<T: ReadableFromChunk> {
    lock: std::io::StdinLock<'static>,
    phantom: std::marker::PhantomData<T>
}
impl<T: ReadableFromChunk> Iterator for ReadChunks<T> {
    type Item = T::Output;
    fn next(&mut self) -> Option<T::Output> {
        read_chunk_from_handle::<T>(&mut self.lock)
    }
}
pub fn read_chunks<T: ReadableFromChunk>() -> ReadChunks<T> {
    unsafe {
        if STDIN.is_none() {
            STDIN = Some(std::io::stdin());
        }
    }
    ReadChunks {
        lock: unsafe { STDIN.as_ref().unwrap().lock() },
        phantom: std::marker::PhantomData::<T>
    }
}
pub trait Words {
    fn read<T: Readable>(&self) -> T::Output;
}
impl<'a> Words for [&'a str] {
    fn read<T: Readable>(&self) -> T::Output {
        T::read_words(self).unwrap()
    }
}
impl<'a> Words for &'a str {
    fn read<T: Readable>(&self) -> T::Output {
        T::read_words(&[self]).unwrap()
    }
}

// SNIPPET utils
pub fn yn(result: bool) {
    if result {
        println!("Yes");
    } else {
        println!("No");
    }
}
#[allow(non_snake_case)]
pub fn YN(result: bool) {
    if result {
        println!("YES");
    } else {
        println!("NO");
    }
}
pub fn exit(msg: impl std::fmt::Display) -> ! {
    println!("{}", msg);
    std::process::exit(0)
}
#[macro_export]
#[cfg(local)]
macro_rules! dbg {
    () => {
        {
            use std::io::{self, Write};
            writeln!(io::stderr(), "{}: dbg", line!()).unwrap();
        }
    };
    ($e: expr) => {
        {
            use std::io::{self, Write};
            let result = $e;
            writeln!(io::stderr(), "{}: {} = {:?}",
                     line!(), stringify!($e), result)
                .unwrap();
            result
        }
    }
}
#[macro_export]
#[cfg(not(local))]
macro_rules! dbg {
    () => {};
    ($e: expr) => {
        { $e }
    }
}

// SNIPPET option
pub trait BoolExt {
    fn then<T>(self, value: T) -> Option<T>;
    fn then_with<T, F>(self, f: F) -> Option<T> where F: FnOnce() -> T;
    fn and<T>(self, option: Option<T>) -> Option<T>;
    fn and_then<T, F>(self, f: F) -> Option<T> where F: FnOnce() -> Option<T>;
}
impl BoolExt for bool {
    fn then<T>(self, value: T) -> Option<T> {
        if self { Some(value) } else { None }
    }
    fn then_with<T, F>(self, f: F) -> Option<T> where F: FnOnce() -> T {
        if self { Some(f()) } else { None }
    }
    fn and<T>(self, option: Option<T>) -> Option<T> {
        if self { option } else { None }
    }
    fn and_then<T, F>(self, f: F) -> Option<T> where F: FnOnce() -> Option<T> {
        if self { f() } else { None }
    }
}
pub trait OptionExt<T> {
    fn to_string_or<U: std::fmt::Display>(&self, default: U) -> String
    where
        T: std::fmt::Display;
}
impl<T> OptionExt<T> for Option<T> {
    fn to_string_or<U: std::fmt::Display>(&self, default: U) -> String
    where
        T: std::fmt::Display
    {
        self.as_ref().map(|x| x.to_string()).unwrap_or(default.to_string())
    }
    /*
    fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
        match *self {
            None => *self = Some(f()),
            _ => ()
        }
        self.as_mut().unwrap()
    }
    */
}
pub trait Guard: Sized {
    fn guard(self, pred: impl FnOnce(&Self) -> bool) -> Option<Self>;
}
impl<T> Guard for T {
    fn guard(self, pred: impl FnOnce(&T) -> bool) -> Option<T> {
        if pred(&self) { Some(self) } else { None }
    }
}

// SNIPPET range
pub trait UsizeRangeBoundsExt {
    fn to_range(&self, len: usize) -> Option<std::ops::Range<usize>>;
}
impl<T: std::ops::RangeBounds<usize>> UsizeRangeBoundsExt for T {
    #[allow(unstable_name_collisions)]
    fn to_range(&self, len: usize) -> Option<std::ops::Range<usize>> {
        use std::ops::Bound::*;
        let start = match self.start_bound() {
            Included(&i) => i,
            Excluded(&i) => i+1,
            Unbounded => 0
        };
        let end = match self.end_bound() {
            Included(&i) => i+1,
            Excluded(&i) => i,
            Unbounded => len,
        };
        (start <= end && end <= len).then(start..end)
    }
}
pub trait BoundCloned<T> {
    fn cloned(self) -> std::ops::Bound<T>;
}
impl<T: Clone> BoundCloned<T> for std::ops::Bound<&T> {
    fn cloned(self) -> std::ops::Bound<T> {
        match self {
            std::ops::Bound::Included(x) => std::ops::Bound::Included(x.clone()),
            std::ops::Bound::Excluded(x) => std::ops::Bound::Excluded(x.clone()),
            std::ops::Bound::Unbounded => std::ops::Bound::Unbounded
        }
    }
}
pub trait BoundExt<T> {
    fn map<U>(self, f: impl FnOnce(T) -> U) -> std::ops::Bound<U>;
}
impl<T> BoundExt<T> for std::ops::Bound<T> {
    fn map<U>(self, f: impl FnOnce(T) -> U) -> std::ops::Bound<U> {
        match self {
            std::ops::Bound::Included(x) => std::ops::Bound::Included(f(x)),
            std::ops::Bound::Excluded(x) => std::ops::Bound::Excluded(f(x)),
            std::ops::Bound::Unbounded => std::ops::Bound::Unbounded
        }
    }
}

// SNIPPET table
pub struct Table<T> {
    inner: Vec<Vec<T>>
}
pub struct TableIndicesIterator {
    height: usize,
    width: usize,
    y: usize,
    x: usize
}
impl Iterator for TableIndicesIterator {
    type Item = (usize, usize);
    fn next(&mut self) -> Option<(usize, usize)> {
        if self.x < self.width {
            self.x += 1;
            return Some((self.y, self.x-1))
        }
        if self.y+1 < self.height {
            self.y += 1;
            self.x = 1;
            return Some((self.y, 0))
        }
        None
    }
}
pub struct TableRows<'a, T> {
    table: &'a Table<T>,
    index: usize
}
impl<'a, T> Iterator for TableRows<'a, T> {
    type Item = &'a [T];
    fn next(&mut self) -> Option<&'a [T]> {
        if self.index < self.table.height() {
            let i = self.index;
            self.index += 1;
            Some(&self.table.inner[i])
        } else {
            None
        }
    }
}
pub trait TableRangeBounds {
    fn y_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>);
    fn x_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>);
}
/*
impl<T1: std::ops::RangeBounds<usize>, T2: std::ops::RangeBounds<usize>> TableRangeBounds for (T1, T2) {
    fn y_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>) {
        (self.0.start_bound().cloned(), self.0.end_bound().cloned())
    }
    fn x_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>) {
        (self.1.start_bound().cloned(), self.1.end_bound().cloned())
    }
}
*/
impl<T: std::ops::RangeBounds<(usize, usize)>> TableRangeBounds for T {
    fn y_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>) {
        (self.start_bound().map(|&(y, _)| y), self.end_bound().map(|&(y, _)| y))
    }
    fn x_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>) {
        (self.start_bound().map(|&(_, x)| x), self.end_bound().map(|&(_, x)| x))
    }
}
pub struct CumulativeTable<T, F1, F2> {
    op: F1,
    op_inv: F2,
    inner: Table<T>
}
impl<T> Table<T> {
    pub fn from_rows(rows: Vec<Vec<T>>) -> Option<Table<T>> {
        rows.windows(2).all(|window| window[0].len() == window[1].len())
            .then_with(|| Table { inner: rows })
    }
    pub unsafe fn from_rows_unchecked(rows: Vec<Vec<T>>) -> Table<T> {
        Table { inner: rows }
    }
    pub fn height(&self) -> usize {
        self.inner.len()
    }
    pub fn width(&self) -> usize {
        self.inner.first().map_or(0, |row| row.len())
    }
    pub fn shape(&self) -> (usize, usize) {
        (self.height(), self.width())
    }
    pub fn indices(&self) -> impl Iterator<Item=(usize, usize)> {
        TableIndicesIterator {
            height: self.height(),
            width: self.width(),
            y: if self.width() == 0 { self.height() } else { 0 },
            x: 0
        }
    }
    pub fn inside(&self, (y, x): (usize, usize)) -> bool {
        y < self.height() && x < self.width()
    }
    pub fn row(&self, y: usize) -> Option<&[T]> {
        self.inner.get(y).map(|vec| vec.as_slice())
    }
    pub fn row_mut(&mut self, y: usize) -> Option<&mut [T]> {
        self.inner.get_mut(y).map(|vec| vec.as_mut_slice())
    }
    pub fn get(&self, (y, x): (usize, usize)) -> Option<&T> {
        self.inner.get(y).and_then(|row| row.get(x))
    }
    pub fn get_mut(&mut self, (y, x): (usize, usize)) -> Option<&mut T> {
        self.inner.get_mut(y).and_then(|row| row.get_mut(x))
    }
    pub fn rows(&self) -> TableRows<T> {
        TableRows { table: self, index: 0 }
    }
    pub fn adjacent4_indices(&self, (y, x): (usize, usize)) -> Option<Vec<(usize, usize)>> {
        self.inside((y, x)).then_with(|| {
            let mut result = Vec::with_capacity(4);
            if y > 0 {
                result.push((y-1, x));
            }
            if x > 0 {
                result.push((y, x-1));
            }
            if x < self.width()-1 {
                result.push((y, x+1));
            }
            if y < self.height()-1 {
                result.push((y+1, x));
            }
            result
        })
    }
    pub fn adjacent8_indices(&self, (y, x): (usize, usize)) -> Option<Vec<(usize, usize)>> {
        self.inside((y, x)).then_with(|| {
            let mut result = Vec::with_capacity(8);
            let xs = x.saturating_sub(1) ..= std::cmp::min(x+1, self.width()-1);
            if y > 0 {
                for x in xs.clone() {
                    result.push((y-1, x));
                }
            }
            if x > 0 {
                result.push((y, x-1));
            }
            if x < self.width()-1 {
                result.push((y, x+1));
            }
            if y < self.height()-1 {
                for x in xs {
                    result.push((y+1, x));
                }
            }
            result
        })
    }
    pub fn accumulate<F1, F2>(&self, identity: T, op: F1, op_inv: F2)
                              -> CumulativeTable<T, F1, F2>
    where
        T: Clone,
        F1: Fn(&T, &T) -> T,
        F2: Fn(&T, &T) -> T
    {
        let mut inner = vec![vec![identity.clone(); self.width() + 1]];
        for table_row in self.rows() {
            let mut new_row = vec![identity.clone()];
            let last_row = inner.last().unwrap();
            for (x, acc1) in table_row.iter().zip(last_row.windows(2)) {
                let acc2 = new_row.last().unwrap();
                let tmp1 = op(x, &acc1[1]);
                let tmp2 = op(&tmp1, acc2);
                new_row.push(op_inv(&tmp2, &acc1[0]));
            }
            inner.push(new_row);
        }
        CumulativeTable { op, op_inv, inner: Table { inner } }
    }
}
impl<T> std::ops::Index<usize> for Table<T> {
    type Output = [T];
    fn index(&self, y: usize) -> &[T] {
        match self.row(y) {
            Some(row) => row,
            None => panic!(
                "index out of bounds: the table has {} rows but the row index is {}",
                self.height(), y
            )
        }
    }
}
impl<T> std::ops::IndexMut<usize> for Table<T> {
    fn index_mut(&mut self, y: usize) -> &mut [T] {
        let height = self.height();
        match self.row_mut(y) {
            Some(row) => row,
            None => panic!(
                "index out of bounds: the table has {} rows but the index is {}",
                height, y
            )
        }
    }
}
impl<T> std::ops::Index<(usize, usize)> for Table<T> {
    type Output = T;
    fn index(&self, index: (usize, usize)) -> &T {
        match self.get(index) {
            Some(result) => result,
            None => panic!(
                "index out of bounds: the table shape is {:?} but the index is {:?}",
                self.shape(), index
            )
        }
    }
}
impl<T> std::ops::IndexMut<(usize, usize)> for Table<T> {
    fn index_mut(&mut self, index: (usize, usize)) -> &mut T {
        let shape = self.shape();
        match self.get_mut(index) {
            Some(result) => result,
            None => panic!(
                "index out of bounds: the table shape is {:?} but the index is {:?}",
                shape, index
            )
        }
    }
}
impl<T, F1: Fn(&T, &T) -> T, F2: Fn(&T, &T) -> T> CumulativeTable<T, F1, F2> {
    pub fn query(&self, range: impl TableRangeBounds) -> Option<T> {
        self.query_yx(range.y_bounds(), range.x_bounds())
    }
    pub fn query_yx(&self, yrange: impl std::ops::RangeBounds<usize>, xrange: impl std::ops::RangeBounds<usize>) -> Option<T> {
        let y = yrange.to_range(self.inner.height() - 1)?;
        let x = xrange.to_range(self.inner.width() - 1)?;
        let val1 = &self.inner.inner[y.end][x.end];
        let val2 = &self.inner.inner[y.end][x.start];
        let val3 = &self.inner.inner[y.start][x.end];
        let val4 = &self.inner.inner[y.start][x.start];
        let tmp1 = (self.op)(val1, val4);
        let tmp2 = (self.op)(val2, val3);
        let result = (self.op_inv)(&tmp1, &tmp2);
        Some(result)
    }
}
pub fn backward2_indices((y, x): (usize, usize)) -> Vec<(usize, usize)> {
    let mut res = Vec::with_capacity(2);
    if y > 0 {
        res.push((y-1, x));
    }
    if x > 0 {
        res.push((y, x-1));
    }
    res
}
#[macro_export]
macro_rules! table {
    () => {
        unsafe { Table::from_rows_unchecked(Vec::new()) }
    };
    ($element:expr ; $rows:expr , $cols:expr) => {
        unsafe { Table::from_rows_unchecked(vec![vec![$element; $cols]; $rows]) }
    };
}
pub fn read_table<T: Readable>() -> Table<T::Output> {
    let res: Vec<Vec<T::Output>> = read_lines::<Vec<T>>().collect();
    Table::from_rows(res).unwrap()
}
pub fn read_table_rows<T: Readable>(height: usize) -> Table<T::Output> {
    let res: Vec<Vec<T::Output>> = read_lines::<Vec<T>>().take(height).collect();
    if res.len() < height {
        panic!(
            "tried reading {} rows for table, but stdin has only {} lines",
            height, res.len()
        );
    }
    Table::from_rows(res).unwrap()
}
pub fn read_char_table() -> Table<char> {
    let res: Vec<Vec<char>> = read_lines::<Chars>().collect();
    Table::from_rows(res).unwrap()
}
pub fn read_char_table_rows(height: usize) -> Table<char> {
    let res: Vec<Vec<char>> = read_lines::<Chars>().take(height).collect();
    if res.len() < height {
        panic!(
            "tried reading {} rows for table, but stdin has only {} lines",
            height, res.len()
        );
    }
    Table::from_rows(res).unwrap()
}

// END SNIPPETS
// Here is the documentation: https://yoshrc.github.io/rust-atcoder-snippets/atcoder_snippets/index.html

fn main() {
    read!(_n = usize, m = usize);
    read!(s = String);
    let s = s.chars().map(|c| c as usize - 'a' as usize).collect::<Vec<_>>();
    let mut freq = table![0; m, m];
    for w in s.windows(2) {
        let x = w[0];
        let y = w[1];
        freq[x][y] += 1;
        if x != y {
            freq[y][x] += 1;
        }
    }

    let mut dp = vec![0i64; 1<<m];
    for set in 1..1<<m {
        dp[set] = (0..m).filter(|&d| (1<<d) & set != 0).map(|x| {
            let subset = set ^ (1<<x);
            let inner: i64 = (0..m).filter(|&d| (1<<d) & subset != 0)
                .map(|y| freq[x][y]).sum();
            let outer: i64 = (0..m).filter(|&d| (1<<d) & set == 0)
                .map(|y| freq[x][y]).sum();
            dp[subset] + subset.count_ones() as i64 * (inner - outer)
        }).min().unwrap();
    }
    println!("{}", dp.last().unwrap());
}