import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop;

struct Edge {
    int to;
    int money;
    long dist;
}

void main() {
    auto s = readln.split.map!(to!int);
    auto N = s[0];
    auto M = s[1];
    auto S = s[2];
    auto G = new Edge[][](N);
    foreach (i; 0..M) {
        s = readln.split.map!(to!int);
        auto u = s[0] - 1;
        auto v = s[1] - 1;
        auto a = s[2];
        auto b = s[3].to!long;
        G[u] ~= Edge(v, a, b);
        G[v] ~= Edge(u, a, b);
    }
    auto CD = iota(N).map!(_ => readln.split.map!(to!int).array).array;

    auto dp = new long[][](N, N*50+1);
    foreach (ref d; dp) d[] = 1L << 59;
    dp[0][min(S,N*50)] = 0;

    auto pq = new BinaryHeap!(Array!(Edge), "a.dist > b.dist");
    pq.insert(Edge(0, min(S, N*50), 0L));

    while (!pq.empty) {
        auto u = pq.front.to;
        auto dist = pq.front.dist;
        auto money = pq.front.money;
        pq.removeFront;
        foreach (const e; G[u]) {
            auto v = e.to;
            auto next_dist = dist + e.dist;
            auto next_money = money - e.money;
            if (next_money < 0) continue;
            if (dp[v][next_money] <= next_dist) continue;
            dp[v][next_money] = next_dist;
            pq.insert(Edge(v, next_money, next_dist));
        }
        if (money < N*50) {
            auto next_money = min(N*50, money + CD[u][0]);
            auto next_dist = dist + CD[u][1];
            if (dp[u][next_money] <= next_dist) continue;
            dp[u][next_money] = next_dist;
            pq.insert(Edge(u, next_money, next_dist));
        }
    }

    foreach (d; dp[1..N]) d.reduce!min.writeln;
}
