#include <cassert>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;

// int bruteforce(int D, bool print) {
//     const int k = to_string(D).size();
//     assert (k <= 4);
//     const int limit = int(pow(10, 2*k));
//     int ans = 0;
//     for (int n = 0; n < limit; n++) {
//         string s = to_string(n), t = s;
//         reverse(t.begin(), t.end());
//         int r = stoi(t);
//         if (D + n == r) {
//             if (print) cerr << n << " + " << D << " = " << r << endl;
//             ans++;
//         }
//     }
//     return ans;
// }

string to_string(int n, int w) {
    ostringstream ss;
    ss << setw(w) << setfill('0') << n;
    return ss.str();
}

bool check(int n, int D, int k, bool lz) {
    const int len = (k + 1) / 2, limit = (int)pow(10, len);
    int r = (n + D) % limit;
    string sr = to_string(r, len), sn = to_string(n, len);
    if (k % 2 && sr[0] != sn[0]) return false;
    reverse(sr.begin(), sr.end());
    string sN = sr + (k % 2 ? sn.substr(1) : sn),
        srevN = sN;
    reverse(srevN.begin(), srevN.end());
    if (!lz && sN[0] == '0') return false;
    const int N = stoi(sN), revN = stoi(srevN);
    // if (N + D == revN) cerr << N << " + " << D << " = " << revN << endl;
    return N + D == revN;
}

bool check2(int n, int D, int k, bool lz) {
    const int len = (k + 1) / 2, limit = (int)pow(10, len);
    int r = (n + D) % limit;
    string sr = to_string(r, len), sn = to_string(n, len);
    if (k % 2 && sr[0] != sn[0]) return false;
    //cerr << n << ' ' << D << ' ' << k << ' ' << r << endl;
    reverse(sr.begin(), sr.end());
    string sN = sr + (k % 2 ? sn.substr(1) : sn),
        srevN = sN;
    reverse(srevN.begin(), srevN.end());
    //cerr << sN << ' ' << srevN << endl;
    if (!lz && sN[0] == '0') return false;
    const int N = stoi(sN), revN = stoi(srevN);
    // if (N + D == revN + (int)pow(10, k))
    //     cerr << sN << " + " << D << " = " << srevN << " + " << (int)pow(10, k) << endl;
    // else cerr << sN << " + " << D << " != " << srevN << " + " <<  (int)pow(10, k) << endl;
    return N + D == revN + (int)pow(10, k);
}

long long f(int D, int k, int m, bool lz) {
    if (k < m) {
        switch (D % 10) {
        case 0: return (9LL + lz) * f(D/10, k-1, m-2, true);
        case 9: {
            const int q = m - k, pw = (int)pow(10, q);
            if ((D + 11) % pw != 0) return 0;
            if (k == q) return q == 1 ? 8 + lz : 0;
            int ans = 0;
            const int limit = (int)pow(10, (k - q + 1) / 2);
            int D1 = q > 1 ? D/pw : D/pw+1;
            cerr << k << ' ' << m << ' ' << q << ' ' << limit << endl;
            for (int n = 0; n < limit; n++) if (check2(n, D1, k-q, true)) ans++;
            return ans * (8 + lz);
        }
        default: return 0;
        }
    } else {
        int ans = 0;
        const int limit = (int)pow(10, (k + 1) / 2);
        for (int n = 0; n < limit; n++) if (check(n, D, k, lz)) ans++;
        return ans;
    }
}

int main() {
    int D; cin >> D;
    if (D % 9) { cout << 0 << endl; return 0; }
    const int k = to_string(D).size();
    long long ans = 0;
    for (int m = k; m <= 2*k; m++) {
        int a = f(D, k, m, false);
        // cerr << D << ' ' << k << ' ' << m << ' ' << " => " << a << endl;
        ans += a;
    }
    cout << ans << endl;
    // if (ans != bruteforce(D, false))
    //     cerr << "D = " << D << ", ans = " << ans << ", bruteforce = " << bruteforce(D, false) << endl;
    // cerr << bruteforce(D, false) << endl;
}


Measured memory_bytes: 256