int pRec(int n) {
    static int *memo = NULL;
    static size_t curSize = 0;

    
    if (curSize <= (size_t) n) {
        size_t lastSize = curSize;
        while (curSize <= (size_t) n) curSize += 1024 * sizeof(int);
        memo = realloc(memo, curSize * sizeof(int));
        memset(memo + lastSize, 0, (curSize - lastSize) * sizeof(int));
    }

    
    if (memo[n] == 0) {
        if (n<=2) memo[n] = 1;
        else memo[n] = pRec(n-2) + pRec(n-3);
    }

    return memo[n];
}


int pFloor(int n) {
    long double p = 1.324717957244746025960908854;
    long double s = 1.0453567932525329623;
    return powl(p, n-1)/s + 0.5;
}


void nextLSystem(const char *prev, char *buf) {
    while (*prev) {
        switch (*prev++) {
            case 'A': *buf++ = 'B'; break;
            case 'B': *buf++ = 'C'; break;
            case 'C': *buf++ = 'A'; *buf++ = 'B'; break;
        }
    }
    *buf = '\0';
}

int main() {
    
    
    char buf1[BUFSZ], buf2[BUFSZ];
    int i;

    
    printf();
    for (i=0; i<20; i++) printf(, pRec(i));
    printf();

    
    printf();
    for (i=0; i<64; i++) {
        if (pRec(i) != pFloor(i)) {
            printf(,
                i, pRec(i), pFloor(i));
            break;
        }
    }
    if (i == 64) {
        printf();
    }

    
    printf(); 
    for (strcpy(buf1, ), i=0; i<10; i++) {
        printf(, buf1);
        strcpy(buf2, buf1);
        nextLSystem(buf2, buf1);
    }

    
    printf();
    for (strcpy(buf1, ), i=0; i<32; i++) {
        if ((int)strlen(buf1) != pFloor(i)) {
            printf(,
                i, (int)strlen(buf1), pFloor(i));
            break;
        }
        strcpy(buf2, buf1);
        nextLSystem(buf2, buf1);
    }
    if (i == 32) {
        printf();
    }

    return 0;
}