I set myself the following additional goal (devised by me):

This program was motivated by an excellent talk given by Professor Imre Leader at the Peterhouse Kelvin Club on Tuesday 13 October. It implements t he recursive relation given here and explained in more detail here to find an upper limit on the Ramsey number R(m, n) from a given m and n. This number is the solution to the question "how many people do there need to be a party to ensure that either n all know each other or m are all strangers to each other?" Ramsey numbers 3 a nd 4 are known, but the the fifth Ramsey number R(5, 5) is only known to be between 43 and 49 inclusive. The upper limit generated by this program is not a strong one but its existence is a consequence of Ramsey's Theorem for a two coloured graph.

I have some limited programming experience in Java so this program was an exercise for me in using various bits of c++ syntax and in a new IDE. It is not especially beautiful or efficient, but since the largest input it can accept is around 35, 35 before it integer overflows any improvement wo uld not be noticed.

//  Ramsey Number Finder
//  I have not used c++ before so there may be some odd looking code

#include 
using namespace std;

int main(int argc, const char * argv[]) {
    
    int m, n;
    cout << "This program calculates an upper limit on the Ramsey number R(a, b) if given a and b, and shows all the values used in the recursive calculation." << endl;
    cout << "\n";
    
    start: // return here if the instructions were insufficiently clear
    
    cout << "Enter two numbers greater than or equal to 3" << endl; // crashes on anything other than an number input
    cin >> m;
    cin >> n;
    cout << endl;
    
    if (m < 3 || n < 3) {
        goto start; // return to the start if either number is less than 3
    }
    
    cout << "R(m, n) is given by the m and n coordinates." << endl << endl;
    
    long ram [m + 1][n + 1]; // create rectangular array and initialise it with some known values. the array represents a binary tree where each R(a, b) has two children R(a-1, b) and R(a, b-1) to from which it is calculated.
    // the indices x and y correspond to n and m - array imagined as if in +ve x, -ve y
    // the upper limit calculated by this method grows by something horrible so longs are used
    
    for (int i = 0; i <= m; i++) { // this is not necessary for the correct functioning of the program, but it seems like a good habit when writing in c++
        for (int j = 0; j <= n; j++) {
            ram[i][j] = 0l;
        }
    }
    
    for (int i = 2; i <= m; i++) { // all that it needs to know is that R(2, z) and R(z, 2) are z.
        ram[i][2] = (long)i;
    }
    for (int i = 2; i <= n; i++) {
        ram[2][i] = (long)i;
    }
    
    
    bool work = true; // while it is working up the grid
    for (int mi = 3; mi <= m; mi++) { // starting at 4, 3 and working diagonally up the grid starting at the left. this approach gets us about halfway in the case of a square grid before we have to start working along the bottom.
        
        int y = mi;
        int x = 3;
        work = true;
        
        while (work) {
            
            if ((ram[y][x-1] % 2l == 0l) && (ram[y-1][x] % 2l == 0l)) { // both of the parents are even
                ram[y][x] = ram[y][x-1] + ram[y-1][x] - 1l;
            }
            else {
                ram[y][x] = ram[y][x-1] + ram[y-1][x];
            }
            
            if ((x == n) || (y == 3)) {
                work = false;
            }
            else {
                x++;
                y--;
            }
        }
    }
    
    for (int ni = 4; ni <= n; ni++) { // same thing working along bottom of grid and going up diagonally
        
        int x = ni;
        int y = m;
        work = true;
        
        while (work) {
            
            if ((ram[y][x-1] % 2l == 0l) && (ram[y-1][x] % 2l == 0l)) { // both of the parents are even
                ram[y][x] = ram[y][x-1] + ram[y-1][x] - 1l;
            }
            else {
                ram[y][x] = ram[y][x-1] + ram[y-1][x];
            }
            
            if (x == n) {
                work = false;
            }
            else {
                x++;
                y--;
            }
        }
    }
    
    
    cout << "\t"; // print the array nicely (where the numbers are 3 digits or less)
    for (int i = 2; i <= n; i++) {
        std::cout << i << "." << "\t";
    }
    cout << endl << endl;
    
    for (int i = 2; i <= m; i++) {
        cout << i << "." << "\t";;
        for (int j = 2; j <= n; j++) {
            cout << ram[i][j] << "\t";
        }
        cout << endl;
    }
    
    cout << endl << "An upper limit for R(" << m << ", " << n << ") is given by " << ram[m][n] << "." << endl << endl;
    
    return 0; // made it to the end. could add a goto to the start if we wanted?
}