1101000011000101010110000010001101100101111110011001110111110100011010101011111101111101001101001000010001110100001101111101000010011111101010001111100000010111010000100001100110010101101101000000111001101000011100010101101101000001100100110000010110100001111011001101111100110011100001111100001000100010100011111101110011010001101001101010110101000000100100101101010010011001001010000001011000001101 1111111111111111101111011111010101010111011011010111100011001100101100100011110111001000101100101110010000110011001110010111000101101111000000111111010001000110001100101001001100001000111010001100011101011101001011101110001000100001000000010101100110010010101101110001001001101101000000111110111001100010000011000011111011111011100111100100100000010100100111101110010111110011011110001001110110101000 0101100101001011010110110110110000011001010010101001111001110100011001011000110000001111011000110110011110111010010010001110000100111011101110010001001010100001000000110100010001100110110101011101100111010101110001101111111000110011101101100101110011011001001001010000111111000110000010111001100101111001010111001101111111100011101011110001001001110100100100001011111011100001011010010011110011100110 0010111010001001011101100111001100000100001110011101011111111000000111110101100101111011111111000111000000110100101010101110001111110100100100001110100111101001111010010011101010110100110011010010111101110000100100101101110001000100001111000010001011110101010011000000011100111100001001000110011111111111110101101111011110011000110100000111011101000000001110011001100110100110011110110100010000100000 1110010101001111011011000000001111011000110001101001110010100101010011101000010000111000001110101000100000000111110101010111110111010011001011000101100010010000011011100011100001100000100000101000111101000000010011100001000000110110101110100000011000101011000111101000000010000101001111110100111111110100110100100101111110100110110101010011110001110101001011010100000110101000001110001111000011011111 1111101101111000000101100111000010011110010000101000010101101110011010011001000101101111100101001100100000011001100110110100110110101011111000110100100100000011111011100101010010001111000011010010010011111100000011100000100111001101001000000000000101001100001011001111000010001010001010101101001101111010110000000100101010111110011000100110101010001000111100000111100001111111010100100101000010110100 0111111110011100001010010010000100100000001001010111100001001001110011101100100101001110110001110100011100110001111101100011000100011010010110000100100001010011010110100100001101000111011100100011001110110110010010100101101111001101000001000010111001000101110100000011010110000000110000100101000110100110101010010011001101101011101000001100011000010011001101010011011010011001000110100011100100010101 0111010000001011111001110110001110011100101010110101001110010000111100011100011111101101010101001110100111110111100001101011011010111010101110100101011011100111101001011011101100011010111010001100111011011111001000111010000001100101111110000011111111111011101110011011011010100111000000010011011111000110110000100010010001100101000111110101000011001110001011111000010010000111111100110011011000101110 1110011000110110011100001000110100101100100101011110101101101100000001001001100110110110000001001100101000111000111110101001110000110001011111010000010000010011101010100001010111010111011101000110010011101001110001001010111001110001100000011010101111101010000110010111010110111101000110100111101111100001010001100110100101111100100001111001111010101011010101100100100100111010101100101101011010101011 1101001010010100110111001000101101101111010101100110001011011001110011011011000001001100010100110101001000001100111011000010010000000110101101010110001001011111100011011111010100110001111011101101010111100101101100011010001101010000000010111011100110000000111000110010011010000110100111000000110110010000010001111010100110100000101010011000100001111111100001001110101000001100000011110010100001000111 0001001100110011111101101111010101100111111111101111111100101110101101000110101001000010010111100101110000011011010010010000011110100010011000010100110000110100011110011010010110011000100100010011010001111000101001000111001101001101000101110100110111001000110010011001001100101001001001001000001000111110101011000011000110111101001000000001101110111110111011110011000100100101101011010101111001000101 0001110101000000100101011010101010011110010001110110010100010000001001110110111011111110011001101111000100111100011100010001000000011100001110000111000110110100101110101111000111000110010100001101010011100011100001001100101101100000100100001010000100100011110111101001110010110001101011010001000100000101010110111111010111101100000011110000100001111010111011001100011110000000011111100000010111000000 0000011001000101111110010111001010111111110010111100111000100011000010001111010001110110001110011111100001110000111110110011010010101110101010001001110011100110110101011000110001110110001001010100110111101000100000100011011111011000010100101011001111011111111100010111000001010000000100111110000001011011110110011101100010110101110100111100010110001111100001001100001010111000011111000110011100110111 1110010100110011101100100100000011000011100100100110111101111000111010000110111000111000110001110010101110000101000100100111101111001110100000000101100110010011111000110110000111000110000011111011110011001110101000000011000010110101100110101010110100101111111000000110101011001011101100101111011100110100010010101111000000111100100000110000001100001100110011001110101010001011101110100010111010011010 0111101111110100110110001001011100011010110100010010011011010000101100110011101101011011001010110111001110010111010111111100111101000011011000110111100000001101111110110010001101111001110110110111101011111011111011010110001001101111001111101110000100100001011000010101111110111011010111100111001011110001000100001101001001100011101000101111010010011010101101001010101000011001101011111100000011111001 1011010110110101000010100011111011101110101001110010011000010000011100001010000110010101011101000001111000011001000001001000111111011011001100101101000101000110001011001111101001001110101000010101101101100110001010001000010111110100111011000111110000011011100110010101011011000111100111110101010110000111110010100001000000010101011010110010011111001010011101011101010010010101100001111101001000111010 0001110101011100100111001110101011110000000010001011001001001001000001000010101100011101011111001101010100100000011101001011011011111110000111110001010010011010011001000010101110110111110111000010001101010100101010001010011110010110100111110111001010011001111101001001001011001101001111011001111011101000001001001111010100100110010011001001011101101010011001111101010100001010111111101110011100101010 0001100101001000110111010010110001110001011101100011010101011101010101100001001100001111000010100111010110111000110010001111111000011111000100001111110111101110100110100100110100110001111100000110111010010111001000000101000101100010101101101011101001100000101010000100000100101110100001001001110110000110111101000011101000010011101000010101001110000101110010101011000001000100010100110111011000000011 1010111111011000010101011100010000111010000100110101100000100000010000100001111111111001101011000110011110001011110101110111110110111010101000101000101010000011110111001011011010010001101110100110011111100110011101111001111100101101110101101010000001010010000101000111101001001101110001100111010011111110010110111111101100000110111011000001011010001001110111001100110011000111000010000010111010110110 1100001000000010001011000000011001111101011100000110111011010110110100100110001101010111100010000100001100011101101000011010000100111011010001000000000111110110110010000001100000111001101000010011111011011110000101110101100011000111000011011100000101010010000111010000110011000000110110000001101001110001111001010110111101001101011001111111000000111001101000010110011101011010100100111110011101111100 1000101000100110000100010000111101001011101011110110000100010011010000010011100000101110011100100011010111010000010011001011011011001101011100001011000100001000100111010101100111011110101100000010101100111101100010000001001010010011001111100010010010010100110110100100101110101101011100110000110101001010000100010000100100011000011001011110100000001011000000111001110010100001110111010000101001111110 0001110011101110011110101000111011111101101110110011110001010010111111110110011001111111110000001001100001100010110001100110100011100110001111010100010111000110001010100001101000011011101010010111011001010100110101001010110111110000010001101010111100010111011100011010110011000101010000011000001001000111000101001100100000010110110011110010011011111000001100111001110111011011000110001001100000100111 0000011110111101010111110111101111100111000000011010100011000111011010111000001010011100111111000000110110000100110111110100010100011011100100111111100100100010101001111001000011101111000110011110000010101110110101001010011100101000011110111101111100110110111011110010110101100000110011010111111101110011000001000010111011110100111110010110110101001111110101101111000011001011101111110100101011000100 1011111000000001101001101001101001101011100010001011010100001001110011110100010000001111010000010111010010100101111100101100100010010111110000000011111101100101001010011110010111110100010011011011101000000110011000001100111001100010011111011101100001000011111001100000110101110000110100001101110100001101010001001110100000100101110101100110110000110010000001100110010000111100001011111111110110000111 0010000000101001001000101001100100000111000000101011111111010000110100111100010011000111000001001001110100100100001111111111010010011001011110001110110100010001100101100101100011010111000010011000000110011101001111001100010111100000111010000010000100110100110100011110111000000110011000010011011110000100110100111100101001011000001100111011001110111101000011111011111100100000000001110001001101101101 0000100111110001011000111111010011000100010110111011001110000111100100100000001111011011101111011101001111000111101101111110001110011001101000001001101011000001000101111100010110111000110000000010000000001100010111011111011001101100101010100001101010111000111101111111100010010011001111000110100011100101111100110101000010011001000110101011010111010101000100001110010000000010001000010000101111010111 1100000011110110100111110111101001011100101101011100110111010000110101000110100100011011000101011110011001101110010110111000011000111111000000111110001011111010110000100001001110101010001101110101010000001010111000101110101111011110101011111000100100110010100010000011010011011110010101110111011100111011100010110010110010011111100000011101111001001001011000001110000110111110000101001001110100010001 0110011011111001001001101101001010010101011000000000010110001010010010010010001000000110110011000111001111101000000010110000000111110110110010110001000100110111001000011011110011010111101001100101010010110111010000010110100000011101011111100110000010110000111010000011110100000001001101010110000001100001001000010000111010100101111011111100011101001110001000011101111110111110000010001010000001011001 0011101110001111000110011010101111000011111100011110000011000110000011111000001001111101011110110111110010010011011001101110011100100100001010010011100000010111010010111110000001010110000000110011011001000110010101101111011010111001100101111100101000000110111101001001101001000001000000000111001010011001100101110111111101001000110110100001010001100000010111010000000100010100011111000011011101000100 0001000010101100001001110011111001010010111111000101001110001110100000011100010001101000010011000100010011000000001111110001001110001100110011101101110110011110001100011000100110000110110111110101111110011001000000010001101110111100100100101011010001100010001011110010100011001110010100111101000010010011100110110101101111111111001011100110010110101100001010001100010101101101001000101011111100000101 0001000101111111010000000001011100111110000110001000101101100001000000000011001111100010001000111011011110110100100000001011110110001011000101101010010000110000011101010101010101001000000001111111011011110010010100001111010110111010000100011010011001100010111110110011110000111011100001110011101011110111111010010011100011110100000010100000111011011001101011010001011100101111111101111010101000110100 1010010011100011000011001011011000000110010010000101100110100100101001000101101001110101111000100001110101100100100110010010001110100111001010011011110110000000101011101101011000101011001100111011011110101100111000101001010100110000100010010110001111111001010010010010001111011111110110000000110010110001000001010110100110001110000010101101111100001011000100010010010111000011110110100101001011010110 0010100101110101000000100111001100111010111011001010000110101001101100000101101011011110100101010011000010011010100011010011011011010010001111011010001100101010010110110101011111010100011011101100110111011010001001100011001000110001111101000011001100100010101111001101010000001010010000011001011111101011110010001110110110011111101100101100000111000111110000100011011111001010110110101110111111101111 1000011100000100000100101010111101000000101010111001011011100100101101111111110011110000101001110001110010101001011001001101100111110011010111100000101101011111111011011100010000000010101010011000110000111111101110100100000000001100010000101101101100111110000011111111110111110000011111110101010000010111100000010100011110011111000001101100111111111011101100001000100100111000000011101000100011011100 0010010100111001010011111111000010000111100100001100110111100000001011110011100000110111011000111100101110100111000011011101001010000101011100111100011111000111001010111011111101111000001000001001011110011110010111100100001000001110010001101001100011110000111111000111010010011000001000111100000000110110010001000100100100011110100111111011000011110001001000101011001101101111001010010111101100011101 0100011111110011011111101001110110100000000011100001110110011000111010010001111110000000111101011100110100110010011111101010010111000000010000001000110101110011000000100011101010010001011000000111100001010110011101011110111011000001100111011010010011000001001110101000100101111011100100010000001100100110011110000010101101010010101100111000110100111001110000011101001000010101011011110110000110110010 1111111100010100011011001011111100101001111110100011111001101110000111100000011000010100110000000100110101111110011110011000110111100000110011011000000010011101101101101000010101010011010101100000010011100001101000111100100100001010110111110001101010011101110101111110100101111100110001110101000111001110101111110101111000010110110111000100000110001010110000001000111011010100000000000011111101000010 0110111011010101001110010011010001001110000101100000000101010110110001110001100111100101011100010110110000010100101110000100100011110101010100011000010011110110010001101011100100110011111011100001100100001110100000000100000111101111001110001000110100100110101010111111001010010100001101110111110100101010010001100100000010100010111000001101110100011111010010111110000110010111010001001100100101000011 1101101010001100111011000110000111111001100001111101011011111011101000010011001101011110101100001011001010100001000110110101100010101000010010101100111100110110001000001111001011110000001101110101001001001101001011111010110010010110100111000100001010100010101011001111000111111010000011111010110111110111111100001110110001101010111111011000111000110110111101111011011011011101101110000010100001111010 0101111000000100000010011110010000101110110001100010101110011011010000010000001110101111110100001111001110101101100100110100110011100011000100011101010110010111000110011111001011111000101000011010011100111111001111011100000000000011100001000000001100011001100101100001111001000100011100111111111110100001111001100000011101010011000010111001011100011011011000111011100110000111110100001110011001001101 0101110111111011100000110100010001010100001011111011101101010000000110000101110101010011001100111110010000010010110100111110010110100110001000100011101000011110110011011001101111110100011101010101111001110111000100111101100111010000101100100111010101111101111010111001110100010110100011011001010110111100011100010000101001101010000001101011001100000010100001101101010011111110010111100010011110110100 0101001011101010000110111110000000001101001111100001101001011101111101110011101101101000000110110010001010100100110001101101000010000011111101010011110001011110100101010101010001111110001101110111011111000100001111101110000001101101110001010101011110100110011010110010111101010001101111010100001110101000011111011010001111001100100010100111110100111000111000011011111111000010110011011001000111011001 0101101010101100101010001010000010111100111100000011000011000010101001100110101010111100101110100101000111010010110010111100100101111001011111101100111101100110110111000001100010011010111010000100011010100011101011011000000010010000111000010001101010101000110100111110011011111110010001011010011000110010110111101100111100001101110101010011000110000111000110100110111100110110001011000010000010101100 0001001000111110111111000100001010111001001110001100010111100001101101001111111001100011001100111001011000011100110000100100010110010101011101010101010010111110111001111101100011101001001011100010001101100001111110100011000000110011001101111011101010100001001101000111101110010111010010010011001111001101111010001011010100001011100111100011001011110110000111000100101111111000110111010110010010000100 0011001101001011111101101100011001011101010111111011011111001000011100011111101110001010000111110011110101110011111010110111111000110000101001000001011100001111111111100011110001110111000001010100110101100111011110101000100101110101101110110100000001011110011001010101111000110011000010011001111001110011001110011111111010010010111111110100010110011001101000000011100101001010000001110000110110101000 0100111011010110001110001011000100110000010101101100000001011000000101000001000011010110111010010100101010100011011111011000001000100011110001101110111101000011110010101101011000111000110010111110110110100101001111000011001111010100011001001011001001011101000001111001111100101111110000110101101010100010010101011000000101101110101000101111001101001011001000000101001000111111011011011110100110110001 1100101110000000111001111011011100100110011001001101111110111111010100010111111100111111011100101010101010110011101011010001010000001001100100001100011000010100001000011101100110111110110000111101110111010111000111010111110010011110100001001110100110001010011110111011001001011000010101101100111010100010000110111100110100011100001000101111011010000010001011110100010001111101001111110001011101101010 0010100000011001001000011011001001101010010110001111011111111101000110110011000100010100110100010011100011111001110101100000001011111011101110001100011001001111011111100100101011010011010010000000011010010101100100011111000110100110100111100111010101111001001001001011001000101101011101111110110000111010100010000101000101100110010010100100001001101001010100111110111010111101101110000101000001000110 0100100100000110100100100110001010010000001100101101110100000100110000100101110111010110000101011110100000110000111011010010101111001101101111110000010001011100011100000100011011101010000011110010010011011110100110010111001110111001010000000000111000110100011111111100000111011110001101100001101110000100000011010011110110011101101111110110000100110011110110101111110010100101111000100111001001111010 1111010010111011110001111000000110010011011101000001110010101011001110110010110110001000011000010111111011011101001101010011101111001001010001000011001011001100111011100000001010101111111100001010001110110101000001001101001100011010000100000101100101110000011000011001001011010110010101001111010111110111010001101011011100111100000101000111001110110001110100110010001110011010010010001011110111101110 1000000110001001010111010111111111111010010111000011101011110100000100011111000100111000001011110000111111010110011010110110010101110100101011001010010111010100011010010011110110000011011110100001001111101010110000001111100001010100000110101000010100000000101011101110001101010000100000001101010111010000011111110111011000101101000100111111100001111011011000101001011100000011011001010010101010101000 1100011110001010111110100011110010100000000000101100001101011101111001100010101001101110010110101100111011101101001001011011011010110011111101001011110100010001001001010100100011001001010000110101001100101011101011110101111001100011101111101110001000010010100000111011000101010101100011100101010000011000111001000010010010100101011011000101101101101101110011100110001100100000100011101111100110101001 0010110101110101001010110111001110110010100100111001010000111001000011111111000100001010011100111000001011101000010101000000100010001110010100101111010110100111000001001011000100110110110100100000100100000100011101100001101000000100110001011001010001011101111100100000000110100110111100000000110111001000101001100001010010010100101000011110001011010011101011011011011101101110011010101011001010010011 1010110011100011000111101011100011111011101010011100110010010001010001001000101111101011011000010101111011000010001001100011110101101111011101001010101001100101100000010011101100011101011001100010110010010010101001100101001111110101011111001011110101000100101000011111010000111000110000000110111101001001101000111001110100000101000100101000001001101111101100100101111111111101011110010111000011100000 1111001110110010111100001011101111101111100101111100110101000110100011000011000011101100111111100111110101000000000111000000100010001011010100011000001100111101010001001001101000011011111100000001001011010000000101011011101111000100011011101110101111110111001010001111010010101010011111010111010101000011100100011101110000011110001100001111110111011110011111111011011111100001001111100110011110001001 0001100000111010111011011011111000100001111011101001101101110010001100001000101000101101000001100000011000100011101000000011110110001010101100000000011110101001001010001000100010110011010001010011111011100001001100011001100011011000010011111010011001110001100110101000001110010001001001011111101010010100100111101010011100000000000111100111110111001000001100011111110011011101110010101000000011101000 1101000101110100011111010000010110101100001100101100011101100101001001000010100110010101011110100000000011000010010111100101001110000100011101101000100110011100001100100010110001000110011110000111010011011111100110100100000111000110010001111110001001011111111001010001011111100001101010010101010111001010110000111010010010100010100001110001100101110100011010010000110111101101011001001001011101010111 1110011110010111111100111111010100111000000100100100000011000011100101000001001111010001100010100111111001100000111111110000100101111101000110101111111011111111010011010110101010100100011011111100101011000001001110000001001101001111110101101010010001111001000001000000111110011001110010001100000010110010000110101010110111011101110011011010100110010011011000110110000100100110000110001111100011101111 1110111011100111001110000001010111111110001110100100110110110101101011100011110011100000100110110001001110000111011011100101000001010100100110111101100011001011111100010100011010111101000111101101001000110111000000000001110010111111001110100001001010001100010100101010011000111111100111111100111001111010111111100001101001010001110010001111000110010101100110010101101111001011100000001000011101001000 0010001001101111110101101101011010001011010001001001111111110001110110000110010010010001011010000011100111100000100110011000111011010011110010011000101111100001010100111101110010001100101001110001010101011011111101100001011100011110010110101110110001011001011101000001101111100111100011100101110110011010111110101011011101101011000110011110100011100111110101010111001001010101001010000100100111011001 1011000100111100111110110100011100011110001000001110101100101011110110010101110101001010010101010000001100100011110111000111101001111101010011111010000001011011100011111010110011000100000000011000000100010111000100010010001000111100100010100011000100110010001100001100000001000101111011111101111000001010001010010111000000011111101110010011010101110101101101011100110111101100001011110100000101101111 0010010101110110111110000111101111110100110101010101110101011011101101011000110110101000001000010100100010000111001110011100100111001010110000111000111101101001100111000111001011001001010110111110100001001110100010010101111000000100001010011010000000110010000100101101111010001010001000000010000100011101001001111111100011011000001010010001111100101110111111100110000111001000100010100000111000110110 1001100000001101011000000001101111101100110000001101010110011100100111101000101001110000110001001111000011001001010010011101001110000010000110010110110100100001101101110111010101101100000010111111000110001000101010111111010010101000011100111001010100100011100110101111111111101101111101110100111011100100010011001010100101000000100000011110000101110001101011011100110100100110010100110100111110101010 0011101010101011001101010010111010011111110110011110101110100111110101111111010000010010111001011100111001100001000000011100101100111000101010110110010110010000111100101110100000011000001111001111110100011000001011111010111001111100010000001001100000111101111001000100000110101100010100100011010101111110001110110110011111101111110100010110011111010110100010010001000001101101101010010101001110010110 1110110010011100000011111100111011111110100010111001010111011000000000000100111110101100111101101001001100101011110111101101110011001001111101100110011101111101110000101100011101101010111001101101111111100111111110000100010100111110110000001101001010111011110010111010110101001101110001011001011001110001110101011010110110010000011010111111110100100011101000001110100010111111001100100101010001100110 1000010110111100000101110100000101111011101111110110100111100001011110000001101011100111010100101011011110110110101010101011111001101111000010010011101000110010001011101111100100110100001110101111100110101010101001111001010110101111101010000111110100000000010111101110101111100101011101001000011001000101010101001010011111110100011011001100111101001001000000101111110011100101001000101001010001000101 1001101111111011000010101100011100111011000000111101110010100101001000000101100000010100001011111010001110010110110100011101110000000010010011000100001000101110001110111111100111011111110101110001001010011000001010110000010111001101000001010111010110101011111011011101000101111011111111000100101001010101001100100001111110011011011110101001011000010110010011111100000101011111000000100110000100001100 0011001110101000111011010111101100000100101011111011110111100110011101100010001010110110100011011011011110111011100101000000001011111100100000011100101010011100011000101100111010111110011100101011111000011111100010011001011000000111010111010101110111100101111010101101000111000100001110100111111101010001111000000000100010011000011011011000001100011011010100101001000010001010011000000010011100000001 0010011110101111101011111111100001110011100101001000011101101111011011000011000010101110101000001110000100101111100001111111011110100000011000101100001111001101000011011011000111000010000110101000100011110111111101101100010111110110110111011000011111010111010110000101101110001000001010000111011111100110011011101100100011011001100001000011001010011000011010100000100111110001110100011011000011110110 1110111010001111101101001100010111100010100101110110110111111111011101100000110010110100010000101001110110010000010101011011001110010011010001100100000010111010000000001010010010100111000100001000000010010100011011100001111100001110010000101100010011100001101010011100010010000110110010000001011100010000001001000110001001100110001010000001011111101101000100011010000111110001010110010010001000100010 1001100111111101100101001110000111001110110100101010000010110111111110011100101111100111100111010010000101011111110000100111101110111111000110000110011101011010010010001001111000001101111101000010001110010100010101111001110111010110011010111000100001110111001001100110111110111110110000000100100010001000011100000100111100110011011100001111111100011001100100001001111011001110110000111110011011000010 1000111010100101001011000111000110100010101011101000001101001001100010001001011000111111110001001011101110100010010111110001100100000001011010100001111110010101111010101111110101001100011010000100000110011000000101111101010101011001001001010101101000011101011001101101011000110011000111010000010000110110110111011111010011100111000100000100111010100000001010011001111000001010100101111111111101000100 1100000001100110011001101101100010100111000111010101101101100000111001000011001111001110110100111101101001010101111100100011011001011011100110100010011001101100011101101100101010010011001101011010100010101001101000011110100111100100110010010101010011100100000000011010110110011100100110001111101011100110011110100000101100100000001111011111010011000010100000101001100101010001001010111111001001111010 1001111111000001010111111101000101000010011100011111101010100000011101000000100111100001001001000100101011011100011101000101101100001100101101110101011010010101111011111100000011100111110100011001111010010101010100011010100010111100101110000101011111001011011111111110010010000111100110101000001011011100000000111101111000000001101110100111111111111100000011010110001100110111110000100010001111111111 1110011100111110010101110010001110110001101000001000101001101111100010001001111100110000111111001000110011111011011010101010100000001101100011001111000111000000111000110111001001010100000101001100001011000101011101111010010011101011100010011100110101101000111100000110100111010010001111010000000100001100100000101000101101001001001110111010011110001111011111011010001110010100010001101101011001111101 0110101101111110111100111011000011011000101110001110000001111111010001010010010001101011110000101100010010010001101000000010110011010000100000000001000110010001101000111010100110001100100011010111010100100110110111000000011100001011001101011111010101001111011100010010011111000111010001000001000110001010110101010100011000011100110100011101000011110101111110001001000010110010101011101010010000000110 1010110011011010010001011110010011000001000001110001101101101100001110010100101011110100000110110001010010001100010010111001110010100000100011000101001001101010100011101011011101011010010111111100001101011100100100001001010110001100010010001011010010101101111011010011011111010000110010001101011011001001001011100001101110011000001010110001110110111000111110011110010011011111010000111000000110001000 1010001001011101011110011001010100001010001000001100010011110001011101000010001001001100000100110001011001001100100000000101000110010111000110100110100101111110110111110100000110001001101001101001100000010001001111110110111010110001000010101110010000010000111110001111110000011010111001011001110000111101000100011000110011100111010000111111111011110011010100011100000011001110110011110111011111110010 1101111110110001001001111011010111110010111101111110000011101100110011000101001011110100001110111110000111001000101001011100100110010010011111101101010011000001100110110101110111111001110110101011100100101110101111010111001111110100110011111011000111101001001001011111000000000000111110001011101011000000110100100010010100000000010101111001101010000000101000101100011011010111000101000100000101001110 1100010101110111011100110000101111010100101101110011001101000001111001000000100111111101000000110001001100011111010111011001010111000000001101011110010101010111100001001101111011000011011001101110000000001000000011110000111100101001010001101011111111001100110101110001101100101101010101010100000000000011101011101101101100111110110000111101001010110000001011100010110101000101011010001101101001111010 0111111110110110011111001000011111010100011111101001100011010100110000110101110100101110011111011010000111101010001010111111001010000100111111010010011101100101111110110111001110100111101101000010001001110101100010101010110001010110001100010110110100110110001111101100100000010111111000010100110001101010110001000111101011010000000010101111110000001001011100011000101010110011101110000101000011010100 0001001101101000000000001000110100010111011110001101001101111101100111000011011101111011001010110001110100001110000111001011011101001111111100111010000000110010010011010101011010110110011000100011101001011010110000111110100011111110001110111110000010000000101110110010010100011111101111001101100101110101000101000010111111101101111100111101110011100101101110011000000111011110000100010101111110000000 1100001001001011010111001000111100010100000001101011100110110110101000011101001111100000011011111011010110000000000100010100110110011111000010101001001011100110110100011001010100011111110001010000001011000101010001010110011100001101110111010001011101110110111100010110101011100000101001100000010100001011100000010111101111011011001110001000111110100000101100010111010001110110001010011010000011111011 0011000110000111110110011011101111010010100000011010101001111110001101011101001101011001011001101101100010000110010111100111101110101010000111001111111001010111100010101100100101100100100101101010011011011110010001101110000000110111010011101011000000110000011011000100100011000100001110011101101111111001101101111101011001001100101100101111100001111000111101111011010001011011011110101100111111001110 1100000010000010111110111000001111101000110000000011101000110011110110111111001101110100110000011101101111000011100111101010100100100011101011100101101111000100110010100000111010100100000111011101101000101001001000000100111010011011110001001101111111100000000101000101011000011110100010001110000111101001011111010000110011000110001100011000111010001100110000101001100100000011111100001010010110010100 1011111100111000011010110000000101101100001100000101010011111101000110001110111001111000011000010001101011010110001100001100000011100010011100101000001101010100100001001101010000110110000101000000100011001101100010101011000001101100010101011001011011100100101100011100001110111100010011110101010011110111101100010000001111010111111110000010111110110010001010111001010110001100111010001110010110010010 0010001110011010111100011111111111001111011110001101001111101101110111000101010110111000110100010010110010001010001000101010011111100011111010011001101011110000100110100100111010100001111010011110010111111111100100111000100110100111010001100101101010110111111010000010000000000100000010101011010011100100010101111001001010110100101000011100000111011110110101111001011011010101011110111110111101001001 0000111110001111000100000111010011010101100111110101111000010111101000100100011011100010110100110100010010011010101100010010000101100011100001010010011000111001111010001110100111110101001010101100100000010010100000011000001100100110000111111110111010110111001110010000011101101011011111010000110111101011001010010011100100011111100100110001011000001110111000100110010100010100110101000000111001111100 1100011001011100111001000100001110000101110000010001101011110000100010110011111011110100111011101010100110000011101100001000011010110110111001001100000011000100110111101000010101111001110000010001011101010011001101010000011100110111000100010010001001001010010001100000011011101010111011001100100000001000000110011111011010101001101100111110110001011101101001110100110011010011011111000110111111010111 0100001011111110001010001101111101101100000110111001100000110110111010101000011011001100000000110101111101111111110110101111000100100010101100000000010100101011101000001111011010110101101011101100111110010100000010010010101001101110100001000011101000100101010010001011000110100011100100010101110111011001000000000001000000111110011001000100111101111100001001000011100011001011001001001010000101010110 1001101000100000010001000011001001111000011010100010001110111000001100101010111000101101011001011001111100101001101101000111101011011000100000111100111100011111000000010000111101011110010111100001000110010111110000000001101110100101110000010100001001011011100110000101001010000001111110101000100101000011010110011100100100111111110011011010110111110010110011001010000000000110010101100101111001000100 1101010111001111001110111101011101100100111110001000010000110000101101010010010000101000111011111001110101110111001000110111111001000101000011111011111010010111100001010011000110110101101100000001010101010011101110010101111100011000100111110001101000001101010100010001000000110010101011001111110000110001101100010101010111001111110110001111101011010001100111100000110010101011101011101010001101101101 0011110110010111101100011101110011010101100100100101000000010011011010101011000000100111001011110111011110100101000010001110110110011101110110000000010111111011000000101110100010110100001011100100001000000011001000000000100011000010011000011111101000101101000100010001000010100000001000100100100111011010100011100111110110011011110011110111001011010010011001100111001011111111011010000111110111010111 1000110110001000111101101001111100000101000100101101000000100001011111000010110100111010001000010001010001011000010101100011001101001110100000101100011100001111010100101000110110010011011100010010011100110111010111010001111110100111010011110000101001011000100000010011101101000110100111111111000100011010111100011101100110101111010110010000110001000001000101110111101011100000010000110011001000001010 0011101101001110000111101101101010011110101001111110011101100101111101010111100100001001011100000110001000110101010110000001110001010010001011010011000111011000100011101001001101101100110010110011111100000000010101001011011000100000101001100111110100000011010010000100011001111011010010001001101110011110101100010111011001111110001010010101111110111000111111001100111110011111010010101100101001010111 1110011010111001011011010000110001001010101100000010111111110100100111111100100101000000010000000110101100101100110111001001001011010100101111101010010100001001001111110100001010010101001010001000100101110000111110010111111011101001100111100100101111101000010110111101110011011101001101000101010110011001000101100100101000101110110111000111100100100110101010000001001011100011111100100100000111010100 1000111100011100101011001011110100111000011101100111011010000100000110110000011011110011010100110000011010111000010001000111000001010100000100110101000110110101000010011000111000111000001001111000011001110100111100010000111011101000000100111000000010111001000011100010000100101110111010011001110110111110110101111111101111101001101001000110111000000101010110110110001001110110010010000100001010011110 0101010100110010100000100100111011000001111000001010001111110010010110110011100100101011001001111100000111001110101010010011111101110100100011110111001100100100100110100101110110111110010001110110111011100011010011100111111110111110111001011001010011011011011000000110011010100000110000010101010011101011001001100101011110011100001100110110010100101100100001000101001110010101110100001010010101000110 0000110011110101101110100010001110100111000100001111011101000111111000110110110000001001001000011100110100110010001100011011111010100110101001010101100100101100110110101010111000111010000001010001001110011110010010000000010100001000011010110001100101000111100101100110011111010110100101110111010111111100010010100011011010101000010010111110000000000000011100111001110111100010011101010010110011000001 0000111110010101101011000011100010110011010110101010100100001101100110010111010110000100010000001111011101110001101100010010000000110111000111000010101101001100000100110100111111001000010010101101011010001111110001000100010111110001111101000101111001000001000011000011100011110010111000111100110000111000100011001100010010010000000000101010001001111011110100000011000110111100010110000101010110000101
C#

【C#】値型と参照型

12/30/2020 1/2/2021

5年以上前の記事です。内容が古くなっている可能性があります。

内部での変数の扱いの違い

似て非なるコード

まず最初に次の2つのプログラムを見てください。

using System;

class Program {
    static void Main(string[] args) {
        Counter c = new Counter(0);
        Console.WriteLine($"before={c.Count}\n");
        PlusOne(c);
        Console.WriteLine($"after={c.Count}\n");
    }
    static void PlusOne(Counter c) { c.Count += 1; }
}
struct Counter {
    public int Count { get; set; }
    public Counter(int initialValue) {
        Count = initialValue;
    }
}

(cAlgoではなくC#のコンソールアプリケーションです。VisualStudio→新規プロジェクト→C#コンソールアプリケーションで適当な名前で新規作成して、このままコピペで動きます)

Counter型のオブジェクトを作って、Counter型を引数にとるメソッドで中身を+1して、最後に結果を表示させているだけの単純なプログラムです。

このコードの結果はこうなります。

before = 0
after = 0

おや、メソッドで+1されたはずなのに0のままですね。なぜでしょうか。

では次をご覧ください。

using System;

class Program {
    static void Main(string[] args) {
        Counter c = new Counter(0);
        Console.WriteLine($"before={c.Count}\n");
        PlusOne(c);
        Console.WriteLine($"after={c.Count}\n");
    }
    static void PlusOne(Counter c) { c.Count += 1; }
}
class Counter {
    public int Count { get; set; }
    public Counter(int initialValue) {
        Count = initialValue;
    }
}

ほぼ同じコードですが、Counterが構造体(struct)ではなくクラスになっています。ぱっと見、同じ動きをしそうに見えるかもしれませんが、結果はこうなります。

before = 0
after  = 1

ちゃんとメソッド内で+1されたものが反映されています。これは何が違うのでしょうか。

 

値型と参照型

この違いが値型と参照型の違いなんです。

 

説明の前に

オブジェクト指向では変数=オブジェクトと考えることが多いですが、この記事では「変数」と「オブジェクト」は概念的に別の意味を持つと思って読んでください。

ここでは「変数」と言ったらCounter cなどと宣言された c を指します。「オブジェクト」と言ったら、どっかのメモリ上に存在する c が表すモノ(値)本体を指します。

この定義であれば「値型」と「参照型」は変数の型の種類ということになります。そして、変数をメソッドの引数に渡すということは一般的に「変数の中身をそのままコピーしてメソッドに渡す」ということ示します。

重要なのでもう一度。引数に渡すということは、その変数の型が値型であろうと参照型であろうと「変数の中身をそのままコピーしてメソッドに渡す」ということなのです。

これを念頭に置いたうえでこの先をどうぞ。

 

構造体Counter型の変数は値型

C#では構造体は値型になります。

値型の変数はオブジェクト本体を自分で持ちます。つまり上記変数c の中身をのぞくとCounter型構造体オブジェクトそのものが入ってるイメージです。オブジェクトを使うときは中身のオブジェクトを直接使います。

引数に渡すときは「変数の中身をそのままコピーして渡す」ので、このCounter型オブジェクト本体をコピーしてメソッドに渡してあげてます。メソッドが使うのは呼び出し元が用意したオブジェクトのコピー品なのです。

上記一つ目のプログラムではメソッド内で+1されたCounter型オブジェクトはMain内で宣言して最後に内容を表示させたCounter型オブジェクトとは全くの別物なので、メソッド内で+1されようとなにしようと、最後の表示には何ら影響を与えません。

Main内の変数cが指すオブジェクトのプロパティは初期値0で作られて表示されただけなので、当然結果は0のままです。

 

クラスCounter型の変数は参照型

C#ではクラスは参照型になります。

参照型の変数はオブジェクト本体はどっか別の場所に置いておき、その場所情報だけを自分で持ちます。つまり変数cの中身をのぞくと、Counter型クラスオブジェクトが入ってると思いきや、そこにはオブジェクトがある場所だけがメモしてあるだけなんです。オブジェクトを使うときはその場所を「参照」して、その先にあるオブジェクトを使います。

引数に渡すときは「変数の中身をそのままコピーして渡す」ので、このオブジェクト場所のメモをコピーして渡してあげるのです。メソッドはその場所情報を「参照」して、そこにあるオブジェクト、つまり結果的に呼び出しが用意したものと全く同じオブジェクトを使います。

であれば、上記2つ目のプログラムではMainでの変数cが指すオブジェクトのプロパティは、初期値0で作られてから、PlusOneメソッド内で+1されて、表示されたということになるため、結果は1になるのです。

 

C#では型の種類により自動的に決まる

C#ではint,doubleなどの組み込みの単純な値と構造体、列挙型は値型、文字列(string)やその他クラスはすべて参照型と決まっています。

プログラマが、参照型にするか値型にするかというのを考える必要はありません。その代わり自分の使ってる型がどっちなのかを意識し、挙動を把握したうえでコーディングしていくことが重要となります。

 

 

「参照渡し」は別の話

「参照渡し」は引数の渡し方を示す言葉

上記は型の種類の話でしたが、似た用語で、メソッドへの引数のを渡し方を表す言葉として「参照渡し」「値渡し」があります。

勘違いしないでいただきたいのですが、「参照型変数を引数に渡すのが参照渡し」ではありません!他の言語でそのような使い方をする人も一部いるようなのでややこしいのですが、少なくともC#では違う意味で使いますので注意してください。

 

C#でいう参照渡し

最初に「メソッドの引数に渡すというのは『変数の中身をそのままコピーしてメソッドに渡す』ということ」と言いました。これがC#を含む多くのプログラミング言語で一般的な引数の渡され方で、引数の「値渡し」と呼ばれます。

これに対し、C#では「参照渡し」という特別な引数の渡し方ができます。「変数自身の参照(場所情報だけ)を渡す」ということができるんです。メソッドの定義時にパラメータにrefキーワードやout,inキーワードをつけることで参照渡しとすることができます。

渡される変数自身が値型か参照型かは関係ありません。何を渡されようとも、その変数の参照で渡すのが参照渡しですので、値型を渡されたら値型の参照を渡しますし、参照型を渡されれば参照型の参照で渡します。

using System;

class Program {
    static void Main(string[] args) {
        int n = 0;
        Console.WriteLine($"before={n}\n");
        // ↓呼び出し時も参照渡しであることを示すrefが必要
        EditParam(ref n); 
        Console.WriteLine($"after={n}\n");
    }
    //-------------------------------------------
    // 引数を参照渡しでもらって編集するメソッド
    static void EditParam(ref int param) { //← ref をつけると参照渡しになる
        // ここでのparamはMainのnを別の名前で持ち込んでると考えていい。
        // こんな風に代入してもnの値も連動して変わる。
        param = 100; 
    }
}

結果はこうなります。

before = 0
after = 100

なにが違うかわかりにくければ、refキーワードを消して動作の違いを確かめてみてください。

参照型の参照とか言われてもわかりにくければ、「参照渡しでは他で宣言された変数をそのまま持ち込むことができる」と考えるとわかりやすいかもしれません。

 

値型の「参照渡し」=参照型の「値渡し」?

違います!実行してみると全く違うのがわかります。

値型の参照渡し

これは値型を参照渡しするコードですが、一番わかりやすい違いは13行目、引数に直接代入処理をしたときの挙動です。

using System;

class Program {
    static void Main(string[] args) {
        Counter c = new Counter(0);
        Console.WriteLine($"before={c.Count}\n");
        EditParam(ref c); 
        Console.WriteLine($"after={c.Count}\n");
    }
    //-------------------------------------------
    // 引数を参照渡しでもらって編集するメソッド
    static void EditParam(ref Counter param) { 
        param = new Counter(100); 
    }
}
struct Counter {
    public int Count { get; set; }
    public Counter(int initialValue) {
        Count = initialValue;
    }
}

結果はこうなります。まぁ実質的に前項と同じコードですからね。

before = 0
after = 100

代入処理をしてもMain側の変数まで連動して変わるというのがポイントです。

 

参照型の値渡し

上のコードの2か所のrefキーワードを消して、structをclassに置き変えるだけで、参照型の「値渡し」になります。

そうすると、結果は当然こうなります。

before = 0
after = 0

むしろ引数に直接別のものを代入した時の挙動としては、こっちのが自然に感じる方が多いのではないでしょうか。

 

挙動の違い

引数に「参照渡し」で渡された場合は、参照型値型にかかわらず、変数自体が共有されます。引数本体が「参照の参照」となるため、引数=変数として扱えるのです。引数に別のものを代入すれば、呼び出し元の変数内のオブジェクトも連動して変わり、引き続き共有されます。

対して、参照型変数が引数に「値渡し」で渡された場合は、引数中身の参照が指し示すオブジェクトのみが共有されます。引数本体はただの「参照のコピー」ですので、引数自体を書き換える代入では、引数側は変わりますが、オブジェクトの共有は切れ、呼び出し元の変数にはなにも影響ありません。

値型の参照渡しと参照型の値渡し、字面だけ見ると同じように見えてしまいますが、別物ですので間違いないようにしましょう。

 

「参照渡し」は何に使うのか

どういうときに使うのか、一つ実例を示します。

文字列を数値に変換するメソッドを作りたいと思ったとします。しかし、この処理は失敗することもあり、成功したかどうかを返り値で受け取りたい、しかし変換した結果の数値もなんらかの形で受け取りたいという状況を考えてください。

さてC#ではメソッドの返り値は一つしか受け取れません。どうしましょうか。いくつか手段はありますが、ここでは引数で結果を受け取る方向で考えます。このときに結果を入れるための引数を「参照渡し」で渡しておき、結果を入れてもらうような設計にするのです。

例えばこんな感じ。最後の引数はoutキーワードを付けることで「参照渡し」で受け取るようにしています。(refキーワードでも内部的には同じですが、返り値代わりのように必ずメソッド内で代入する場合はoutキーワードの方がおすすめです。)

bool TryParse(string s, out int result);

あ、もしかしてこんなメソッド見たことありますか?ですよね、もともとある組み込みのメソッドですからね。

参考までにintやdoubleの静的メソッドTryParseはこんな風に使えます。

class Program {
    static void Main(string[] args) {
        string str = Console.ReadLine();
        int n;
        bool res = int.TryParse(str, out n);
        if (res) {
            Console.WriteLine($"入力は整数{n}です。");
        } else {
            Console.WriteLine("入力は整数ではありません。");
        }
    }
}

 参照渡しする変数nは初期化の必要はありませんし、なんなら渡すときに宣言してもかまいません。(outキーワードなら。refキーワードだとこれができません。)

この「参照渡し」自体は自分から積極的に使う必要はないのですが、こんな感じで使われてるメソッドもあるため、使い方くらいは知っておいてもいいかもしれません。

 

 

まとめ

値型と参照型の挙動の違いはしっかり理解しておいた方がいいです。「参照渡し」は仕組みとして一応知っておきましょう。

値型  → 型の種類。値型変数を他で使うときはコピーを渡すので基本的に他のメソッドと共有はできない。

参照型 → 型の種類。参照型変数の指すオブジェクト本体は他のメソッドと共有可能。

値渡し  → 変数を引数に渡す普通の渡し方。特に意識しなくていい。

参照渡し → 引数に渡すときの特別な渡し方。メソッド内に他で宣言された変数をそのまま持ち込める。
       渡される変数が値型か参照型かは関係ない。

あと、繰り返しになりますが単に参照型変数を引数に渡すことを「参照渡し」と呼ぶ人もいるみたいなので、その辺は空気読んでうまく対応しましょう。

 


まだコメントはありません

新しいコメント

コメントは承認後に公開されます。承認まで次のコメントは投稿できません。

cTrader's Life

© 2026 ajinori